闹钟管理器重复功能

5

我有一个闹钟,在特定时间发送通知(如果那一天是联系人的生日)。

我需要的是当我设置闹钟时,它应该在每年的同一天和同一时间重复。我该怎么做?

Intent myIntent = new Intent(Main.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(Main.this, 0, myIntent, 0);

AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.clear();
cal.set(2012,5,20,18,40);

alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60*60*24*365*1000, pendingIntent);

这是AlarmService:

public class MyAlarmService extends Service {
  static final int uniqueID = 1394885;
  private PendingIntent pendingIntent;

  @Override
  public void onCreate() {
    // TODO Auto-generated method stub
    Toast.makeText(this, "MyAlarmService.onCreate()", Toast.LENGTH_LONG).show();

  }

  @Override
  public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "MyAlarmService.onBind()", Toast.LENGTH_LONG).show();
    return null;
  }

  @Override
  public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Toast.makeText(this, "MyAlarmService.onDestroy()", Toast.LENGTH_LONG).show();
  }

  @Override
  public void onStart(Intent intent, int startId) {
    // TODO Auto-generated method stub

  }

  @Override
  public boolean onUnbind(Intent intent) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "MyAlarmService.onUnbind()", Toast.LENGTH_LONG).show();
    return super.onUnbind(intent);
  }
}

Could you help me, please?

2个回答

9
Intent intent = new Intent(this, MyReceiver.class);
intent.putExtra("key", "Alert");
pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);

alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar=Calendar.getInstance();

// Calendar.set(int year, int month, int day, int hourOfDay, int minute, int second)
calendar.set(2013, Calendar.OCTOBER, 13, 18, 55, 40);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5*1000, pendingIntent);

这个参数是闹钟下一次重复的时间间隔,单位为毫秒:

5*1000 = 5秒

示例:

1年 = 365(天)* 24(小时)* 60(分钟)* 60(秒)* 1000(毫秒);
// 闰年366天

月份值从0开始计数,因此使用如Calendar.OCTOBER之类的常量可能更加清晰。

MyReceiver.java

public class MyReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
       Toast.makeText(context,intent.getStringExtra("key"),Toast.LENGTH_SHORT).show();
  }

}
更新:注意:从API 19(Build.VERSION_CODES.KITKAT)开始,闹钟传递是不准确的:操作系统将移动闹钟以最小化唤醒和电池使用。有新的API支持需要严格的传递保证的应用程序,请参见setWindow(int、long、long、PendingIntent)和setExact(int、long、PendingIntent)。目标SDK版本早于API 19的应用程序仍将看到以前的行为,在其中所有警报在被请求时都会被精确传递。 参考文献

我推荐在Android 21上使用JobScheduler或在较旧设备上使用Firebase JobDispatcher代替Alarm Manager。

更新:Google已经发布了WorkManager作为JetPack的一部分。使用WorkManager调度任务

如果我们想要每年重复执行,并且在同一日期和时间执行,那么在间隔字段中应该使用什么? alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5*1000, pendingIntent); - mushahid
1
1年 = 365(天) * 24(小时) * 60(分钟) * 60(秒) * 1000(秒 -> 毫秒); // 闰年366天 - vuhung3990
注意:根据Android 5.1的规定,值(在此示例中为51000)将被强制提升至601000。 - Muhammad Riyaz

4

使用alarmManager.set()设置闹钟

Intent myIntent = new Intent(Main.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(Main.this, 0, myIntent, 0);

AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.clear();
cal.set(2012,5,20,18,40);

alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);  

当警报响起时,从MyAlarmService中设置下一年的闹钟。


我尝试过,但是我收到的通知没有停止。我不得不关闭手机才能停止它们。我应该把它添加在哪里,在Start方法中吗? - stanga bogdan
@stangabogdan 你是在使用alarmManager.set还是alarmManager.setRepeating? - Eight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接