• Android随笔之——闹钟制作铺垫之AlarmManager详解


      说实话,之前写的两篇博客Android广播机制Broadcast详解Android时间、日期相关类和方法以及现在要写的,都算是为之后要写的闹钟应用做铺垫,有兴趣的话,大家可以去看看前两篇博客。

    一、AlarmManager简介

      对于一个闹钟应用的实现,个人觉得最主要的应该要属于AlarmManager了。AlarmManager称为全局定时器,字面意思就是闹钟管理(请原谅我蹩脚的英语),是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent。简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Intent,通常我们使用 PendingIntent(这货在调用系统发送短信的时候也有,找个时间温习下Intent,顺带把这个也好好学习下),PendingIntent可以理解为Intent的封装包,简单的说就是在Intent上在加个指定的动作。在使用Intent的时候,我们还需要在执行startActivity、startService或sendBroadcast才能使Intent有用。而PendingIntent的话就是将这个动作包含在内了。

    //定义一个PendingIntent对象,此处先照样画葫芦,下次学了再细讲
    PendingIntent pi = PendingIntent.getBroadcast(Context, int, Intent, int);

    补充:网上有人再说PendingIntent的第二个和第四个参数不重要,其实不然,如果在闹钟这个应用中,你的第二个参数都是同一个常数,那么你之后设的闹钟会把之前的闹钟给覆盖掉,导致时间到了也不提醒的情况。解决办法就是:根据设置闹钟时的时间毫秒数来产生第二个参数。

    二、AlarmManager常用方法简介

      AlarmManager类提供的常用方法主要有一下几个:

    public void set(int type, long triggerAtMillis, PendingIntent operation)
    功能:用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示触发这个闹钟要等待的时间,与type相关(不懂英文就查字典吧,我也是查了才理解这个参数的意思的),
    第三个参数闹钟响应的动作 参数:type AlarmManager.ELAPSED_REALTIME 在指定的延时过后,发送广播,但不唤醒设备。 AlarmManager.ELAPSED_REALTIME_WAKEUP 在指定的演示后,发送广播,并唤醒设备 AlarmManager.RTC 在指定的时刻,发送广播,但不唤醒设备 时刻是相对于1970
    -01-01 00:00:00来说的毫秒数 AlarmManager.RTC_WAKEUP 在指定的时刻,发送广播,并唤醒设备 AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能状态值为4;不过我测试的时候并没有这个常量,估计和SDK有关 operation 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等。 public void setExact(int type, long triggerAtMillis, PendingIntent operation) 功能:在规定的时间精确的执行闹钟,这个函数应该是闹钟执行精度比较高吧 public void setRepeating(int type, long triggerAtMills, long intervalMillis, PendingIntent operation) 功能:该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示触发这个闹钟要等待的时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。 public void setInexactRepeating(int type, long triggerAtMills, long intervalMillis, PendingIntent operation) 功能:设置一个重复闹钟的不精确版本,它相对而言更节能一些,因为系统可能会将几个差不多的闹钟合并为一个来执行,减少设备的唤醒次数。
    由于不是精确版,所以这里的intervaMills会略有不同 参数:intervalMillis: INTERVAL_FIFTEEN_MINUTES INTERVAL_HALF_HOUR INTERVAL_HOUR INTERVAL_HALF_DAY INTERVAL_DAY
    public void cancel(PendingIntent operation) 功能:取消一个设置的闹钟,移除任意匹配意图的闹钟 public void setTimeZone(String timeZone) 功能:设置系统的默认时区。需要android.permission.SET_TIME_ZONE权限

     三、一个简单的闹钟的实例Demo

      首先,我们现在AndroidManifest.xml中注册一个广播,如果不清楚可以去看我之前写的博客Android随笔之——Android广播机制Broadcast详解

        <receiver android:name=".AlarmReceiver" ><!-- Reveiver名称,如果是内部类静态注册广播,请在内部类前加$ -->
                <intent-filter>
                    <action android:name="android.intent.action.ALARM_RECEIVER" /><!-- 广播接收的Intent -->
    
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </receiver>

      接着,我们就要编写一个广播接收器,用来接收闹钟的广播事件,进行相关处理

     1 package com.example.alarmmanager;
     2 
     3 import android.content.BroadcastReceiver;
     4 import android.content.Context;
     5 import android.content.Intent;
     6 import android.widget.Toast;
     7 
     8 public class AlarmReceiver extends BroadcastReceiver{
     9 
    10     @Override
    11     public void onReceive(Context arg0, Intent arg1) {
    12         //此处可以添加闹钟铃声
    13         System.out.println("我是闹钟,我要叫醒你...");
    14         Toast.makeText(arg0, "我是闹钟,我要叫醒你...", Toast.LENGTH_SHORT).show();  
    15     }
    16 
    17 }

      最后,在MainActivity.java写上具体的实现代码

     1 package com.example.alarmmanager;
     2 
     3 import java.text.ParseException;
     4 import java.text.SimpleDateFormat;
     5 import java.util.Date;
     6 
     7 import android.annotation.SuppressLint;
     8 import android.app.Activity;
     9 import android.app.AlarmManager;
    10 import android.app.PendingIntent;
    11 import android.content.Intent;
    12 import android.os.Bundle;
    13 import android.os.SystemClock;
    14 import android.view.View;
    15 import android.view.View.OnClickListener;
    16 
    17 public class MainActivity extends Activity implements OnClickListener {
    18 
    19     private AlarmManager alarmManager;
    20     private PendingIntent operation;
    21 
    22     protected void onCreate(Bundle savedInstanceState) {
    23         super.onCreate(savedInstanceState);
    24         setContentView(R.layout.activity_main);
    25 
    26         // 初始化按钮,并绑定监听事件
    27         findViewById(R.id.ELAPSED_REALTIME_CLOCK).setOnClickListener(this);
    28         findViewById(R.id.ELAPSED_REALTIME_WAKEUP_CLOCK).setOnClickListener(
    29                 this);
    30         findViewById(R.id.RTC_CLOCK).setOnClickListener(this);
    31         findViewById(R.id.RTC_WAKEUP_CLOCK).setOnClickListener(this);
    32         findViewById(R.id.repeating_clock).setOnClickListener(this);
    33         findViewById(R.id.cancel_clock).setOnClickListener(this);
    34 
    35         // 获取AlarmManager对象
    36         alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    37 
    38         // 创建Intent对象,action为android.intent.action.ALARM_RECEIVER
    39         Intent intent = new Intent("android.intent.action.ALARM_RECEIVER");
    40         operation = PendingIntent.getBroadcast(this, 0, intent, 0);
    41     }
    42 
    43     @Override
    44     public void onClick(View v) {
    45         switch (v.getId()) {
    46         case R.id.ELAPSED_REALTIME_CLOCK:
    47             // 在指定的演示后,发送广播,并唤醒设备
    48             // 延时是要把系统启动的时间SystemClock.elapsedRealtime()算进去的
    49             int triggerAtTime = (int) (SystemClock.elapsedRealtime() + 10 * 1000);
    50             alarmManager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTime, operation);
    51             break;
    52         case R.id.ELAPSED_REALTIME_WAKEUP_CLOCK:
    53             // 在指定的演示后,发送广播,并唤醒设备
    54             // 延时是要把系统启动的时间SystemClock.elapsedRealtime()算进去的
    55             int triggerAtTime1 = (int) (SystemClock.elapsedRealtime() + 5 * 1000);
    56             alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
    57                     triggerAtTime1, operation);
    58             break;
    59         case R.id.RTC_CLOCK:// 在指定的时刻,发送广播,但不唤醒设备
    60             alarmManager.set(AlarmManager.RTC,
    61                     getDateMills("2014-08-30 10:06:00"), operation);
    62             break;
    63         case R.id.RTC_WAKEUP_CLOCK:// 在指定的时刻,发送广播,并唤醒设备
    64             alarmManager.set(AlarmManager.RTC_WAKEUP,
    65                     getDateMills("2014-08-30 10:10:00"), operation);
    66             break;
    67         case R.id.repeating_clock:// 设置重复闹钟
    68             alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 5000, 10000,
    69                     operation);
    70             break;
    71         case R.id.cancel_clock:// 取消闹钟
    72             alarmManager.cancel(operation);
    73             break;
    74         default:
    75             break;
    76         }
    77     }
    78 
    79     @SuppressLint("SimpleDateFormat")
    80     public long getDateMills(String dateStr) {
    81         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
    82         Date date;
    83         try {
    84             date = format.parse(dateStr);
    85             return date.getTime();
    86         } catch (ParseException e) {
    87             e.printStackTrace();
    88         }
    89         return 0;
    90     }
    91 }

      activity_main.xml

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical" >
     6 
     7     <Button
     8         android:id="@+id/ELAPSED_REALTIME_CLOCK"
     9         android:layout_width="match_parent"
    10         android:layout_height="wrap_content"
    11         android:text="一次性闹钟:ELAPSED_REALTIME" />
    12 
    13     <Button
    14         android:id="@+id/ELAPSED_REALTIME_WAKEUP_CLOCK"
    15         android:layout_width="match_parent"
    16         android:layout_height="wrap_content"
    17         android:text="一次性闹钟:ELAPSED_REALTIME_WAKEUP " />
    18 
    19     <Button
    20         android:id="@+id/RTC_CLOCK"
    21         android:layout_width="match_parent"
    22         android:layout_height="wrap_content"
    23         android:text="一次性闹钟:RTC  " />
    24 
    25     <Button
    26         android:id="@+id/RTC_WAKEUP_CLOCK"
    27         android:layout_width="match_parent"
    28         android:layout_height="wrap_content"
    29         android:text="一次性闹钟:RTC_WAKEUP_CLOCK" />
    30 
    31     <Button
    32         android:id="@+id/repeating_clock"
    33         android:layout_width="match_parent"
    34         android:layout_height="wrap_content"
    35         android:text="设置重复闹钟" />
    36 
    37     <Button
    38         android:id="@+id/cancel_clock"
    39         android:layout_width="match_parent"
    40         android:layout_height="wrap_content"
    41         android:text="取消闹钟" />
    42 
    43 </LinearLayout>

      这样,一个简单的闹钟就完成了,呼~我的目标是做一个真正可以使用的闹钟,再接再厉!也欢迎大家关注我的博客!

    作者:登天路

    转载请说明出处:http://www.cnblogs.com/travellife/

    源码下载:百度云盘

  • 相关阅读:
    我的第一个网络爬虫
    python中os模块的walk函数
    <Think Python>中统计文献单词的处理代码
    <Think Python>中斐波那契使用memo实现的章节
    Python中bisect的使用
    vim中使用系统粘贴板
    linux下的重命名
    HTML Dog 初级教程中关于 forms 的翻译
    unittest:1 用例编写
    python UI自动化实战记录十一: 总结
  • 原文地址:https://www.cnblogs.com/travellife/p/3945754.html
Copyright © 2020-2023  润新知