Android广播事件处理闹钟实例

Android广播事件处理闹钟实例
Android广播事件处理闹钟实例

Android广播事件处理闹钟实例

对应AlarmManage有一个AlarmManagerServie服务程序,该服务程序才是正真提供闹铃服务的,它主要维护应用程序注册下来的各类闹铃并适时的设置即将触发的闹铃给闹铃设备(在系

统中,linux实现的设备名为”/dev/alarm”),并且一直监听闹铃设备,一旦有闹铃触发或

者是闹铃事件发生,AlarmManagerServie服务程序就会遍历闹铃列表找到相应的注册闹铃并

发出广播。该服务程序在系统启动时被系统服务程序system_service启动并初始化闹铃设备(/dev/alarm)。当然,在JAVA层的AlarmManagerService与Linux Alarm驱动程序接口之间

还有一层封装,那就是JNI。

AlarmManager将应用与服务分割开来后,使得应用程序开发者不用关心具体的服务,而

是直接通过AlarmManager来使用这种服务。这也许就是客户/服务模式的好处吧。AlarmManager与 AlarmManagerServie之间是通过Binder来通信的,他们之间是多对一的关系。

在android系统中,AlarmManage提供了3个接口5种类型的闹铃服务。

3个接口:

1. // 取消已经注册的与参数匹配的闹铃

2. void cancel(PendingIntent operation)

1.

2. //注册一个新的闹铃

3. void set(int type, long triggerAtTime, PendingIntent operation)

4. //注册一个重复类型的闹铃

5. void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation)

6. //设置时区

7. void setTimeZone(String timeZone)

5个闹铃类型

public static final int ELAPSED_REALTIME

1. //当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传

递它,该闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠

2. 时间,可以通过调用SystemClock.elapsedRealtime()获得。系统值是 3

(0x00000003)。

3. public static final int ELAPSED_REALTIME_WAKEUP

4. //能唤醒系统,用法同ELAPSED_REALTIME,系统值是2 (0x00000002) 。

5. public static final int RTC

6.

7. //当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传

递它,该闹铃所用的时间是绝对时间,所用时间是UTC时间,可以通过调用

8. System.currentTimeMillis()获得。系统值是1 (0x00000001) 。

9. public static final int RTC_WAKEUP

10. //能唤醒系统,用法同RTC类型,系统值为 0 (0x00000000) 。

11. Public static final int POWER_OFF_WAKEUP

12.

13. //能唤醒系统,它是一种关机闹铃,就是说设备在关机状态下也可以唤醒系统,所以

我们把它称之为关机闹铃。使用方法同RTC类型,系统值为

14. 4(0x00000004)。

注意一个重要的参数PendingIntent。这个PendingIntent可以说是 Intent的进一步封装,他既包含了Intent的描述又是Intent行为的执行(这种定义也许不太严格),如果将Intent比作成一个订单的话,PendingIntent更像是一个下订单的人,因为它既要负责将订

单发出去,也要负责订单发送后的处理,比如发送成功后要准备验收订单货物,发送失败后

要重发还是取消订单等操作。开发者可以通过调用getActivity(Context, int, Intent, int) getBroadcast(Context, int, Intent, int)

getService(Context, int, Intent, int)

三种不同方式来得到一个PendingIntent实例。

getBroadcast——通过该函数获得的PendingIntent将会扮演一个广播的功能,就像调用Context.sendBroadcast()函数一样。当系统通过它要发送一个intent时要采用广播的形式,并且在该intent中会包含相应的 intent接收对象,当然这个对象我们可以在创建PendingIntent的时候指定,也可以通过ACTION 和CATEGORY等描述让系统自动找到该行为

处理对象。

1. Intent intent = new Intent(AlarmController. this , OneShotAlarm. class );

2. PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this , 0 ,

intent, 0 );

getActivity——通过该函数获得的PendingIntent可以直接启动新的activity, 就像调用Context.startActivity(Intent)一样.不过值得注意的是要想这个新的Activity不再是当

