Android隨筆之——鬧鍾制作鋪墊之AlarmManager詳解


  說實話,之前寫的兩篇博客Android廣播機制Broadcast詳解Android時間、日期相關類和方法以及現在要寫的,都算是為之后要寫的鬧鍾應用做鋪墊,有興趣的話,大家可以去看看前兩篇博客。

一、AlarmManager簡介

  對於一個鬧鍾應用的實現,個人覺得最主要的應該要屬於AlarmManager了。AlarmManager稱為全局定時器,字面意思就是鬧鍾管理(請原諒我蹩腳的英語),是Android中常用的一種系統級別的提示服務,在特定的時刻為我們廣播一個指定的Intent。簡單的說就是我們設定一個時間,然后在該時間到來時,AlarmManager為我們廣播一個我們設定的Intent,通常我們使用 PendingIntent(這貨在調用系統發送短信的時候也有,找個時間溫習下Intent,順帶把這個也好好學習下),PendingIntent可以理解為Intent的封裝包,簡單的說就是在Intent上在加個指定的動作。在使用Intent的時候,我們還需要在執行startActivity、startService或sendBroadcast才能使Intent有用。而PendingIntent的話就是將這個動作包含在內了。

//定義一個PendingIntent對象,此處先照樣畫葫蘆,下次學了再細講
PendingIntent pi = PendingIntent.getBroadcast(Context, int, Intent, int);

補充:網上有人再說PendingIntent的第二個和第四個參數不重要,其實不然,如果在鬧鍾這個應用中,你的第二個參數都是同一個常數,那么你之后設的鬧鍾會把之前的鬧鍾給覆蓋掉,導致時間到了也不提醒的情況。解決辦法就是:根據設置鬧鍾時的時間毫秒數來產生第二個參數。

二、AlarmManager常用方法簡介

  AlarmManager類提供的常用方法主要有一下幾個:

public void set(int type, long triggerAtMillis, PendingIntent operation)
功能:用於設置一次性鬧鍾,第一個參數表示鬧鍾類型,第二個參數表示觸發這個鬧鍾要等待的時間,與type相關(不懂英文就查字典吧,我也是查了才理解這個參數的意思的),
第三個參數鬧鍾響應的動作 參數:type AlarmManager.ELAPSED_REALTIME 在指定的延時過后,發送廣播,但不喚醒設備。 AlarmManager.ELAPSED_REALTIME_WAKEUP 在指定的演示后,發送廣播,並喚醒設備 AlarmManager.RTC 在指定的時刻,發送廣播,但不喚醒設備 時刻是相對於1970
-01-01 00:00:00來說的毫秒數 AlarmManager.RTC_WAKEUP 在指定的時刻,發送廣播,並喚醒設備 AlarmManager.POWER_OFF_WAKEUP表示鬧鍾在手機關機狀態下也能正常進行提示功能狀態值為4;不過我測試的時候並沒有這個常量,估計和SDK有關 operation 綁定了鬧鍾的執行動作,比如發送一個廣播、給出提示等等。 public void setExact(int type, long triggerAtMillis, PendingIntent operation) 功能:在規定的時間精確的執行鬧鍾,這個函數應該是鬧鍾執行精度比較高吧 public void setRepeating(int type, long triggerAtMills, long intervalMillis, PendingIntent operation) 功能:該方法用於設置重復鬧鍾,第一個參數表示鬧鍾類型,第二個參數表示觸發這個鬧鍾要等待的時間,第三個參數表示鬧鍾兩次執行的間隔時間,第三個參數表示鬧鍾響應動作。 public void setInexactRepeating(int type, long triggerAtMills, long intervalMillis, PendingIntent operation) 功能:設置一個重復鬧鍾的不精確版本,它相對而言更節能一些,因為系統可能會將幾個差不多的鬧鍾合並為一個來執行,減少設備的喚醒次數。
由於不是精確版,所以這里的intervaMills會略有不同 參數:intervalMillis: INTERVAL_FIFTEEN_MINUTES INTERVAL_HALF_HOUR INTERVAL_HOUR INTERVAL_HALF_DAY INTERVAL_DAY
public void cancel(PendingIntent operation) 功能:取消一個設置的鬧鍾,移除任意匹配意圖的鬧鍾 public void setTimeZone(String timeZone) 功能:設置系統的默認時區。需要android.permission.SET_TIME_ZONE權限

 

 三、一個簡單的鬧鍾的實例Demo

  首先,我們現在AndroidManifest.xml中注冊一個廣播,如果不清楚可以去看我之前寫的博客Android隨筆之——Android廣播機制Broadcast詳解

    <receiver android:name=".AlarmReceiver" ><!-- Reveiver名稱,如果是內部類靜態注冊廣播,請在內部類前加$ -->
            <intent-filter>
                <action android:name="android.intent.action.ALARM_RECEIVER" /><!-- 廣播接收的Intent -->

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

  接着,我們就要編寫一個廣播接收器,用來接收鬧鍾的廣播事件,進行相關處理

 1 package com.example.alarmmanager;
 2 
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 import android.widget.Toast;
 7 
 8 public class AlarmReceiver extends BroadcastReceiver{
 9 
10     @Override
11     public void onReceive(Context arg0, Intent arg1) {
12         //此處可以添加鬧鍾鈴聲
13         System.out.println("我是鬧鍾,我要叫醒你...");
14         Toast.makeText(arg0, "我是鬧鍾,我要叫醒你...", Toast.LENGTH_SHORT).show();  
15     }
16 
17 }

  最后,在MainActivity.java寫上具體的實現代碼

 1 package com.example.alarmmanager;
 2 
 3 import java.text.ParseException;
 4 import java.text.SimpleDateFormat;
 5 import java.util.Date;
 6 
 7 import android.annotation.SuppressLint;
 8 import android.app.Activity;
 9 import android.app.AlarmManager;
