AlarmManager 这个类在 Android 开发中非常实用,它是系统及服务,可以进行定时操作而不依赖于 Acitivity 或 Service,但是 Android 在不同的 API 级别中有一定的差异性,往往给开发带来一定的困难,这里将举例说明 AlarmManager 在不同 API 级别中的基本使用方法。
在 Android 4.4 之前,一般都是使用 alarmManager 的 set 方法和 setRepeating 来实现定时操作,从这两个方法的名字就可以看出两者的区别,set 方法一般用来实现在指定的时间执行一次性的操作,而 setRepeating 方法用来实现每隔一段时间执行一次的操作。
但是从 Android 4.4 开始,set 方法和 setRepeating 方法存在一些问题,无法实现准确定时,可能会有些延迟,官方也提供了准确定时的替代方法,即 setExact 和 setWindow,但是这两个方法都只是执行一次性操作的,那么如何才能实现每隔一段时间执行一次的操作呢?
其实很简单,只要在时间到了执行操作的时候再重新设置一下 AlarmManager 就好了,为了方便版本的统一,我们这里在 Android 4.4 之前和之后都使用这样的方法来实现每隔一段时间执行一次的操作。
这里我们以一个 TextView 实现数字时钟为例,代码如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv = (TextView) findViewById(R.id.text_view);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("update_time_action");
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("update_time_action")) {
// 接收到广播之后先设置tv,然后重新设置AlarmManager
tv.setText(getText());
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
long nextTime = getNextTime();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
am.setExact(AlarmManager.RTC_WAKEUP, nextTime, pi);
} else {
am.set(AlarmManager.RTC_WAKEUP, nextTime, pi);
}
}
}
}, intentFilter);
sendBroadcast(new Intent("update_time_action"));
}
// 获取当前时间的样式
private String getText() {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
return format.format(date);
}
// 获取下次更新TextView的时间
private long getNextTime() {
long now = System.currentTimeMillis();
return now + 60 * 1000 - now % (60 * 1000);
}
}