每周Android警报管理器

时间:2016-04-14 13:17:42

标签: android alarmmanager android-alarms

在我的Android应用程序中,我需要在每个星期一09.00向用户显示通知。我使用报警管理器。把它做好了工作。

这是我的代码:

public void addReminder() {
    Intent alarmIntent = new Intent(this, WeeklyReminderReceiver.class);
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.DAY_OF_WEEK, 2);
    calendar.set(Calendar.HOUR_OF_DAY, 9);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    alarmManager.setRepeating(
            AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY * 7,
            PendingIntent.getBroadcast(this, 1, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}

但是这段代码不能正常工作。任何人都可以帮我这个吗?

2 个答案:

答案 0 :(得分:2)

Android API 19及以上,setRepeating()将不再准确。如果要触发确切的警报,则必须设置setExact()。如果你想要一个精确的重复警报,你必须自己做。例如,以这种方式:在class之外的任何activity之外创建一个context以发送警报。通过这种方式,您可以独立于activity并可以随时随地添加警报。

//pass the context, so you are independant from any activity
public void addReminder(Context context) {

  Intent alarmIntent = new Intent(context, WeeklyReminderReceiver.class);

  PendingIntent  pendingIntent = PendingIntent.getBroadcast(context, 0, 
            alarmIntent, PendingIntent.FLAG_ONE_SHOT);    

  AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

  Calendar calendar = Calendar.getInstance();

  calendar.set(Calendar.DAY_OF_WEEK, 2);
  calendar.set(Calendar.HOUR_OF_DAY, 9);
  calendar.set(Calendar.MINUTE, 0);
  calendar.set(Calendar.SECOND, 0);
  calendar.set(Calendar.MILLISECOND, 0);   

  alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);     

    }

现在,如果警报触发,用户必须通过按下按钮来杀死它。按此按钮,您可以再次设置新警报:

stopButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){

     yourAlarmClass.addReminder(yourContext);
   }    
});

但有几点需要注意:

  1. 即使setExact()也不能保证准确触发,它只会像系统一样精确触发,这在API中有描述:
  2. 警报将尽可能地传递到请求的触发时间。

    1. 如果您的设备将关闭并重新启动,您的闹钟将不再存在,因此您必须获得Broadcast BOOT_COMPLETED。例如:
    2. 创建BroadcastReceiver

      public class AlarmBootReceiver extends BroadcastReceiver
      {
      
                  public void onReceive(Context context, Intent intent)
                  {
                     yourAlarmClass.addReminder(context);
                  }
      }
      

      manifest

      中注册
      <receiver android:name=".AlarmBootReceiver">
          <intent-filter>
             <action android:name="android.intent.action.BOOT_COMPLETED" />
             <category android:name="android.intent.category.HOME" />
          </intent-filter>
      </receiver>
      

      并将permissions添加到manifest

      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
      
      1. 如果您在上面的Marshmallow和(将来)开发,您必须在运行时请求该权限。但这超出了该线程,所以如果您需要它,请阅读API:http://developer.android.com/training/permissions/requesting.html

      2. 你必须考虑到系统不应该不必要地重载。即使是API setExact()

      3. ,也会注意到这一点

        注意:只有对确切时间交付有强烈需求的警报(例如闹钟在请求的时间响铃)才应安排为准确。强烈建议不要使用确切的警报,因为它们会降低操作系统最小化电池使用的能力。

        如果所有这些示例都不适合您,则必须存在您未在问题中显示的其他问题。如果是这样,请回来,我们会尝试找到问题。

答案 1 :(得分:0)

通过手机重启,AlarmManager的闹钟不会持续存在,这是我最好的猜测,为什么你的代码根据你提供的细节不起作用。