設置Android鬧鐘

由於項目中需要鬧鐘提醒服務,在看了網上的一些代碼後,自己實現了一下。 要點:PendingIntent,AlarmManager,BroadcastReceiver,Calendar。實現的效果如圖:

因爲在鬧鐘時間到達時需要發出警報(是一種Service),這需要AlarmManager來執行,警報發出後(實際上發出的是廣播),作爲響應者,需要一個BroadcastReceiver來接收此警報,接收後的具體行爲是通過重寫BroadcastReceiver之下的onReceive()來實現的。

先附上鬧鐘響應時(繼承BroadcastReceiver)的代碼,就是一個Toast:

package com.example.alarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast; public class AlarmReceiver extends BroadcastReceiver { @Override
 public void onReceive(Context arg0, Intent arg1) {
  // TODO  
     Toast.makeText(arg0, "時間已到", Toast.LENGTH_SHORT).show();
  }}

然後是分別是‘設置鬧鐘’和‘取消鬧鐘’按鈕下的邏輯操作,主要內容是用Intent去聯繫BroadcastReceiver;PendingIntent;用AlarmManager去設置警報時間和取消鬧鐘。

package com.example.alarm;

import java.util.Calendar;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity {

	Calendar calendar=Calendar.getInstance();
	Button start_alarm,stop_alarm;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		start_alarm=(Button) findViewById(R.id.start_alarm);
		stop_alarm=(Button) findViewById(R.id.stop_alarm);
		start_alarm.setOnClickListener(listener);
		stop_alarm.setOnClickListener(listener);
		
		
	}
	View.OnClickListener listener=new View.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO 自動生成的方法存根
			int Id=v.getId();
			switch (Id){
			
			case R.id.stop_alarm:
				
				Intent intent=new Intent(MainActivity.this,AlarmReceiver.class);
				
//				此處的requestcode和flag要與設置鬧鐘時的PendingIntent一致。
				PendingIntent pendingIntent=PendingIntent.getBroadcast(MainActivity.this, 26, intent, 0);
			
				 //獲取鬧鐘管理器
				AlarmManager alarmManager=(AlarmManager) getSystemService(ALARM_SERVICE);
				alarmManager.cancel(pendingIntent);
						
				Toast.makeText(MainActivity.this, "鬧鐘已取消", Toast.LENGTH_SHORT).show();
				
				break;
				
			case R.id.start_alarm:
				
				calendar.setTimeInMillis(System.currentTimeMillis());
				
				int myhour=calendar.get(Calendar.HOUR_OF_DAY);
				int myminute=calendar.get(Calendar.MINUTE);
				
				new TimePickerDialog(MainActivity.this,new TimePickerDialog.OnTimeSetListener() {
					
					@Override
					public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
						// TODO 自動生成的方法存根
						
						//設置日曆的時間,主要是讓日曆的年月日和當前同步 
						calendar.setTimeInMillis(System.currentTimeMillis());
						
						//設置日曆的小時和分鐘
						calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);//
						calendar.set(Calendar.MINUTE, minute);
						
						//將秒和毫秒設置爲0  
						calendar.set(Calendar.SECOND, 0);
						calendar.set(Calendar.MILLISECOND, 0);
						
						//建立Intent和PendingIntent來調用鬧鐘管理器
						Intent intent=new Intent(MainActivity.this,AlarmReceiver.class);
						PendingIntent pendingIntent=PendingIntent.getBroadcast(MainActivity.this, 26, intent, 0);
						
						//獲取鬧鐘管理器
						AlarmManager alarmManager=(AlarmManager) getSystemService(ALARM_SERVICE);	
						alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
						
						alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000*1000, pendingIntent);
						
						Toast.makeText(MainActivity.this, "設置的鬧鐘時間爲:"+String.valueOf(hourOfDay)+":"+String.valueOf(minute), Toast.LENGTH_SHORT).show();
					}
				}, myhour, myminute, true).show();//myhour, myminute是TimePickerDialog的初始顯示時間		                                                    
                                         break;							}		}	};}


這裏有兩點要說明:1.這裏的calendar,並不是一個生活意義上的‘日曆’,這裏將其理解爲一個可以任由我們改寫時間的時間容器會比較好,而且精度高至秒。從行可看到,其時間是可以由我們自行改寫的。同時,在onTimeSet()方法下,calendar的時間被賦值當前的TimePickerDialog控件的輸入值。而設置鬧鐘最關鍵的就是alarmManager.set()這一步,該方法的實參是我們希望的鬧鐘時刻,這個時刻被存在calendar裏。類似地,取消鬧鐘最關鍵的則是alarmManager.cancel(pendingIntent)這一步。這裏重點要加深對calendar的理解。2.calendar.setTimeInMillis(System.currentTimeMillis());這裏的‘賦時’操作,實際上是根據加法實現的,System.currentTimeMillis()是以毫秒爲單位的從1970.1.1 0:0年至今的時間差,calendar.setTimeInMillis()則是重新在1970.1.1 0:0 基礎上增加這段時間差,來達到今時的時間。另外,由於使用了 BroadcastReceiver 服務,因此需要在 AndroidManifest.xml中進行聲明,代碼如下

<receiver android:name=".AlarmReceiver" android:process=":remote"></receiver>

與<activity>並列寫在<application>之內即可。

附 Intent和PendingIntent的區別:(引自鏈接

 

a. Intent是立即使用的,而PendingIntent可以等到事件發生後觸發,PendingIntent可以cancel
b. Intent在程序結束後即終止,而PendingIntent在程序結束後依然有效
c. PendingIntent自帶Context,而Intent需要在某個Context內運行
d. Intent在原task中運行,PendingIntent在新的task中運行


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章