Reputation: 3213
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
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
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