10 import android.app.PendingIntent;
11 import android.content.Intent;
12 import android.os.Bundle;
13 import android.os.SystemClock;
14 import android.view.View;
15 import android.view.View.OnClickListener;
16 
17 public class MainActivity extends Activity implements OnClickListener {
18 
19     private AlarmManager alarmManager;
20     private PendingIntent operation;
21 
22     protected void onCreate(Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.activity_main);
25 
26         // 初始化按鈕,並綁定監聽事件
27         findViewById(R.id.ELAPSED_REALTIME_CLOCK).setOnClickListener(this);
28         findViewById(R.id.ELAPSED_REALTIME_WAKEUP_CLOCK).setOnClickListener(
29                 this);
30         findViewById(R.id.RTC_CLOCK).setOnClickListener(this);
31         findViewById(R.id.RTC_WAKEUP_CLOCK).setOnClickListener(this);
32         findViewById(R.id.repeating_clock).setOnClickListener(this);
33         findViewById(R.id.cancel_clock).setOnClickListener(this);
34 
35         // 獲取AlarmManager對象
36         alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
37 
38         // 創建Intent對象,action為android.intent.action.ALARM_RECEIVER
39         Intent intent = new Intent("android.intent.action.ALARM_RECEIVER");
40         operation = PendingIntent.getBroadcast(this, 0, intent, 0);
41     }
42 
43     @Override
44     public void onClick(View v) {
45         switch (v.getId()) {
46         case R.id.ELAPSED_REALTIME_CLOCK:
47             // 在指定的演示后,發送廣播,並喚醒設備
48             // 延時是要把系統啟動的時間SystemClock.elapsedRealtime()算進去的
49             int triggerAtTime = (int) (SystemClock.elapsedRealtime() + 10 * 1000);
50             alarmManager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTime, operation);
51             break;
52         case R.id.ELAPSED_REALTIME_WAKEUP_CLOCK:
53             // 在指定的演示后,發送廣播,並喚醒設備
54             // 延時是要把系統啟動的時間SystemClock.elapsedRealtime()算進去的
55             int triggerAtTime1 = (int) (SystemClock.elapsedRealtime() + 5 * 1000);
56             alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
57                     triggerAtTime1, operation);
58             break;
59         case R.id.RTC_CLOCK:// 在指定的時刻,發送廣播,但不喚醒設備
60             alarmManager.set(AlarmManager.RTC,
61                     getDateMills("2014-08-30 10:06:00"), operation);
62             break;
63         case R.id.RTC_WAKEUP_CLOCK:// 在指定的時刻,發送廣播,並喚醒設備
64             alarmManager.set(AlarmManager.RTC_WAKEUP,
65                     getDateMills("2014-08-30 10:10:00"), operation);
66             break;
67         case R.id.repeating_clock:// 設置重復鬧鍾
68             alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 5000, 10000,
69                     operation);
70             break;
71         case R.id.cancel_clock:// 取消鬧鍾
72             alarmManager.cancel(operation);
73             break;
74         default:
75             break;
76         }
77     }
78 
79     @SuppressLint("SimpleDateFormat")
80     public long getDateMills(String dateStr) {
81         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
82         Date date;
83         try {
84             date = format.parse(dateStr);
85             return date.getTime();
86         } catch (ParseException e) {
87             e.printStackTrace();
88         }
89         return 0;
90     }
91 }

  activity_main.xml

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6 
 7     <Button
 8         android:id="@+id/ELAPSED_REALTIME_CLOCK"
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content"
11         android:text="一次性鬧鍾:ELAPSED_REALTIME" />
12 
13     <Button
14         android:id="@+id/ELAPSED_REALTIME_WAKEUP_CLOCK"
15         android:layout_width="match_parent"
16         android:layout_height="wrap_content"
17         android:text="一次性鬧鍾:ELAPSED_REALTIME_WAKEUP " />
18 
19     <Button
20         android:id="@+id/RTC_CLOCK"
21         android:layout_width="match_parent"
22         android:layout_height="wrap_content"
23         android:text="一次性鬧鍾:RTC  " />
24 
25     <Button
26         android:id="@+id/RTC_WAKEUP_CLOCK"
27         android:layout_width="match_parent"
28         android:layout_height="wrap_content"
29         android:text="一次性鬧鍾:RTC_WAKEUP_CLOCK" />
30 
31     <Button
32         android:id="@+id/repeating_clock"
33         android:layout_width="match_parent"
34         android:layout_height="wrap_content"
35         android:text="設置重復鬧鍾" />
36 
37     <Button
38         android:id="@+id/cancel_clock"
39         android:layout_width="match_parent"
40         android:layout_height="wrap_content"
41         android:text="取消鬧鍾" />
42 
43 </LinearLayout>

 

  這樣,一個簡單的鬧鍾就完成了,呼~我的目標是做一個真正可以使用的鬧鍾,再接再厲!也歡迎大家關注我的博客!

作者:登天路

轉載請說明出處:http://www.cnblogs.com/travellife/

源碼下載:百度雲盤


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM