设置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中运行


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值