前进程存在的Activity 时。我们在intent中必须使用Intent.FLAG_ACTIVITY_NEW_TASK.

// The PendingIntent to launch our activity if the user selects this notification

1. PendingIntent contentIntent = PendingIntent.getActivity(this , 0 , new Intent( this , AlarmService. class ), 0 );

getService——通过该函数获得的PengdingIntent可以直接启动新的Service,就像调用Context.startService()一样。

// Create an IntentSender that will launch our service, to be scheduled

// with the alarm manager.

1. mAlarmSender = PendingIntent.getService(AlarmService.this , 0 , new Intent(AlarmService. this , AlarmService_Service. class ), 0 );

实例:

/Chapter08_Broadcast_AlarmManager/src/com/amaker/ch08/app/MainActivity.java

代码

package com.amaker.ch08.app;

import com.amaker.ch08.app.R;

import android.app.Activity;

import android.app.AlarmManager;

import android.app.PendingIntent;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

/**

*

* 测试AlarmManager

*/

public class MainActivity extends Activity {

// 声明Button

private Button setBtn, cancelBtn;

// 定义广播Action

private static final String BC_ACTION = "com.amaker.ch08.app.action.BC_ACTION";

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 设置当前布局视图

setContentView(https://www.360docs.net/doc/3914625954.html,yout.main);

// 实例化Button

setBtn = (Button) findViewById(R.id.Button01);

cancelBtn = (Button) findViewById(R.id.Button02);

// 获得AlarmManager实例

final AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);

// 实例化Intent

Intent intent = new Intent();

// 设置Intent action属性

intent.setAction(BC_ACTION);

intent.putExtra("msg", "你该去开会啦!");

// 实例化PendingIntent

final PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);

// 获得系统时间

final long time = System.currentTimeMillis();

// 设置按钮单击事件

setBtn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// 重复提示,从当前时间开始,间隔5秒

am.setRepeating(AlarmManager.RTC_WAKEUP, time,

8 * 1000, pi);

}

});

// 设置按钮单击事件

cancelBtn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

am.cancel(pi);

}

});

}

}

/Chapter08_Broadcast_AlarmManager/src/com/amaker/ch08/app/MyReceiver.java 代码

package com.amaker.ch08.app;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// 获得提示信息

String msg = intent.getStringExtra("msg");

// 显示提示信息

Toast.makeText(context, msg, Toast.LENGTH_LONG).show();

}

}

/Chapter08_Broadcast_AlarmManager/res/layout/main.xml

代码

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:text="设置闹钟"

android:id="@+id/Button01"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

android:text="取消闹钟"

android:id="@+id/Button02"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

/Chapter08_Broadcast_AlarmManager/AndroidManifest.xml

代码

package="com.amaker.ch08.app"

android:versionCode="1"

android:versionName="1.0">

android:label="@string/app_name">

================================================================================ AlarmManager的使用机制有的称呼为全局定时器,有的称呼为闹钟。通过对它的使用,个人

觉得叫全局定时器比较合适,其实它的作用和Timer有点相似。都有两种相似的用法:(1)在指定时长后执行某项操作(2)周期性的执行某项操作

AlarmManager对象配合Intent使用,可以定时的开启一个Activity,发送一个BroadCast,或者开启一个Service.

下面的代码详细的介绍了两种定时方式的使用:

(1)在指定时长后执行某项操作

代码

//操作:发送一个广播,广播接收后Toast提示定时操作完成

Intent intent =new Intent(Main.this, alarmreceiver.class);

intent.setAction("short");

PendingIntent sender=

PendingIntent.getBroadcast(Main.this, 0, intent, 0);

//设定一个五秒后的时间

Calendar calendar=Calendar.getInstance();

calendar.setTimeInMillis(System.currentTimeMillis());

calendar.add(Calendar.SECOND, 5);

AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE);

alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);

//或者以下面方式简化

//alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+5*1000, sender);

Toast.makeText(Main.this, "五秒后alarm开启", Toast.LENGTH_LONG).show();

