Broadcast Receiver is not working when application is removed from background?

Viewed 1354

I am trying to run this code in my mobile app, but it is not running and also giving no error. I have tried printing log also, but it is not showing anything in logcat. This problem only occur in Oreo and run well in all other Android versions, also runs well when application is in background.

public class MainActivity extends AppCompatActivity {

   AlarmManager am;
    TimeAlarm timeAlarm;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        setOneTimeAlarm();
    }

    public void setOneTimeAlarm() {
        Intent intent = new Intent(this, TimeAlarm.class);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);

        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (5 * 1000), pendingIntent);
    }

    public void setRepeatingAlarm() {
        Intent intent = new Intent(this, TimeAlarm.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (5 * 1000), pendingIntent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("ondestroy","ondestroy");

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("onstart","onstart");

        IntentFilter intentFilter=new IntentFilter("my.custom.action.tag.fordemo");
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
        registerReceiver(timeAlarm,intentFilter);
    }
}

Code Of broadcast receiver, when I have removed the application from background it stopped working.

public class TimeAlarm extends BroadcastReceiver {

    NotificationManager nm;
    String channelId = "channel-01";
    String channelName = "Channel Name";
    int importance = NotificationManager.IMPORTANCE_HIGH;

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
    nm = (NotificationManager) 
    context.getSystemService(Context.NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel mChannel = new NotificationChannel(
                        channelId, channelName, importance);
                nm.createNotificationChannel(mChannel);
            } else {

            }
            CharSequence from = "Nithin";
            CharSequence message = "Crazy About Android...";
            PendingIntent contentIntent = 
            PendingIntent.getActivity(context, 0, new Intent(), 0);
            //Notification notif = new Notification(R.drawable.logo, 
           "Crazy About Android...", System.currentTimeMillis());
            NotificationCompat.Builder notification = new 
            NotificationCompat.Builder(context.getApplicationContext());
            // notification.setContentIntent(pintent);
       notification.setTicker(from).setSubText(from).setSmallIcon(R.drawable.logo);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                notification.setChannelId(channelId);
            }

            Notification notification1 = notification.build();
            notif.setLatestEventInfo(context, from, message,contentIntent);
            nm.notify(1, notification1);
        }
    }        
3 Answers

It shouldn't be working when in the background on any version of the OS. You're registering the receiver in onStart, then unregistering in onStop. That means the receiver, to the OS, does not exist after onStop is processed. If you're seeing it work on other versions of the OS, that's actually a bug.

Sure, your broadcast is killed when your application is closed. If you dont unregisterReceiver in onStop/onDestroyed, you will have a leak issue. To avoid it, you should implement a Service (and call registerReceiver(timeAlarm,intentFilter); in your service) which runs in the background even when your application is closed.

P/s: remember to startForeground to prevent service from being killed by system in Android 8.0 or above.

You have to add alarm permission in your manifest

<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

And also To register your broadcast

    <receiver
        android:name=".broadcast.ServiceBroadcast"
        android:enabled="true"
        android:exported="true"
        android:label="RestartServices">
        <intent-filter>
        <action android:name="restart_services"/>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>
Related