Android學習筆記之AlarmManager有關的定時器和鬧鐘的實現

來源:互聯網
上載者:User

標籤:

  畢業設計中有個功能模組叫就醫提醒,大抵的功能就是使用者設定一個未來時間的鬧鐘,並設定鬧鐘的標籤,標籤上寫著去哪裡就醫之類的資訊,主要設計參考魅族系統內建的鬧鐘功能。我在網上看了不少部落格,也在github上下載了不少源碼,發現也沒有寫的特別好的,總有這種或者那種的問題,比如說鬧鐘不是寫成後台服務的模式,APP關閉之後鬧鐘不會提醒,或者手機關機之後之前設定的鬧鐘資訊丟失,所以我準備自己寫一個功能比較齊全的。

  所以這個鬧鐘的功能需要用到Android的資料庫Sqlite、Service、BroadcastReceiver三大比較重要的模組,之前在看《第一行代碼》時,由於看的比較匆忙,所以書本後面的部分知識點學習的並不紮實,書中的代碼並沒有親自在IDE中敲一敲,所以藉著五一假期三天又重頭好好看了一遍《第一行代碼》中關於資料庫Sqlite、Service、BroadcastReceiver的部分。

  Sqlite是一個輕量級的Android內建資料庫,通常只佔幾百KB的記憶體,所以在行動裝置上也非常的適用。建立資料庫的表如下,並寫了一個Helper類對資料庫操作進行了封裝,簡化了底層操作資料的操作。

 1 public class AlarmDBHelper extends SQLiteOpenHelper{ 2     public static final String DATABASE_NAME = "userinfo.db"; 3     public static final int DATABASE_VERSION = 2; 4     public static final String TABLE = "alarm"; 5  6  7     private static final String CREATE_ALARM_TABLE = "CREATE TABLE " + TABLE + " (" 8             + AlarmColumn._ID + " integer primary key AUTOINCREMENT," 9             + AlarmColumn.ALARM_ID + " text UNIQUE ON CONFLICT REPLACE,"10             + AlarmColumn.ALARM_CALENDAR + " text,"11             + AlarmColumn.ALARM_CANCELABLE + " text,"12             + AlarmColumn.ALARM_TAG + " text,"13             + AlarmColumn.ALARM_AVAILABLE + " text,"14             + AlarmColumn.ALARM_RINGTONE + " text)";15 16     public AlarmDBHelper(Context context) {17         super(context, DATABASE_NAME, null, DATABASE_VERSION);18     }19 20     @Override21     public void onCreate(SQLiteDatabase db) {22         db.execSQL(CREATE_ALARM_TABLE);23     }24 25     @Override26     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {27         String sql=" DROP TABLE IF EXISTS "+TABLE;28         db.execSQL(sql);29         onCreate(db);30     }31 }

若要修改原先的資料庫,只需要在 dbHelper = new AlarmDBHelper(this, "userinfo.db", null, 3); 中增加version的版本號碼即可。資料庫的操作無非就是CRUD,C代表添加(Create),R代表查詢(Retrieve),U代表更新(Update),D代表刪除(Delete)。操作基本與SQL相同,同時官方支援使用SQL語句建立資料庫和CRUD。其中查詢資料庫設計到一個新的資料類型——Cursor,本意為游標,可以理解為資料庫中每行的內容。cursor.moveToFirst()移動到表中的第一行,cursor.moveToNext() 即指移動到下一行。上述代碼即建立一個鬧鐘的 table ,將建立鬧鐘所需的一些資訊儲存在資料庫中。

 1 public class BootReceiver extends BroadcastReceiver{ 2     @Override 3     public void onReceive(Context context, Intent intent) { 4         ArrayList<Alarm> alarms = getAllAlarms(context); 5         for (Alarm alarm : alarms) { 6             // Test 7             // 當重啟後,所有的都應該恢複,而如果這是定時任務,那麼只要恢複月度和年度的就可以了. 8             // 如果每天00:00重建鬧鐘的話,那麼00:00時響的鬧鐘會不會響呢 9             // 所以最後錯開一點,因為鬧鐘沒有秒數,所以設定為00:00:30秒何如。10             // 不論是什麼鬧鐘,都會保證如果第二天有鬧鐘的話就會設定上的,所以不用擔心00:00的鬧鐘不會設定上11             alarm.activate();12         }13     }14 15     /**16      * 從本機資料庫恢複所有的鬧鐘17      *18      * @return19      */20     private ArrayList<Alarm> getAllAlarms(Context context) {21         AlarmHelper helper = new AlarmHelper(context);22         return helper.getAlarms();23     }24 }

並註冊一個廣播監聽開機的action,每當開機時將所有的alarm從資料庫中都出來,並啟用所有的鬧鐘,即AlarmReceive監聽所有鬧鐘。

 1  private void setOneTimeAlarm() { 2         if (AudreyCalendar.getTimeInMillis() - System.currentTimeMillis() > 0) { 3             // 最後一個參數必須是PendingIntent.FLAG_UPDATE_CURRENT,否則BroadcastReceiver將收不到參數。 4             PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 5                     0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 6             AlarmManager manager = (AlarmManager) mContext 7                     .getSystemService(Context.ALARM_SERVICE); 8             manager.set(AlarmManager.RTC_WAKEUP, 9                     AudreyCalendar.getTimeInMillis(), pendingIntent);10         } else {11             Toast.makeText(mContext, "小夥子,設定太早鬧鐘是不會執行滴!",12                     Toast.LENGTH_SHORT).show();13         }14     }

通過這樣資料庫中的鬧鐘會在 setOneTimeAlarm() 設定響鈴的時間。AlarmReceive 中的代碼如下,

 1 public class AlarmReceiver extends BroadcastReceiver{ 2  3     @Override 4     public void onReceive(Context context, Intent intent) { 5  6         Alarm alarm=new Alarm(context, intent.getExtras()); 7         Intent intent2=new Intent(); 8         intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9         intent2.setClass(context, RingActivity.class);10         intent2.putExtras(Alarm.alarm2Bundle(alarm));11         context.startActivity(intent2);12 13 14 15     }16 }

通過Receive中的方法啟動RingActivity,觸發響鈴的操作,整個鬧鐘的邏輯就完成了。

按理說,鬧鐘的實現應該通過service實現,這樣就可以使得即使app關閉時,背景鬧鐘也是在啟動並執行,不過如何在service中啟動一個鬧鐘我不知道如何?。整個的邏輯應該是當設定好鬧鐘的屬性,點擊增加鬧鐘時,鬧鐘的資訊被儲存在資料庫中,同時觸發一個service啟動,在service服務中接受alarm中的資訊,設定後一個

 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 5                     0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 6             AlarmManager manager = (AlarmManager) mContext 7                     .getSystemService(Context.ALARM_SERVICE); 8             manager.set(AlarmManager.RTC_WAKEUP, 9                     AudreyCalendar.getTimeInMillis(), pendingIntent);   將getBroadcast改成getActivity,跳轉到RingActivity即可實現整個的邏輯。


因My Code借鑒了他人的代碼,導致我在代碼的閱讀中陷入了極大的混亂,同時整個的邏輯也非常的不清晰,造成了代碼工作非常緩慢的事實,此後我必須在閱讀他人的代碼的基礎上理解整個邏輯實現,理清思路,完成自己的設計。

 

Android學習筆記之AlarmManager有關的定時器和鬧鐘的實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.