//注意:receiver记得在manifest.xml注册

代码

public static class alarmreceiver extends BroadcastReceiver{

@Override

public void onReceive(Context context, Intent intent) {

// TODO Auto-generated method stub

if(intent.getAction().equals("short")){

Toast.makeText(context, "short alarm", Toast.LENGTH_LONG).show();

}else{

Toast.makeText(context, "repeating alarm",

Toast.LENGTH_LONG).show();

}

}

}

(2)周期性的执行某项操作

代码

Intent intent =new Intent(Main.this, alarmreceiver.class);

intent.setAction("repeating");

PendingIntent sender=PendingIntent

.getBroadcast(Main.this, 0, intent, 0);

//开始时间

long firstime=SystemClock.elapsedRealtime();

AlarmManager am=(AlarmManager)getSystemService(ALARM_SERVICE);

//5秒一个周期,不停的发送广播

am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP

, firstime, 5*1000, sender);

AlarmManager的setRepeating()相当于Timer的Schedule(task,delay,peroid);有点差异的地方时Timer这个方法是指定延迟多长时间

以后开始周期性的执行task;

AlarmManager的取消:(其中需要注意的是取消的Intent必须与启动Intent保持绝对一致才能支持取消AlarmManager)

代码

Intent intent =new Intent(Main.this, alarmreceiver.class);

intent.setAction("repeating");

PendingIntent sender=PendingIntent

.getBroadcast(Main.this, 0, intent, 0);

AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE);

alarm.cancel(sender);

================================================================================

Android-AlarmManager多个闹钟相互独立的实现

分类:android学习经验

2010.8.8 17:55 作者:mgbin2010 | 评论:2 | 阅读:6061

首届Google暑期大学生博客分享大赛——2010 Andriod篇

最近在做一个android的记事本,准备在其中添加闹钟提醒功能,由于想要每个记事之间的闹钟互不影响,但是google n久以后却发现网上的demo都是单个闹钟的。

最后经过自己测试终于搞定,现在把解决办法写下来跟大家分享下,有什么错误不妥的地方还希望大家帮忙提醒,大家一起进步。

Intent i=new Intent(TimeSetActivity.this,AlarmReceiver.class);

PendingIntent pi = PendingIntent.getBroadcast(TimeSetActivity.this,Integer.valueOf(id) , i, 0); //通过getBroadcast第二个参数区分闹钟,将查询得到的note的ID值作为第二个参数。

AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);

am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);//设置闹铃

Intent i=new Intent(TimeSetActivity.this,AlarmReceiver.class);

PendingIntent pi = PendingIntent.getBroadcast(TimeSetActivity.this,Integer.valueOf(id) , i, 0); am.cancel(pi);//取消闹钟

这样就通过getBroadcast的第二个参数有效的区分了各个闹钟,不知道这种方法是否妥当,不过还是达到了想要的目的。

希望有更好办法的朋友将您的办法留言告诉我,好让我更好的学习。

================================================================================

android之定时器AlarmManager 收藏

最终效果图:

当我们点击定时时,会弹出一个时间选择器,选定好时间之后,系统便可以进行定时了。注意,这里可不是会真的响铃,我们在定时的任务里并没有添加响铃的代码,只是在Logcat中做了个简单的打印。本例子重点在于讲解在android中AlarmManager的使用。

activity的代码:

view plaincopy to clipboardprint?

1. package https://www.360docs.net/doc/3914625954.html,.chenzheng_java;

2.

3. import java.util.Calendar;

4.

5. import android.app.Activity;

6. import android.app.AlarmManager;

7. import android.app.PendingIntent;

8. import android.app.TimePickerDialog;

9. import android.app.TimePickerDialog.OnTimeSetListener;

10. import android.content.Intent;

11. import android.os.Bundle;

12. import android.util.Log;

13. import android.view.View;

14. import android.view.View.OnClickListener;

15. import android.widget.Button;

16. import android.widget.CheckBox;

