How to send a custom broadcast action to receivers in manifest?
25,481
Solution 1
I use Android 8.
Then you have to use an explicit Intent
, one that identifies the receiver, such as:
sendBroadcast(new Intent(this, MyReceiver.class).setAction("MyAction"));
See Broacast limitations in Android 8 release docs.
Solution 2
In Android 8 onwords
- We need to provide the explicite class for handling i.e setcomponent param along with action
Example :
private void triggerBroadCast(String firstFavApp, String secondFavApp) {
Intent intent = new Intent("FavAppsUpdated");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.putExtra("FIRST_FAV_APP", firstFavApp);
intent.putExtra("SECOND_FAV_APP", secondFavApp);
intent.setComponent(new
ComponentName("com.android.systemui",
"com.android.systemui.statusbar.phone.FavAppsChanged"));
Log.i(TAG, "Trigger Fav Apps" + firstFavApp + " " + secondFavApp);
favouriteContract.getAppContext().sendBroadcast(intent);
}
Below Android 8
- Only action is enough for receiving Broadcast
void broadCastParkingStates(Context context) {
Intent intent = new Intent("ReverseCameraStates");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.putExtra("PARKING_GUIDE", ReverseCameraPreference.getParkingGuide(context));
intent.putExtra("PARKING_SENSOR", ReverseCameraPreference.getParkingSensor(context));
intent.putExtra("TRAJECTORY", ReverseCameraPreference.getTrajectory(context));
Log.i("BootCompletedReceiver", "Sending Reverse Camera settings states BaordCast");
Log.i("BootCompletedReceiver", "States Parking:Sensor:Trajectory="
+ intent.getExtras().getBoolean("PARKING_GUIDE")
+ ":" + intent.getExtras().getBoolean("PARKING_SENSOR")
+ ":" + intent.getExtras().getBoolean("TRAJECTORY")
);
context.sendBroadcast(intent);
}
Solution 3
If you have multiple receivers, you can send broadcast to all the receivers using only custom action defined in manifest for that you need to add the following flag while sending broadcast
Note: I have used adb to test it on Android 10, you can add it in application
FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000
adb shell am broadcast -a MyAction -f 0x01000000
Solution 4
In Kotlin:
val intent = Intent(this, MyBroadCastReceiver::class.java)
intent.addCategory(Intent.CATEGORY_DEFAULT)
intent.action = "my.custom.broadcast"
sendBroadcast(intent)
Author by
Yairopro
Updated on October 13, 2020Comments
-
Yairopro over 3 years
MyReceiver.java
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { Log.i("MyReceiver", "MyAction received!"); } }
In
AndroidManifest.xml
(under theapplication
tag)<receiver android:name=".MyReceiver"> <intent-filter> <action android:name="MyAction" /> </intent-filter> </receiver>
MainActivity.Java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sendBroadcast(new Intent("MyAction")); } }
MyReceiver.onReceive
method is never triggered. Did I miss something? -
Yairopro about 6 yearsIt's impossible to use only the action? If I've got multiple receivers to trigger. Why Android have restricted its broadcast system? Where does it talk about it in its documentation?
-
CommonsWare about 6 years@Yairopro: "It's impossible to use only the action?" -- on Android 8.0+, yes, at least for a receiver that you also intend to use for other broadcasts. See the documentation for more.
-
CommonsWare over 5 years@ChRoNoN: There are only a few IPC mechanisms in Android. If you need to talk across process boundaries within an app, a "broadcast" to a specific receiver is one possibility. It's not an especially common need, and for in-process use, there are many other options that I outlined in a comment on the question.
-
Yairopro over 5 yearsOn Android 8 it seems you cannot do that anymore.
-
Yairopro over 5 years@ChRoNoN The action, as its name indicates, tell the receiver what it should do.
-
ChRoNoN over 5 yearsIndeed, they changed it Oreo.
-
Minding over 4 yearsThis code is the same as in CommonsWare's answer (just split over 3 lines). Please avoid duplicate answers.
-
AJW almost 4 years@Commonsware For IPC, assuming two users have the same app, is there a way to set up an explicit intent for user A to send an Intent with data to a BroadcastReceiver in user B's app via default SMS app for both? I was able to set up using implicit intent that requires RECEIVE_SMS permission, but now that permission requires approval from Google Play Store administrators.
-
AJW almost 4 yearsDoes your solution work for two users who are using the same app? I would like to see if there a way to set up an explicit intent for user A to send an Intent with data to a BroadcastReceiver in user B's app via default SMS app for both? I was able to set up using implicit intent that requires RECEIVE_SMS permission, but now that permission requires approval from Google Play Store administrators.
-
CommonsWare almost 4 years@AJW: I am sorry, but I do not understand the scenario. You might want to ask a separate Stack Overflow question, where you can provide more details.
-
AJW almost 4 years@CommonsWare See more details at this question: stackoverflow.com/questions/62239517/…
-
CommonsWare almost 4 years@AJW: Nothing of what you describe there is practical. There are hundreds, if not thousands, of SMS clients, any of which could be the default one for a user. There is no requirement for any of them to support any form of link in a message. Those that do will use
startActivity()
, notsendBroadcast()
, because "click on a link to do something silently on the device without the user's knowledge" is a great vector for malware. -
AJW almost 4 years@CommonsWare I understand. The objective for clicking on the link is for the recipient to approve taking in the data into the app, from the sender. The sender is a known and trusted friend, family member, co-worker etc. It doesn't have to be a link though, but I thought that would be a convenient way for the recipient to provide approval. As for the malware concern, if the recipient trusts the sender and they trust the app to deliver the data securely, I don't think they will have any problem approving the link. Somehow there could be malware added, like getting a malware email.
-
CommonsWare almost 4 years@AJW: "As for the malware concern, if the recipient trusts the sender and they trust the app to deliver the data securely, I don't think they will have any problem approving the link" -- in your particular case, perhaps. But you are advocating for a feature (send a broadcast from an SMS client) that malware authors would drool over. I worry about an entire planet's worth of users, and so I sincerely hope that no SMS client has that sort of capability.
-
AJW almost 4 years@CommonsWare So I should avoid sending dat thru SMS because a legitimate app with protections like: published with same apk certificate, setPackage() is the same for both sender and recipient and android: protection level is set with signature level permission, the app would be too big of a target for attackers? If so, would sending data via email be any better? Or do I need to rely on a server because that is much more secure than the SMS protections? Struggling with a solution to deliver the data.
-
CommonsWare almost 4 years@AJW: "a legitimate app with protections like: published with same apk certificate, setPackage() is the same for both sender and recipient and android: protection level is set with signature level permission, the app would be too big of a target for attackers?" -- those defenses only have a meaning when you are talking actual IPC (inter-process communication) between two apps on the same device. "would sending data via email be any better?" -- no, in that no email client should be sending a broadcast in response to something contained in an email.
-
CommonsWare almost 4 years@AJW: SMS clients and email clients, to the extent they handle links at all, will start activities, not send broadcasts. I do not know why you want to send a broadcast, but neither of those sorts of clients are going to do that for you. "Or do I need to rely on a server" -- that certainly is a typical approach and it gets you away from dealing with other infrastructure interference. But, if you could switch your mental model to activities instead of broadcasts, you might find that SMS or email will work for your needs.
-
AJW almost 4 years@CommonsWare I am happy to switch over to activities for SMS. The only thing I need to work on is not jarring the user by just starting my app when the SMS arrives because they may be doing something else on the device. That is why I thought of the clickable link or clickable image because it doesn't open the activity right away, it is like a pendingIntent on the Activity...it waits for approval from the recipient and then the activity can open to display the new data. Starting an activity will be much safer from malware bad actors than the broadcasts?
-
CommonsWare almost 4 years@AJW: "The only thing I need to work on is not jarring the user by just starting my app when the SMS arrives because they may be doing something else on the device" -- nothing would happen until the user clicked a link. And your question to me was about broadcasts, not activities. "Starting an activity will be much safer from malware bad actors than the broadcasts?" -- yes, in that the user has to click a link, at minimum. SMS clients might offer other protections (e.g., confirmation dialog).
-
AJW almost 4 years@CommonsWare The broadcast was to send the data from the SMS to a BroadcastReceiver, that then starts a JobIntentService that then starts the Activity. So if the broadcast is not safe I will just include a link in the SMS and clicking on the link will start the Activity to show the data (in a CardView). I could then add a popup dialog to confirm user would like to accept the data. Sound copacetic from your vantage point?
-
CommonsWare almost 4 years@AJW: Sure. That is how I would expect this sort of thing to work. And what you wanted ("a JobIntentService that then starts the Activity") isn't possible on modern versions of Android anyway (no background activity starts). The question that you linked to is about the details of the message to pull that off, and I think that what you want is going to be too fancy to be reliable. But, the general flow of "you send message with a deep link, and recipient clicks that link to trigger their copy of the app to do some work" is perfectly reasonable.
-
AJW almost 4 years@CommonsWare Excellent, I appreciate all of the feedback. Cheers.
-
AJW almost 4 years@CommonsWare One more issue I am struggling with is the passing of the data from app user A to same app user B's MainActivity. What would I need to do to pass the plain/text data received into user B's default SMS app to user B's MainActivity? I don't think I get access to the default SMS app and I am avoiding use of a BroadcastReceiver so can't use Object[], .get("pdus") and creatFromPdu() methods that I see in other answers on stackoverflow.
-
CommonsWare almost 4 years@AJW: Put it in the URL that you are using for your deeplink. Or, put an identifier in that URL that allows App B to obtain the data from your Web service.
-
AJW almost 4 years@CommonsWare There is no Web service, just user A texting user B with the default SMS app. So just attach the data (JSONObject) to the URL clickable link?
-
CommonsWare almost 4 years@AJW: "There is no Web service, just user A texting user B with the default SMS app" -- if you wish to pass significant data, SMS is a lousy transport mechanism. "So just attach the data (JSONObject) to the URL clickable link?" -- you are giving yourself no other choice, AFAICT.
-
AJW almost 4 years@CommonsWare Not significant data and will try the URL route, ty!
-
AJW almost 4 years@CommonsWare I'm not finding any good examples or tutorials on stackoverflow or google search on attaching a JsonObject to a URL...do you know of any examples or tutorials that can steer me in the right direction?
-
CommonsWare almost 4 years@AJW: I don't know which
JsonObject
you are referring to. Converting an object to a JSON string is fairly commonly done. I tend to use Moshi, and it is covered in the very first section of the README. Once you have a JSON string, you can put it as a query parameter on a URL, as you would any other string or number. -
Vinayak almost 4 yearsChecked just now it is working inside app as well Thanks
-
AJW over 3 years@CommonsWare So I'm able to send data between the 2 users. But the String value as a query parameter is added to the end of the URL's scheme/host. If the String has many characters then the URL link becomes very long, not user-friendly i/m/o. Is there any way to pass the String characters by attaching them say as an object for the query parameter value? The object could then have a much shorter name, so that the clickable link ends ups much shorter. Then the object would be "unpacked" (like JSON parsing?) to get the String characters that were sent to the other user's Activity via SMS?
-
CommonsWare over 3 years@AJW: "Is there any way to pass the String characters by attaching them say as an object for the query parameter value?" -- no more than you can do that for a Web URL, which in effect is what you are creating.
-
spartygw over 3 yearsThe -f flag was the difference maker for me to be able to test on Android 10