无意间看到Alarm 这个类 觉得挺有意思 这个用法应该会比较常用到 看了一些介绍 然后自己写了一个demo
Alarm是在预定的时间上触发Intent的一种独立的方法。
Alarm超出了应用程序的作用域,所以它们可以用于触发应用程序事件或动作,甚至在应用程序关闭之后,与Broadcast Receiver结合,它们可以变得尤其的强大,可以通过设置Alarm来启动应用程序或者执行动作,而应用程序不需要打开或者处于活跃状态。
举个例子,你可以使用Alarm来实现一个闹钟程序,执行正常的网络查询,或者在“非高峰”时间安排耗时或有代价的操作。
对于仅在应用程序生命周期内发生的定时操作,Handler类与Timer和Thread类的结合是一个更好的选择,它允许Android更好地控制系统资源。
Android中的Alarm在设备处于睡眠模式时仍保持活跃,它可以设置来唤醒设备;然而,所有的Alarm在设备重启时都会被取消。
Alarm的操作通过AlarmManager来处理,通过getSystemService可以获得其系统服务,如下所示:
AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
为了创建一个新的Alarm,使用set方法并指定一个Alarm类型、触发时间和在Alarm触发时要调用的Intent。如果你设定的Alarm发生在过去,那么,它将立即触发。
这里有4种Alarm类型。你的选择将决定你在set方法中传递的时间值代表什么,是特定的时间或者是时间流逝:
❑ RTC_WAKEUP
在指定的时刻(设置Alarm的时候),唤醒设备来触发Intent。
❑ RTC
在一个显式的时间触发Intent,但不唤醒设备。
❑ ELAPSED_REALTIME
从设备启动后,如果流逝的时间达到总时间,那么触发Intent,但不唤醒设备。流逝的时间包括设备睡眠的任何时间。注意一点的是,时间流逝的计算点是自从它最后一次启动算起。
❑ ELAPSED_REALTIME_WAKEUP
从设备启动后,达到流逝的总时间后,如果需要将唤醒设备并触发Intent。
效果图如下:
下面看代码
- public class AlarmSettingActivity extends Activity {
- private Button setbutton;
- private Button canclebutton;
- private TextView mTextView;
- private Calendar calendar;
- private AlarmManager am;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //获得Alarm管理实例
- am = (AlarmManager) getSystemService(ALARM_SERVICE);
- calendar = Calendar.getInstance();
- mTextView = (TextView) findViewById(R.id.textinfo);
- setbutton = (Button) findViewById(R.id.setbutton);
- canclebutton = (Button) findViewById(R.id.canclebutton);
- setbutton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- calendar.setTimeInMillis(System.currentTimeMillis());
- int mHour = calendar.get(Calendar.HOUR_OF_DAY);
- int mMinute = calendar.get(Calendar.MINUTE);
- new TimePickerDialog(AlarmSettingActivity.this,
- new TimePickerDialog.OnTimeSetListener() {
- public void onTimeSet(TimePicker view,
- int hourOfDay, int minute) {
- calendar.setTimeInMillis(System
- .currentTimeMillis());
- calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
- calendar.set(Calendar.MINUTE, minute);
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);
- Intent intent = new Intent(AlarmSettingActivity.this, AlarmBroadCastReceiver.class);
- //这里可以传递消息,譬如提醒信息
- Bundle bundle = new Bundle();
- bundle.putString("info", "该起床啦 ~~~~~");
- bundle.putInt("id", new Random().nextInt(100));
- intent.putExtras(bundle);
- //获得一个可以挂起的Intent
- PendingIntent pendingIntent = PendingIntent.getBroadcast(AlarmSettingActivity.this, 0,intent, 0);
- /* 设置闹钟 */
- am.set(AlarmManager.RTC_WAKEUP, calendar
- .getTimeInMillis(), pendingIntent);
- /* 设置周期闹 */
- am.setRepeating(AlarmManager.RTC_WAKEUP, System
- .currentTimeMillis()
- + (10 * 1000), (24 * 60 * 60 * 1000),
- pendingIntent);
- String tmpS = "设置闹钟时间为" + format(hourOfDay)
- + ":" + format(minute);
- mTextView.setText(tmpS);
- }
- }, mHour, mMinute, true).show();
- }
- });
- canclebutton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- Intent intent = new Intent(AlarmSettingActivity.this, AlarmBroadCastReceiver.class);
- PendingIntent pendingIntent = PendingIntent.getBroadcast(
- AlarmSettingActivity.this, 0, intent, 0);
- //取消该Intent
- am.cancel(pendingIntent);
- mTextView.setText("闹钟已取消!");
- }
- });
- }
- //格式化字符串 不满两位 前面补0
- private String format(int x) {
- String s = "" + x;
- if (s.length() == 1)
- s = "0" + s;
- return s;
- }
- }
这里用到了一个类 PendingIntent
pending是挂起的意思 它的功能跟Intent差不多 也是用来进行传递数据 它的内部也有Intent的引用 这里的主要区别还是生命周期
因为Alarm具有了不依赖应用程序的功能,Intent是依赖应用的,所以Intent就不能满足这种需求,
PendingIntent的生命周期,由系统管理,创建他的应用被Kill了,该PendingIntent可以照样存在,在别的进程中照样可以使用
下面就是通过BroadcastReceiver 来接收消息
- public class AlarmBroadCastReceiver extends BroadcastReceiver{
- private int id;
- @Override
- public void onReceive(Context context, Intent intent) {
- //获取传递的信息
- Bundle bundle = intent.getExtras();
- String info = bundle.getString("info");
- id = bundle.getInt("id",1);
- NotificationManager notiManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- Notification notification = new Notification(R.drawable.alarm, info, System.currentTimeMillis());
- //设置提示框的状态
- notification.flags = Notification.FLAG_AUTO_CANCEL;
- Intent intentTarget = new Intent(context, AlarmSettingActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- PendingIntent contentIntent = PendingIntent.getActivity(context, id,intentTarget, PendingIntent.FLAG_UPDATE_CURRENT);
- notification.setLatestEventInfo(context, "闹钟"+id, info,
- contentIntent);
- notiManager.notify(id, notification);
- Toast.makeText(context, "时间到了!!!!", Toast.LENGTH_LONG).show();
- }
- }
这里接收到得消息是以通知的方式显示
Notification 就是用来在屏幕顶端显示通知信息的
它主要的功能是创建一个状态条图标、在扩展的状态条窗口中显示额外的信息(和启动一个Intent)、还有声音震动等
提示信息
可以通过Id来取消通知
- notiManager.cancel(id);
另外还有一些其他的设置:
- //创建一个NotificationManager的引用
- String ns = Context.NOTIFICATION_SERVICE;
- NotificationManager mNotificationManager = (NotificationManager)getSystemService(ns);
- //定义Notification的各种属性
- int icon = R.drawable.icon; //通知图标
- CharSequence tickerText = "Hello"; //状态栏显示的通知文本提示
- long when = System.currentTimeMillis(); //通知产生的时间,会在通知信息里显示
- //用上面的属性初始化Nofification
- Notification notification = new Notification(icon,tickerText,when);
- /*
- * 添加声音
- * notification.defaults |=Notification.DEFAULT_SOUND;
- * 或者使用以下几种方式
- * notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");
- * notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
- * 如果想要让声音持续重复直到用户对通知做出反应,则可以在notification的flags字段增加"FLAG_INSISTENT"
- * 如果notification的defaults字段包括了"DEFAULT_SOUND"属性,则这个属性将覆盖sound字段中定义的声音
- */
- /*
- * 添加振动
- * notification.defaults |= Notification.DEFAULT_VIBRATE;
- * 或者可以定义自己的振动模式:
- * long[] vibrate = {0,100,200,300}; //0毫秒后开始振动,振动100毫秒后停止,再过200毫秒后再次振动300毫秒
- * notification.vibrate = vibrate;
- * long数组可以定义成想要的任何长度
- * 如果notification的defaults字段包括了"DEFAULT_VIBRATE",则这个属性将覆盖vibrate字段中定义的振动
- */
- /*
- * 添加LED灯提醒
- * notification.defaults |= Notification.DEFAULT_LIGHTS;
- * 或者可以自己的LED提醒模式:
- * notification.ledARGB = 0xff00ff00;
- * notification.ledOnMS = 300; //亮的时间
- * notification.ledOffMS = 1000; //灭的时间
- * notification.flags |= Notification.FLAG_SHOW_LIGHTS;
- */
- /*
- * 更多的特征属性
- * notification.flags |= FLAG_AUTO_CANCEL; //在通知栏上点击此通知后自动清除此通知
- * notification.flags |= FLAG_INSISTENT; //重复发出声音,直到用户响应此通知
- * notification.flags |= FLAG_ONGOING_EVENT; //将此通知放到通知栏的"Ongoing"即"正在运行"组中
- * notification.flags |= FLAG_NO_CLEAR; //表明在点击了通知栏中的"清除通知"后,此通知不清除,
- * //经常与FLAG_ONGOING_EVENT一起使用
- * notification.number = 1; //number字段表示此通知代表的当前事件数量,它将覆盖在状态栏图标的顶部
- * //如果要使用此字段,必须从1开始
- * notification.iconLevel = ; //
- */