17. import https://www.360docs.net/doc/3914625954.html,poundButton;

18. import android.widget.TimePicker;

19. import https://www.360docs.net/doc/3914625954.html,poundButton.OnCheckedChangeListener;

20.

21. public class AlarmManagerActivity extends Activity implements OnClickListener,OnTimeSetListener,OnCheckedChangeListener{

22. Calendar calendar = Calendar.getInstance();// 代表当前时间的日历

23. Button button1 ;

24. CheckBox checkBox;

25. boolean flag = false ;// 是否只执行一次

26.

27. @Override

28. protected void onCreate(Bundle savedInstanceState) {

29. super.onCreate(savedInstanceState);

30. setContentView(https://www.360docs.net/doc/3914625954.html,yout.alarm);

31.

32. button1 = (Button) findViewById(R.id.button_alarm1);

33. checkBox = (CheckBox) findViewById(R.id.checkBox1_alarm);

34. checkBox.setOnCheckedChangeListener(this);

35.

36. button1.setOnClickListener(this);

37. }

38.

39. @Override

40. public void onClick(View v) {

41. if(v==button1){

42. calendar.setTimeInMillis(System.currentTimeMillis());

43. new TimePickerDialog(AlarmManagerActivity.this, this,

44. calendar.get(Calendar.HOUR_OF_DAY),

45. calendar.get(Calendar.MINUTE), true).show();

46. }

47. }

48.

49. /**

50. * 当我们设置了新时间时触发。

51. */

52. @Override

53. public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

54.

55. // 将时间设置为定时的时间

56. calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);

57. calendar.set(Calendar.MINUTE, minute);

58.

59. Intent intent = new Intent(AlarmManagerActivity.this,MyAlarmBroadCast.class);

60. PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);

61.

62. /***

63. * 获取全局定时器的服务管理器

64. */

65. AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

66.

67. if(flag){

68.

69.

70. /**

71. * 指定的任务只会执行一次,如果该pendingIntent指定的任务已经被执行过了,那么该方法直接会被cancel掉。

72. * set(int type, long triggerAtTime, PendingIntent operation)

73. * type 指定定时模式。

74. * triggerAtTime 触发任务的时间。该参数和定时模式息息相关

75. * operation 该参数指定一个广播Intent,当时间到了时,系统会广播里面的intent,触发相应的广播接收者执行某些操作,比如响铃……

76. */

77. alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

78. }

79. else

80. {

81. /**

82. * 通过该方法指定的任务会一直间隔执行,第三个参数就指定了执行的

时间间隔

83. * 如果我们想取消的话,请使用:alarmManager.cancel(pendingIntent);

84. * 注意,这里的pendingIntent要和setRepeating方法中的一致哦。

85. */

86. alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5*1000, pendingIntent);

87. }

88. Log.i("通知", "定时成功!");

89.

90. }

91.

92.

93.

94. @Override

95. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

96. flag = !isChecked;

97. }

98.

99.

100.

101.

102. }

package https://www.360docs.net/doc/3914625954.html,.chenzheng_java; import java.util.Calendar; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.TimePickerDialog; import android.app.TimePickerDialog.OnTimeSetListener; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; import https://www.360docs.net/doc/3914625954.html,poundButton; import android.widget.TimePicker; import https://www.360docs.net/doc/3914625954.html,poundButton.OnCheckedChangeListener; public class AlarmManagerActivity extends Activity implements OnClickListener,OnTimeSetListener,OnCheckedChangeListener{ Calendar calendar = Calendar.getInstance();// 代表当前时间的日历 Button button1 ; CheckBox checkBox; boolean flag = false ;// 是否只执行一次 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(https://www.360docs.net/doc/3914625954.html,yout.alarm); button1 = (Button) findViewById(R.id.button_alarm1); checkBox = (CheckBox) findViewById(R.id.checkBox1_alarm); checkBox.setOnCheckedChangeListener(this); button1.setOnClickListener(this); } @Override public void onClick(View v) { if(v==button1){ calendar.setTimeInMillis(System.currentTimeMillis()); new

