zoukankan      html  css  js  c++  java
  • 转:Android进阶:模拟闹钟 学习Alarm与Notification

    无意间看到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。

    效果图如下:

    下面看代码

    1. public class AlarmSettingActivity extends Activity {  
    2.     private Button setbutton;    
    3.     private Button canclebutton;    
    4.     
    5.     private TextView mTextView;    
    6.     
    7.     private Calendar calendar;    
    8.       
    9.     private AlarmManager am;    
    10.     
    11.     @Override    
    12.     public void onCreate(Bundle savedInstanceState) {    
    13.         super.onCreate(savedInstanceState);    
    14.     
    15.         setContentView(R.layout.main);    
    16.           
    17.         //获得Alarm管理实例   
    18.         am = (AlarmManager) getSystemService(ALARM_SERVICE);    
    19.           
    20.         calendar = Calendar.getInstance();    
    21.     
    22.         mTextView = (TextView) findViewById(R.id.textinfo);    
    23.         setbutton = (Button) findViewById(R.id.setbutton);    
    24.         canclebutton = (Button) findViewById(R.id.canclebutton);    
    25.     
    26.         setbutton.setOnClickListener(new View.OnClickListener() {    
    27.             public void onClick(View v) {    
    28.                 calendar.setTimeInMillis(System.currentTimeMillis());    
    29.                 int mHour = calendar.get(Calendar.HOUR_OF_DAY);    
    30.                 int mMinute = calendar.get(Calendar.MINUTE);    
    31.                 new TimePickerDialog(AlarmSettingActivity.this,    
    32.                     new TimePickerDialog.OnTimeSetListener() {    
    33.                         public void onTimeSet(TimePicker view,    
    34.                                 int hourOfDay, int minute) {    
    35.                             calendar.setTimeInMillis(System    
    36.                                     .currentTimeMillis());    
    37.                             calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);    
    38.                             calendar.set(Calendar.MINUTE, minute);    
    39.                             calendar.set(Calendar.SECOND, 0);    
    40.                             calendar.set(Calendar.MILLISECOND, 0);    
    41.                             Intent intent = new Intent(AlarmSettingActivity.this, AlarmBroadCastReceiver.class);  
    42.                             //这里可以传递消息,譬如提醒信息   
    43.                             Bundle bundle = new Bundle();  
    44.                             bundle.putString("info""该起床啦 ~~~~~");  
    45.                             bundle.putInt("id"new Random().nextInt(100));  
    46.                             intent.putExtras(bundle);  
    47.                             //获得一个可以挂起的Intent   
    48.                             PendingIntent pendingIntent = PendingIntent.getBroadcast(AlarmSettingActivity.this0,intent, 0);    
    49.                             /* 设置闹钟 */    
    50.                             am.set(AlarmManager.RTC_WAKEUP, calendar    
    51.                                     .getTimeInMillis(), pendingIntent);    
    52.                             /* 设置周期闹 */    
    53.                             am.setRepeating(AlarmManager.RTC_WAKEUP, System    
    54.                                     .currentTimeMillis()    
    55.                                     + (10 * 1000), (24 * 60 * 60 * 1000),    
    56.                                     pendingIntent);    
    57.                             String tmpS = "设置闹钟时间为" + format(hourOfDay)    
    58.                                     + ":" + format(minute);    
    59.                             mTextView.setText(tmpS);    
    60.                         }    
    61.                     }, mHour, mMinute, true).show();    
    62.             }    
    63.         });    
    64.     
    65.         canclebutton.setOnClickListener(new View.OnClickListener() {    
    66.             public void onClick(View v) {    
    67.                 Intent intent = new Intent(AlarmSettingActivity.this, AlarmBroadCastReceiver.class);    
    68.                 PendingIntent pendingIntent = PendingIntent.getBroadcast(    
    69.                         AlarmSettingActivity.this0, intent, 0);    
    70.                 //取消该Intent   
    71.                 am.cancel(pendingIntent);    
    72.                 mTextView.setText("闹钟已取消!");    
    73.             }    
    74.         });    
    75.     }    
    76.     
    77.     //格式化字符串 不满两位 前面补0   
    78.     private String format(int x) {    
    79.         String s = "" + x;    
    80.         if (s.length() == 1)    
    81.             s = "0" + s;    
    82.         return s;    
    83.     }   
    84. }  

    这里用到了一个类 PendingIntent

    pending是挂起的意思 它的功能跟Intent差不多 也是用来进行传递数据 它的内部也有Intent的引用 这里的主要区别还是生命周期

    因为Alarm具有了不依赖应用程序的功能,Intent是依赖应用的,所以Intent就不能满足这种需求,

    PendingIntent的生命周期,由系统管理,创建他的应用被Kill了,该PendingIntent可以照样存在,在别的进程中照样可以使用

    下面就是通过BroadcastReceiver 来接收消息

    1. public class AlarmBroadCastReceiver extends BroadcastReceiver{  
    2.     private int id;  
    3.     @Override  
    4.     public void onReceive(Context context, Intent intent) {  
    5.         //获取传递的信息   
    6.         Bundle bundle = intent.getExtras();  
    7.         String info = bundle.getString("info");  
    8.         id = bundle.getInt("id",1);  
    9.         NotificationManager notiManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);  
    10.         Notification notification = new Notification(R.drawable.alarm, info, System.currentTimeMillis());  
    11.         //设置提示框的状态   
    12.         notification.flags = Notification.FLAG_AUTO_CANCEL;  
    13.         Intent intentTarget = new Intent(context, AlarmSettingActivity.class);  
    14.         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);  
    15.         PendingIntent contentIntent = PendingIntent.getActivity(context, id,intentTarget, PendingIntent.FLAG_UPDATE_CURRENT);  
    16.         notification.setLatestEventInfo(context, "闹钟"+id, info,  
    17.                 contentIntent);  
    18.         notiManager.notify(id, notification);  
    19.           
    20.           
    21.         Toast.makeText(context, "时间到了!!!!", Toast.LENGTH_LONG).show();  
    22.     }  
    23. }  

    这里接收到得消息是以通知的方式显示

    Notification 就是用来在屏幕顶端显示通知信息的


     它主要的功能是创建一个状态条图标、在扩展的状态条窗口中显示额外的信息(和启动一个Intent)、还有声音震动等
    提示信息

    可以通过Id来取消通知

    1. notiManager.cancel(id);  


     另外还有一些其他的设置:

    1. //创建一个NotificationManager的引用   
    2. String ns = Context.NOTIFICATION_SERVICE;  
    3. NotificationManager mNotificationManager = (NotificationManager)getSystemService(ns);  
    4. //定义Notification的各种属性   
    5. int icon = R.drawable.icon; //通知图标   
    6. CharSequence tickerText = "Hello"//状态栏显示的通知文本提示   
    7. long when = System.currentTimeMillis(); //通知产生的时间,会在通知信息里显示   
    8. //用上面的属性初始化Nofification   
    9. Notification notification = new Notification(icon,tickerText,when);  
    10. /* 
    11. * 添加声音 
    12. * notification.defaults |=Notification.DEFAULT_SOUND; 
    13. * 或者使用以下几种方式 
    14. * notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); 
    15. * notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6"); 
    16. * 如果想要让声音持续重复直到用户对通知做出反应,则可以在notification的flags字段增加"FLAG_INSISTENT" 
    17. * 如果notification的defaults字段包括了"DEFAULT_SOUND"属性,则这个属性将覆盖sound字段中定义的声音 
    18. */  
    19. /* 
    20. * 添加振动 
    21. * notification.defaults |= Notification.DEFAULT_VIBRATE; 
    22. * 或者可以定义自己的振动模式: 
    23. * long[] vibrate = {0,100,200,300}; //0毫秒后开始振动,振动100毫秒后停止,再过200毫秒后再次振动300毫秒 
    24. * notification.vibrate = vibrate; 
    25. * long数组可以定义成想要的任何长度 
    26. * 如果notification的defaults字段包括了"DEFAULT_VIBRATE",则这个属性将覆盖vibrate字段中定义的振动 
    27. */  
    28. /* 
    29. * 添加LED灯提醒 
    30. * notification.defaults |= Notification.DEFAULT_LIGHTS; 
    31. * 或者可以自己的LED提醒模式: 
    32. * notification.ledARGB = 0xff00ff00; 
    33. * notification.ledOnMS = 300; //亮的时间 
    34. * notification.ledOffMS = 1000; //灭的时间 
    35. * notification.flags |= Notification.FLAG_SHOW_LIGHTS; 
    36. */  
    37. /* 
    38. * 更多的特征属性 
    39. * notification.flags |= FLAG_AUTO_CANCEL; //在通知栏上点击此通知后自动清除此通知 
    40. * notification.flags |= FLAG_INSISTENT; //重复发出声音,直到用户响应此通知 
    41. * notification.flags |= FLAG_ONGOING_EVENT; //将此通知放到通知栏的"Ongoing"即"正在运行"组中 
    42. * notification.flags |= FLAG_NO_CLEAR; //表明在点击了通知栏中的"清除通知"后,此通知不清除, 
    43. * //经常与FLAG_ONGOING_EVENT一起使用 
    44. * notification.number = 1; //number字段表示此通知代表的当前事件数量,它将覆盖在状态栏图标的顶部 
    45. * //如果要使用此字段,必须从1开始 
    46. * notification.iconLevel = ; // 
    47. */  
  • 相关阅读:
    【C语言疯狂讲义】(三)C语言运算符
    RAII手法封装相互排斥锁
    《Java并发编程实战》第十一章 性能与可伸缩性 读书笔记
    Nginx之红黑树
    我第一家互联网公司产品开发周期
    javascript中的XML
    哈夫曼树
    【HttpClient4.5中文教程】【第一章 :基础】1.1运行请求(二)
    H3C开启Ssh
    H3C创建本地用户
  • 原文地址:https://www.cnblogs.com/lovelili/p/2576812.html
Copyright © 2011-2022 走看看