Alessandra Maria
Alessandra Maria

Reputation: 255

Android notification not fired when app killed

I am using alarm manager to set the time and fire a notification at that particular time. Works fine when app is foreground or background. I am testing on Android 8. However my problem is when app is killed from task manager, the notification is not fired because the broadcast does not work. This is because I register receiver in onCreate() of MainActivity and unregister receiver in onDestroy(). Maybe it would work if I register my broadcast receiver in manifest but it is not allowed from Android 8 onwards. How do I address this problem that I receive the broadcast even when app is killed?

Upvotes: 0

Views: 112

Answers (1)

jonny h.
jonny h.

Reputation: 11

BroadCastREceiver Example

public class SchedulerMailBroadcastReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            Log.i("scheduler: " + new DateWrapper().getLocaleString());
            PowerManager pm = (PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = null;
            if (pm != null) {
                Log.d("aquire wakelog");
                wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ics:mailScheduler");
                wl.acquire(10000);
            }
            startInNewThread(context.getApplicationContext(),wl);
        }catch(Exception e){
            Log.e(e);
        }
    }
    public void startInNewThread(final Context context, PowerManager.WakeLock wl){
        new ThreadWrapper(() -> {
            try {
               //Do Stuff
            }catch(Exception e){
                Log.e(e);
            }finally {
                Log.d("releasing wakelog");
                try {
                    wl.release();
                    Log.i("released wakelog");
                }catch(Exception e){
                    Log.e("wakelog release","exception on releasing wawkelog");
                }
            }
        }).start();
    }

    public static boolean registerScheduler(Context context){

        final int requestCode=1234;

        Intent intent = new Intent(context, SchedulerMailBroadcastReceiver.class);
        intent.setAction("startScheduler");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        if (alarmManager != null) {
           // alarmManager.cancel(previousPendingIntent);
            alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 60*15, pendingIntent);
            Log.i("registered repeating");
        }
        return  true;
    }


}

you probably dont want setRepeating though

JobService example

public class SchedulerMailJobManager extends JobService{

    @Override
    public boolean onStartJob(JobParameters params) {
        try {
            Log.i("SchedulerMailJobManager","scheduler run at "+ new DateWrapper().getLocaleString());
            startInNewThread(getApplicationContext(),params);
            return true;
        }catch(Exception e){
            Log.e("SchedulerMailJobManager","errpr in starting new thread",e);
            return false;
        }
    }

    @Override
    public void onDestroy(){
        Intent intent = new Intent(this,ServiceRestarter.class);
        intent.setAction("restartService");
        intent.putExtra("service","mailScheduler");
        sendBroadcast(intent);
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        Log.w("stoppedJob","stopped");
        return true;
    }

    public void startInNewThread(final Context context,final JobParameters params){
        new ThreadWrapper(() -> {
            try {
                //Do Stuff
            }catch(Exception e){
                Log.e("JobScheduler2ndThread","Exception",e);
            }finally {
                if(params!=null) {
                    this.jobFinished(params,false);
                }else{
                    Log.e("JobScheduler2ndThread","no params for jobFinished");
                }
            }
        }).start();
    }


    static JobInfo createScheduledJob(Context context){
        ComponentName serviceComponent = new ComponentName(context,SchedulerMailJobManager.class );
        JobInfo.Builder builder=new JobInfo.Builder(1234,serviceComponent);
        int waitMin=30;
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        builder.setPersisted(true);
        builder.setPeriodic(1000*60*waitMin,1000);
        return builder.build();
    }
    public static boolean registerScheduler(Context context){
        JobScheduler scheduler=context.getSystemService(JobScheduler.class);
        if(scheduler==null){
            Log.e("registerScheduler","scheduler is null");
            return false;
        }
        if(scheduler.getPendingJob(1234)!=null) {
            scheduler.cancel(1234);
            Log.i("registerScheduler","cancelled previous");
        }
        int resultCode=scheduler.schedule(createScheduledJob(context));
        if(resultCode==JobScheduler.RESULT_SUCCESS){
            Log.i("JobManagerScheduler","registered new scheduler");
            return true;
        }else{
            Log.e("registerScheduler","failed registering");
            return false;
        }

    }

}

since you only have a Notification you probably dont need to start anything in a new thread which means in this solution you should return false in OnStartJob

Upvotes: 1

Related Questions