Search code examples
javaandroidandroid-serviceandroid-broadcast

How to Send a LocalBroadcast to a running service from a BroadcastReceiver?


I have a BroadcastReceiver that is triggered with an external application and its OnReceive method is triggered successfully. but I want to send another LocalBroadcast to a running service in my application from that OnReceive, the problem is the SendBroadcast method of the LocalBroadcastManager returns false and the receiver in the service is not triggered. There is no documentation available about that boolean value in the android website. I googled a bit and found that it means there are no registered receivers. but I'm sure I've registered the intent successfully in the running service and the I've made it as a Foreground service to make sure it is running.

Another question, is this the best way to communicate with a running service from the BroadcastReceiver?

Here is code:

MyService.java

public class MyService extends Service {

private final IBinder mBinder = new OneSheeldBinder();

public static final String PLUGIN_MESSAGE = "PLUGIN_MESSAGE";
@Override
public void onCreate() {

    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
              new IntentFilter(MyService.PLUGIN_MESSAGE));
            showNotification();
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    return START_REDELIVER_INTENT;
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

@Override
public void onDestroy() {
    hideNotifcation();
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
    super.onDestroy();
}

private void showNotification(){
    Notification.Builder build=new Notification.Builder(this);
    build.setSmallIcon(R.drawable.ic_launcher);
    build.setContentText("The service is running!");
    build.setContentTitle("The service is running!");
    build.setTicker("The service is running!");
    build.setWhen(System.currentTimeMillis());

    Notification notification=build.build();
    startForeground(1, notification);
}

private void hideNotifcation(){
    stopForeground(true);
}

 public class OneSheeldBinder extends Binder {
     public MyService getService() {
            return MyService.this;
        }

    }

 private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
     @Override
     public void onReceive(Context context, Intent intent) {
          Log.d("LocalBroadcast","Received!");
       }
     };

}

FireReceiver.java

public final class FireReceiver extends BroadcastReceiver
{

@Override
public void onReceive(final Context context, final Intent intent)
{
        Intent intent = new Intent();
        boolean test=LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
        Log.d("LocalBroadcast","Intent Fired!:"+test);//test is always false!
}


}

receiver and service blocks in the Manifest File

<receiver
        android:name=".FireReceiver"
        android:exported="true"
        android:process=":background"
        tools:ignore="ExportedReceiver" >
        <intent-filter>
            <action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" />
        </intent-filter>
</receiver>

    <service
        android:name=.MyService"
        android:exported="false" />

Solution

  • LocalBroadcastManager is local to a process. For whatever reason, you elected to use two different processes, and so LocalBroadcastManager will not work.

    The simple solution is to remove android:process=":background" from your <receiver> element, as it is wasteful, unnecessary, and interferes with your use of LocalBroadcastManager.