Seb
Seb

Reputation: 3213

broadcast receiver not received in IntentService

I am building a service to be able to catch intent from FirebaseMessagingService.

The first version I made use to do it at app level in the main activity but I do not want to handle it at this level anymore. I have created an intent service as below:

package com.seb.sebastien.appservices;

import android.app.IntentService;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import android.content.IntentFilter;
import android.telephony.TelephonyManager;
import android.util.Log;

public class appsControlIntentService extends IntentService {
    public static final String REQUEST_MSG = "request";
    public static final String RESPONSE_MSG = "response";
    public static final String TAG = "appsControlIntentService";
    private String type_sim;


    public appsControlIntentService() {
        super("appsControlIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        boolean request = intent.getBooleanExtra(REQUEST_MSG, false);

        if(request == true) {
            sendResponse("Enable");
            handleAction(getCarrier());
            registerAllReceivers();
        }
        else if (request == false) {
            sendResponse("Disable");
            unRegisterAllReceivers();
            disableAction();
        }
        else
            Log.e(TAG, "Error msg");

    }
    ...

    /* Firebase and SIM */
    private BroadcastReceiver serviceBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "Broadcast received");
            if (intent.getExtras().getString(appFirebaseMessagingService.FIREBASE).equals(appFirebaseMessagingService.FIREBASE))
                type_sim = intent.getExtras().getString(appFirebaseMessagingService.SIM_TYPE);
            else if(intent.getExtras().getString(SimNotificationService.EXTRA_SIM_STATE) != null)
                Log.d(TAG, "Get something from Sim");
            else
                type_sim = null;

            if(type_sim != null){
                handleAction(type_sim);
            }
        }
    };

    private void registerAllReceivers(){
        Log.d(TAG, "Broadcast receiver register");
        registerReceiver(serviceBroadcastReceiver, new IntentFilter(appFirebaseMessagingService.INTENT_FILTER));
    }

    private void unRegisterAllReceivers() {
        if (serviceBroadcastReceiver != null) {
            unregisterReceiver(serviceBroadcastReceiver);
            serviceBroadcastReceiver = null;
        }
    }

    @Override
    public void onDestroy() {
        unRegisterAllReceivers();
        super.onDestroy();
    }

}

this intent service register a broadcast receiver to be able to receive the firebase broadcast as shown below:

package com.seb.sebastien.appservices;

public class appFirebaseMessagingService extends FirebaseMessagingService {

    public static final String TAG = "appFirebaseMessagingService";
    public static final String INTENT_FILTER = "INTENT_FILTER";
    public static final String FIREBASE = "firebase";
    public static final String SIM_TYPE = "simtype";

    public appFirebaseMessagingService() {
    }

   /* @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    } */

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        String sim = null;

        Log.d(TAG, "From: " + remoteMessage.getFrom());

        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            sim = remoteMessage.getNotification().getBody();
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }

        Intent intent = new Intent(INTENT_FILTER);
        intent.putExtra(FIREBASE, FIREBASE);
        intent.putExtra(SIM_TYPE, sim );

        sendBroadcast(intent);

    }
}

when debugging, I saw that we went until the sendBroadcast but nothing seems received in the "appControlIntentService" class event if I have registered the receiver.

Any idea why the broadcast is not received in the intentservice ?

Upvotes: 1

Views: 1456

Answers (2)

Itay Bianco
Itay Bianco

Reputation: 747

First off, not sure where you actually created an instance of your appsControlIntentService.

Second, IntentService gets stopped when onHandleIntent finishes. It is meant to do a short task and finish. So basically even if you created one to listen to the broadcast, it would only do so for a very limited time until its onDestroy was called.

About BroadcastReceiver solutions for listening to your custom intent:

1) make a service that runs in the background (not IntentService, regular Service), and have it register a BroadcastListener. This service you can create when your activity first wakes, and probably in the Boot BroadcastReceiver. Decide if you want it to be a foreground or background service. background services are more likely to be killed by the OS due to memory issues. but foreground services require that you show an icon in the status bar.

2) just put the BroadcastReceiver in the manifest. This way the OS will even wake the app to handle the broadcast when it arrives. Even if the app is not currently running. have a look at "Manifest-declared receivers" in: https://developer.android.com/guide/components/broadcasts.html.

to disable this receiver, have a look at: Android - how to unregister a receiver created in the manifest?. or, you could save in the shared preferences whether you want it to do something with the event or not, or better yet, don't send the intent from the FirebaseMessagingService if it is disabled in the first place.

Upvotes: 2

Akshay Sahai
Akshay Sahai

Reputation: 2350

You should use alarm manager for broadcast receiver like this -

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        Intent alarmIntent = new Intent(MainActivity.this, BroadCastReciever.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1,
                alarmIntent, 0);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
                    + duration(in millisecond), pendingIntent);
        } else {
            alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
                    + in millisecond, pendingIntent);

        }

Upvotes: 0

Related Questions