TimePickerDialog(AlarmManagerActivity.this, this, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true).show(); } } /** * 当我们设置了新时间时触发。*/ @Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { // 将时间设置为定时的时间calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); calendar.set(Calendar.MINUTE, minute); Intent intent = new Intent(AlarmManagerActivity.this,MyAlarmBroadCast.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0); /*** * 获取全局定时器的服务管理器 */ AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); if(flag){ /** * 指定的任务只会执行一次,如果该pendingIntent指定的任务已经被执行过了,那么该方法直接会被cancel掉。 * set(int type, long triggerAtTime, PendingIntent operation) * type 指定定时模式。 * triggerAtTime 触发任务的时间。该参数和定时模式息息相关 * operation 该参数指定一个广播Intent,当时间到了时,系统会广播里面的intent,触发相应的广播接收者执行某些操作,比如响铃……*/ alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } else { /** * 通过该方法指定的任务会一直间隔执行,第三个参数就指定了执行的时间间隔* 如果我们想取消的话,请使用:alarmManager.cancel(pendingIntent); * 注意,这里的pendingIntent要和setRepeating 方法中的一致哦。*/ alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5*1000, pendingIntent); } Log.i("通知", "定时成功!"); } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { flag = !isChecked; } }

alarm.xml

view plaincopy to clipboardprint?

1.

2.

3. android:layout_width="match_parent" android:layout_height="match_parent"

4. android:orientation="vertical">

5.

6. android:layout_width="wrap_content" android:layout_height="wrap_content">

7.

android:layout_height="wrap_content">

8.

10.

xmlns:android="https://www.360docs.net/doc/3914625954.html,/apk/res/android"

android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">

android:layout_height="wrap_content">

MyAlarmBroadCast.java

view plaincopy to clipboardprint?

1. package https://www.360docs.net/doc/3914625954.html,.chenzheng_java;

2.

3. import android.content.BroadcastReceiver;

4. import android.content.Context;

5. import android.content.Intent;

6. import android.util.Log;

7. import android.widget.Toast;

8.

9. /**

10. * 声明接受AlarmManager时间到了时发布的广播

11. * @author chenzheng_java

12. */

13. public class MyAlarmBroadCast extends BroadcastReceiver{

14.

15. @Override

16. public void onReceive(Context context, Intent intent) {

17. Log.i("通知", "收到了广播");

18. // 可以在此处添加响铃的代码

19. }

20.

21. }

package https://www.360docs.net/doc/3914625954.html,.chenzheng_java; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; /** * 声明接受AlarmManager时间到了时发布的广播 * @author chenzheng_java */ public class MyAlarmBroadCast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Log.i("通知", "收到了广播"); // 可以在此处添加响铃的代码 } }

Manifest.xml代码:

view plaincopy to clipboardprint?

1.

2.

3. package="https://www.360docs.net/doc/3914625954.html,.chenzheng_java"

4. android:versionCode="1"

5. android:versionName="1.0">

6.

7.

8.

9.

10. android:label="@string/app_name">

11.

12.

13.

14.

15.

16.

17.

18.

package="https://www.360docs.net/doc/3914625954.html,.chenzheng_java" android:versionCode="1" android:versionName="1.0">

------------------------------------------------------------------

AlarmManager的使用机制有的称呼为全局定时器,有的称呼为闹钟。通过对它的使用,个人觉得叫全局定时器比较合适,其实它的作用和Timer有点相似。都有两种相似的用法:(1)在指定时长后执行某项操作(2)周期性的执行某项操作

使用的步骤:

第一:获取管理器。AlarmManager alarmManager = this.getSystemService(ALARM_SERVICE);

第二:通过AlarmManager的set和setRepeating方法定时。可以通过cancel()方法取消定时。

在set和setRepeating方法中,第一个参数type代表定时模式,这里的定时模式主要有以下几种。

相关主题
相关文档
最新文档