AlarmManager Not called next day if the app sleeps for abt 1 day

白昼怎懂夜的黑 提交于 2019-12-13 03:23:39

问题


I am developing an android app which shows a notification every 12 hour if the time is saved in the database. So everytime a data is entered or edited in the database ,I cancel the current alarmmanager and start a fresh new one so that I dont miss one. Also on reboot I have called the alarmmanager. On the broadcast receiver, the database is checked for entry and if found a notification is set and the app is opened automatically.

So when I test the app by changing the date manually,the app works as expected.Also on reboot the app works.But if I keep the app idle for nearly 14 hours,the notification is not set ,but if I open the app and suspend it the notification is set after that.

This is how I call the alarmmanager. Intent alarmintent = new Intent(context, package.Alarm_Manager.class);

    alarmintent.putExtra("note","Notify");
    sender = PendingIntent.getBroadcast(context , 0 , alarmintent , PendingIntent.FLAG_CANCEL_CURRENT | Intent.FILL_IN_DATA);            
    alarm_manger = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    alarm_manger.cancel(sender);
    Calendar cal = Calendar.getInstance();
    long now = cal.getTimeInMillis();
    alarmintent = new Intent(context, package.Alarm_Manager.class);
    alarmintent.putExtra("note","Notification");
    sender = PendingIntent.getBroadcast(context , 0 , alarmintent , PendingIntent.FLAG_CANCEL_CURRENT | Intent.FILL_IN_DATA);            
    alarm_manger = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarm_manger.setRepeating(AlarmManager.RTC_WAKEUP, now, AlarmManager.INTERVAL_HALF_DAY, sender);

This is the broadcast receiver

@Override
public void onReceive(Context context, Intent intent)
{
       NotificationManager manger = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
       Calendar cal = Calendar.getInstance();
       date = (int)(cal.getTimeInMillis()/1000);
       Notification notification = new Notification(R.drawable.vlcsnap_396460 , "Notify" , System.currentTimeMillis());
       PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0);
       notification.setLatestEventInfo(context, "App", "Notify" , contentIntent);
       notification.flags = Notification.FLAG_INSISTENT;
       manger.notify( 0 , notification);
   }

回答1:


You don't need to call alarm_manager.cancel(sender); if you set the PendingIntent.FLAG_CANCEL_CURRENT.

Your call to

alarm_manger.setRepeating(AlarmManager.RTC_WAKEUP, now, AlarmManager.INTERVAL_HALF_DAY, sender);

will trigger the alarm right away, since the now is already passed when you set the alarm.

I suggest you use

now + DateUtils.HOUR_IN_MILLIS / 2 

for the triggerAtMillis parameter

Did you tried to schedule it for smaller interval? Does it get triggered ?




回答2:


After having seen your Alarm_Manager code, I think it is illegal to do this in your BroadcastReceiver object directly. Quote:

If this BroadcastReceiver was launched through a tag, then the object is no longer alive after returning from this function.

I believe there is no other way than to create a Service which is informed by your BroadcastReceiver, and make sure that the Service calls setLatestEventInfo() with itself (this) as the Context.

The reason why your asynchronous Broadcast fails while it works when your app is running is probably that the Context provided to the BroadcastReceiver lives only for the duration of the call to the BroadcastReceiver when your app does not run. So the Notification service, which only runs after your BroadcastReceiver has died along with the temporary context, is missing a valid context.

When your app runs, the Broadcast probably comes with your Activity or Application object as Context, and this is still vaild when the Notification manager runs.

Hope this helps.

Update: An `IntentService`` will do. You don't want a full time Service for that.

Update 2: Some snippets.

<service android:name=".MyIntentService" android:label="@string/my_intent_service_name" />

public final class MyIntentService extends IntentService {
    public MyIntentService() {
    super("service name");
    // set any properties you need
    }
    @Override
    public void onCreate() {
        super.onCreate();
        // do init, e.g. get reference to notification service
    }
    @Override
    protected void onHandleIntent(Intent intent) {
    // handle the intent
        // ...especially:
        notification.setLatestEventInfo(this, "App", "Notify" , contentIntent);
        // ...
    }
}

public final class MyAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        context.startService(new Intent(context, MyIntentService.class));
    }
}


来源:https://stackoverflow.com/questions/14498171/alarmmanager-not-called-next-day-if-the-app-sleeps-for-abt-1-day

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!