How to Send BroadCast from one app to another app

AndroidBroadcastreceiverBroadcast

Android Problem Overview


I have App A and App B. In App A I want to send broadcast to App B. This is the code for App A:

final Intent intent = new Intent();
intent.setAction("com.pkg.perform.Ruby");
intent.putExtra("KeyName", "code1id");
intent.setComponent(new ComponentName("com.pkg.AppB", "com.pkg.AppB.MainActivity"));
sendBroadcast(intent);

And in App B - In MainActivity, I have MyBroadCastReceiver Class.

public class MainActivity extends Activity {
    private MyBroadcastReceiver MyReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Receive broadcast from External App
        IntentFilter intentFilter = new IntentFilter("com.pkg.perform.Ruby");
        MyReceiver = new MyBroadcastReceiver();
        if(intentFilter != null)
        {
            registerReceiver(MyReceiver, intentFilter);
        }
    }

    public class MyBroadcastReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(MainActivity.this, "Data Received from External App", Toast.LENGTH_SHORT).show();
        }
    }
   
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(MyReceiver != null)
            unregisterReceiver(MyReceiver);
    }
}

I am getting the error - Receiver is not registered.

Android Solutions


Solution 1 - Android

First thing first declare the receiver in app B in the manifest file like this:

<receiver android:name=".MyBroadcastReceiver"
	android:enabled="true"
	android:exported="true">
		<intent-filter>
		  <action android:name="com.pkg.perform.Ruby" />
		</intent-filter>
</receiver>

when sending the broadcast add FLAG_INCLUDE_STOPPED_PACKAGES flag to the intent [src] because when you broadcast from app A to app B , app B might not be running, this flag insures that the broadcast reachs out even apps not running:

> FLAG_INCLUDE_STOPPED_PACKAGES flag is added to the intent before it > is sent to indicate that the intent is to be allowed to start a > component of a stopped application.

intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);

In your case it will be like this:

    final Intent intent=new Intent();
    intent.setAction("com.pkg.perform.Ruby");
    intent.putExtra("KeyName","code1id");
    intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
    intent.setComponent(  
        new ComponentName("com.pkg.AppB","com.pkg.AppB.MyBroadcastReceiver"));  
    sendBroadcast(intent);

Solution 2 - Android

In App A: Send the broadcast here.

 final Intent i= new Intent();
 i.putExtra("data", "Some data");
 i.setAction("com.pkg.perform.Ruby");
 i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
 getApplicationContext().sendBroadcast(i);

In App B manifest

 <receiver  android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.pkg.perform.Ruby" />
            </intent-filter>
        </receiver>

In App B MainActivity: register the receiver oncreate(), and unregister onDestroy()

 public class MainActivity extends AppCompatActivity
 {
      private MyBroadcastReceiver MyReceiver;
    
       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            MyReceiver = new MyBroadcastReceiver();
            IntentFilter intentFilter = new IntentFilter("com.pkg.perform.Ruby");
            if(intentFilter != null)
            {
               registerReceiver(MyReceiver, intentFilter);
            }
       }

       @Override
       protected void onDestroy()
       {
           super.onDestroy();
           if(MyReceiver != null)
               unregisterReceiver(MyReceiver);
       }
  }

In App B BroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        String data = intent.getStringExtra("data");
        Log.i("BR" ,"Data received:  " + data);
    }
}

Solution 3 - Android

There may be two cases :

> 1. Your appB is not running, hence the activity is not instantiated, and so the receiver is not registered. > 2. Your activity is destroyed, means that you have unregistered your receiver that you registered via registerReceiver() in onCreate()

Solution :

> Register your broadcast receiver in manifest.

Inside manifest of appB :

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.pkg.perform.Ruby" />
    </intent-filter>
</receiver>

And comment out the line in appA

intent.setComponent(new ComponentName("com.pkg.AppB","com.pkg.AppB.MainActivity"));

Write the logic in MyBroadcastReceiver to display relevant data/launch new activity

Solution 4 - Android

MyReceiver is class not object. Create

myReceiver = new MyReceiver(); 

and put...........

registerReceiver(myReceiver,intentFilter);

Solution 5 - Android

If this helps some one and it works for me

In App A in activity or in a content provider-

  Intent intent = new Intent("Updated");
  intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
  intent.setComponent (new
  ComponentName "com.exam.appA",
  "com.exam.appA.DbaseChanged"));
  getContext().sendBroadcast(intent);

In App B in the manifest

      <receiver
        android:name=".DbaseChanged"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="Updated" />
        </intent-filter>
      </receiver>

In App B Broadcast receiver class-

    public class DbaseChanged extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent
     intent)   {

           String act = intent.getAction();
           if(act != null && act.equals("Updated")  )
            {
                Toast.makeText(context, act ,
              Toast.LENGTH_SHORT).show();

            }

            }
       }

Solution 6 - Android

I needed to call setPackage("package_name") to ensure explicitness when I registered the broadcast receiver in the Manifest. I was then able to receive the data even if the app was closed completely.

// sending app sends broadcast
Intent intent = new Intent(ACTION_RECOMMEND);
intent.putExtra(LISTEN_RECOMMENDATION, "Triggered - Jhene Aiko");
intent.putExtra(WATCH_RECOMMENDATION, "Goblin - Kim Go-eun");
intent.setPackage("com.example.package.receiverapp");
sendBroadcast(intent);


//receiving app manifest registers receiver
<receiver
   android:name=".ManifestRegisteredBroadcastReceiver"
   android:exported="true">
   <intent-filter>
       <action android:name="com.random.action.RECOMMEND" />
   </intent-filter>
</receiver>

I didn't need to add intent.setPackage(package_name) when registering the receiver via an activity, but this also meant that I couldn't get the data if the activity was destroyed (app closed, app in background for long period)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionabh22ishekView Question on Stackoverflow
Solution 1 - AndroiddsharewView Answer on Stackoverflow
Solution 2 - AndroidSophus H. B. WeirsøeView Answer on Stackoverflow
Solution 3 - AndroidabhisheshView Answer on Stackoverflow
Solution 4 - Androidd.k.View Answer on Stackoverflow
Solution 5 - AndroidJroView Answer on Stackoverflow
Solution 6 - AndroidbibangambaView Answer on Stackoverflow