android全局计时_Android定时器AlarmManager
AlarmManager是Android的全局定時器。就是在指定時間做一個事情(封裝在PendingIntent)。通過PendingIntent的getActivity()、getService()或getBroadcast()來執行。
聽起來AlarmManager和Timer很類似,但是Timer有可能因為手機休眠而被殺掉服務,但是AlarmManager可以做到喚醒手機。
創建方式
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
注:ALARM_SERVIC是context的一個常量。
鬧鐘類型
RTC_WAKEUP
表示鬧鐘在睡眠狀態下喚醒系統并執行提示功能,絕對時間。
RTC
睡眠狀態下不可用,絕對時間。
ELAPSED_REALTIME_WAKEUP
睡眠狀態下可用,相對時間。
ELAPSED_REALTIME
睡眠狀態下不可用,相對時間。
以上絕對時間就是手機的時間,相對時間是相對于當前開機時間來說。例如如果是絕對時間,那么你測試可以通過修改系統時間來提前觸發。而相對時間的使用場景是強調多久之后觸發,例如2小時后,這個時候把時間修改到2小時后也是沒用的。
注:以前還有一個POWER_OFF_WAKEUP,即使在關機后還能提醒,但是Android4.0以后就沒有了。
常用方法
set(int type, long triggerAtMillis, PendingIntent operation)
該方法用于設置一次性鬧鐘。第一個參數是鬧鐘類型,第二個參數是觸發時間,第三個參數是動作。
setExact(int type, long triggerAtMillis, PendingIntent operation)
和set一樣,但是時間更精準。
setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
重復鬧鐘,第1、2、4個參數同上,第3個參數是兩次鬧鐘的時間間隔。
setRepeating(int type, long triggerAtMillis,long intervalMillis, PendingIntent operation)
和setInexactRepeating一樣,但是時間更精準。
以上四個方法時間精不精準的原因還沒有深入研究,大概是是否允許系統同時發出多個提醒,意義在于系統喚醒cpu后會把時間接近的alarm同時發出,避免重復喚醒cpu,減少電量。
cancel(PendingIntent operation)
取消鬧鐘。
寫個小程序實驗一下
目的:在指定時間從一個發送個廣播,收到廣播后打印log。界面如下面這樣。
布局:
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.xuhongchuan.alarmclocktest.MainActivity">
android:id="@+id/view_group1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:id="@+id/time_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:id="@+id/view_group2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:layout_below="@id/view_group1">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="是否重復"/>
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:id="@+id/confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/view_group2"
android:text="確定" />
廣播接收器:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == MainActivity.INTENT_ALARM_LOG) {
Log.d("AlarmReceiver", "log log log");
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
public static final String INTENT_ALARM_LOG = "intent_alarm_log";
private TimePicker timePicker;
private CheckBox checkBox;
private Button btnConfirm;
private int hour;
private int minute;
AlarmManager am;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
timePicker = (TimePicker) findViewById(R.id.time_picker);
timePicker.setIs24HourView(true);
checkBox = (CheckBox) findViewById(R.id.checkbox);
btnConfirm = (Button) findViewById(R.id.confirm);
am = (AlarmManager) getSystemService(ALARM_SERVICE);
btnConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 23) {
hour = timePicker.getHour();
minute = timePicker.getMinute();
} else {
hour = timePicker.getCurrentHour();
minute = timePicker.getCurrentMinute();
}
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
Intent intent = new Intent(INTENT_ALARM_LOG);
PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
if (!checkBox.isChecked()) {
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
} else {
long intervalMillis = 60 * 1000; // 60秒
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), intervalMillis, pi);
}
}
});
}
}
AndroidManifest要注冊一下receiver
經過測試,以上的時間間隔intervalMillis即使設置5秒也是沒用的,因為誤差(幾十秒呢)無法避免,即使是setRepeating。所以精確是相對的。
總結
以上是生活随笔為你收集整理的android全局计时_Android定时器AlarmManager的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cuda二维数组内存分配和数据拷贝
- 下一篇: CUDA分支优化