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