Android:使用AlarmManager设置定期警报

时间:2012-04-01 17:08:23

标签: android alarmmanager android-pendingintent

在我的应用程序中,我需要向数据库添加一行并同时设置一个Alarm事件,以便在其中一个数据库列中指定的时间每天重复一次。我已经有了一些代码,但它会在指定时间触发警报事件。这是我的代码:

public class Add_reminder extends Activity {
    AlarmManager am;
    int hours, minutes;
    REMIND_DB db;
    Calendar calendar;
    Cursor cursor;
    Button button;

    public void onCreate(Bundle savedInstanceState) {
        //The usual code in the beginning of onCreate

        //I load db from extended Application class as global since i use it in more
        //Activities. Ints hours and minutes is set by user interaction

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

        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                db.open();
                db.insertReminder( -- parameters for database --);
                cursor = db.getAllReminders();
                cursor.moveToLast();
                calendar.set(Calendar.HOUR, hours);
                calendar.set(Calendar.MINUTE, minutes);
                Intent intent = new Intent(Add_reminder.this, ReminderAlarm.class);
                intent.putExtra("id_of_db_row", cursor.getInt(0));
                PendingIntent pi =  PendingIntent.getActivity(Add_reminder.this,
                    cursor.getInt(0), intent, PendingIntent.FLAG_CANCEL_CURRENT);
                am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                    24*3600*1000, pi);
                db.close()
            } 
        });
    }
}

数据库已正确更新,但ReminderActivity从未在指定时间启动。我不知道什么是错的。我看到一些使用BroadcastReceiver的示例代码,而不是使用PendingIntent启动Activity,但这也应该有效,对吧?有谁知道什么可能是错的?

我的第二个问题是,当我想要从不同的Activity中添加或删除某些警报时,我是否需要相同的AlarmManager实例,或者我是否只在我需要的每个Activity中声明另一个AlarmManager?

谢谢!

1 个答案:

答案 0 :(得分:1)

您应该使用广播接收器进行警报,然后启动执行实际工作的服务。广播接收器不应该通过冗长的操作(例如写入DB)来阻止UI线程。此外,“每天一次”警报可能会出现问题:如果用户重新启动电话:已注册的警报将丢失。你需要:

  • 将警报运行的时间保存到,例如,SharedPreferecnes
  • 手机启动时重新注册闹钟(接收BOOT_COMPLETED广播)
  • 不要使用setRepeating(),而是让每个警报在
  • 上注册

使用较短的时间(1或2分钟)进行测试也有帮助。

对于AlarmManager实例,它是一个系统服务,您不需要关心您正在使用的实例。只需使用getSystemService()

即可