我正在使用警报管理器设置时间并在该特定时间触发通知。当应用程序是前景或背景时,效果很好。我正在Android 8上进行测试。但是,我的问题是,当应用程序从任务管理器中终止时,由于广播无法正常工作,因此未触发通知。这是因为我在MainActivity的onCreate()中注册了接收者,而在onDestroy()中取消了注册接收者。如果我在清单中注册我的广播接收器,也许会工作,但是从Android 8开始不允许这样做。我该如何解决即使应用被杀死我仍会收到广播的问题?
答案 0 :(得分:0)
BroadCastREceiver示例
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;
}
}
您可能不希望setRepeating
JobService示例
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;
}
}
}
由于只有一个Notification,您可能不需要在新线程中启动任何内容,这意味着在此解决方案中,您应该在OnStartJob中返回false