I\'m developing an app which needs to run some code (Networking) whenever an SMS is received.
In API 25 and lower it\'s fine, I register an implicit receiver
Since there are lots of ways to do the job in android O, I post this answer and mention my approach to solve the problem. Obviously by problem I mean the general problem not the SMS_RECEIVED
receiver itself.
I start a foreground service and in there I register a dynamic or explicit receiver to listen to the incoming calls (for instance):
In MainActivity.java
:
String action = "START"
final Intent intent = new Intent(this, CallMonitorService.class);
intent.setAction(action);
startService(intent);
In CallMonitorService.java
s onCreate()
method where I have BroadcastReceiver callExplicitReceiver
as a field:
final IntentFilter intentFilter = new IntentFilter();
intentFilter.setPriority(2147483647);
intentFilter.addAction("android.intent.action.PHONE_STATE");
this.callExplicitReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
// do the stuff here
}
}
};
registerReceiver(callExplicitReceiver, intentFilter);
and then in onStartCommand()
:
if (intent.getAction().equals("START")) {
Intent callServiceNotificationIntent = new Intent(this, MainActivity.class);
callServiceNotificationIntent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent
.getActivity(this, CALL_SERVICE_REQUEST_CODE,
callServiceNotificationIntent, CALL_SERVICE_FLAG);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(CALL_NOTIFICATION_CONTENT_TITLE)
.setTicker(CALL_NOTIFICATION_TICKER)
.setContentText(CALL_NOTIFICATION_CONTENT_TEXT)
.setSmallIcon(R.drawable.ic_info_outline_black_24dp)
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
startForeground(CALL_NOTIFICATION_ID, notification);
}
and finally:
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(callExplicitReceiver);
}
I think of this as a good approach since the user is notified of the running service because of the undismissable notification and that's what android Oreo
wants, however through a button in the app user could stop the service and the monitoring receiver as a direct result of destroying service (I cleared that part of code).