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)
Share:
25,481
Yairopro
Author by

Yairopro

Updated on October 13, 2020

Comments

  • Yairopro
    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 the application 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
    Yairopro about 6 years
    It'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
    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
    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
    Yairopro over 5 years
    On Android 8 it seems you cannot do that anymore.
  • Yairopro
    Yairopro over 5 years
    @ChRoNoN The action, as its name indicates, tell the receiver what it should do.
  • ChRoNoN
    ChRoNoN over 5 years
    Indeed, they changed it Oreo.
  • Minding
    Minding over 4 years
    This code is the same as in CommonsWare's answer (just split over 3 lines). Please avoid duplicate answers.
  • AJW
    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
    AJW almost 4 years
    Does 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
    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
    AJW almost 4 years
    @CommonsWare See more details at this question: stackoverflow.com/questions/62239517/…
  • CommonsWare
    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(), not sendBroadcast(), because "click on a link to do something silently on the device without the user's knowledge" is a great vector for malware.
  • AJW
    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
    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
    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
    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
    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
    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
    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
    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
    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
    AJW almost 4 years
    @CommonsWare Excellent, I appreciate all of the feedback. Cheers.
  • AJW
    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
    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
    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
    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
    AJW almost 4 years
    @CommonsWare Not significant data and will try the URL route, ty!
  • AJW
    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
    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
    Vinayak almost 4 years
    Checked just now it is working inside app as well Thanks
  • AJW
    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
    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
    spartygw over 3 years
    The -f flag was the difference maker for me to be able to test on Android 10