安卓开发笔记——Broadcast广播机制(实现自定义小闹钟)

什么是广播机制?

简单点来说,是一种广泛运用在程序之间的传输信息的一种方式。比如,手机电量不足10%,此时系统会发出一个通知,这就是运用到了广播机制。

广播机制的三要素:

Android广播机制包含三个要素:广播(Broadcast) - 用于发送广播;广播接收器(BroadcastReceiver) - 用于接收广播;意图(Intent)-用于保存广播相关信息的媒介。

可以把它理解成我们的传统电视台,我们的电视就是一个广播接收器,然而电视有很多频道,是由电视台发送出来的,也就是广播了,意图可以理解成不同频道所播放的不同电视内容。我们每次只能观看一个频道,也就是说一个广播接收器只能接受一个广播,至于如何去区分到底是哪个广播接收器接收哪个广播,这里会有个过滤器intent-filter,我们只需要去设置intent的action标示符即可(下文会提到)。

首先,先来说下广播接收器(BroadcastReceiver):

我们要使用一个广播需要先注册它,就像我们新添一个Activity一样,需要在AndroidManifest.xml里面声明,广播亦是如此。

广播接收器注册,这里提供了2种方式

1、静态注册,也就是在配置文件AndroidManifest.xml声明:

1         <receiver
2             android:name="广播接收器所在的包名类名"
3             android:enabled="true"
4             android:process=":remote" >
5             <intent-filter>
6                 <action android:name="过滤标示符,用来区分接收哪个广播" />
7             </intent-filter>
8         </receiver>

2、代码动态注册:

1 //创建一个广播接受者
2 MyReceiver receiver = new MyReceiver();
3 //创建过滤器,并指定action,使之用于接收同action的广播
4 IntentFilter filter = new IntentFilter("过滤标示符,用来区分接收哪个广播");5 //注册广播接收器 6 Context.registerReceiver(receiver, filter); 

通过静态方式注册的广播接收器,不需要手动注销,该对象的实例在onReceive被调用之后就会在任意时间内被销毁,而通过动态方式注册的广播接收器,则需要在Activity进入停止或者销毁状态的时候使用unregisterReceiver方法手动注销。

1 //注销广播接收器
2 unregisterReceiver(receiver);

创建广播接收器也很简单,只需要去继承BroadcastRecevice并实现OnReceive方法即可,当广播发送后,系统会去检查广播接收器的过滤器与广播所发送的Intent是否一致, 如果一致调用OnReceive方法,若没有,广播接收器会一直存在着。

1 public class MyReceiver extends BroadcastReceiver {
2
3     @Override
4     public void onReceive(Context context, Intent intent) {
5         // TODO Auto-generated method stub
6     }
7 }

注意事项:

BroadcastReceiver的生命周期只有10秒,不要在OnReceive方法内执行任何耗时操作,若要执行耗时操作可以通过发送Intent给Service操作,切记不能去开子线程,由于BroadcastReceiver只有10秒的生命周期,当宿主线程挂了,那么子线程也自动销毁了。

广播(Broadcast):

先来说下广播的种类,分为三种:

普通广播(Normal Broadcasts):

1、所有广播接收者都可以接收到的广播,同级别的接收者接收顺序随机不确定。

2、不能拦截广播的继续传播也不能处理处理广播

3、同级别动态注册高于静态注册

有序广播(Ordered Broadcasts):

1、按照接收者的优先级接收,优先级可以在intnt-filter里的priority里设置,值越大,优先级越高。

2、可以拦截广播的继续传播,高级别的广播接收器可以决定低级别的广播接收器是否能接收到广播。可以处理广播。

3、同级别动态注册高于静态注册

黏性广播(Sticky Broadcasts):

1、不能处理广播传递给下一个接收者,而且广播一直存在,不销毁。(不常用)

发送广播的方式:

以上3种广播的发送方式分别是:

Context.sendBroadcast()

Context.sendOrderBroadcast()

Context.sendStickyBroadcast()

随手写了个简单小demo,看下效果:

广播接收类:

 1 package com.example.broadcasttest;
 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 MyBroadcastReceive extends BroadcastReceiver {
 9
10     @Override
11     public void onReceive(Context context, Intent intent) {
12         Toast.makeText(context, "广播被收到了!", Toast.LENGTH_SHORT).show();
13     }
14
15 }

主程序类:

 1 package com.example.broadcasttest;
 2
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Button;
 9
10 public class MainActivity extends Activity {
11
12     private Button bt;
13     @Override
14     protected void onCreate(Bundle savedInstanceState) {
15         super.onCreate(savedInstanceState);
16         setContentView(R.layout.activity_main);
17
18         this.bt=(Button) findViewById(R.id.button);
19         bt.setOnClickListener(new OnClickListener() {
20
21             @Override
22             public void onClick(View v) {
23                 Intent intent=new Intent();
24                 intent.putExtra("msg", "你好,我是一个广播");
25                 intent.setAction("com.lcw.broadcast");
26                 intent.setClass(MainActivity.this, MyBroadcastReceive.class);
27
28                 MainActivity.this.sendBroadcast(intent);
29             }
30         });
31
32     }
33
34 }

AndroidManifest.xml

1         <receiver
2             android:name="com.example.broadcasttest.MyBroadcastReceive"
3             >
4             <intent-filter>
5                 <action android:name="com.lcw.broadcast"></action>
6              </intent-filter>
7         </receiver>

配合PendingIntent和广播机制实现一个小闹钟:

先看来先什么是PendingIntent:

Intent的主要功能是表示用户的一种操作意图,当用户使用Intent之后则立刻执行用户所需要的操作,但是在Android之中也提供了一个PendingIntent操作,表示的是将要发生的操作,所谓的将要发生的Intent指的是在当前的Activity不立即使用此Intent进行处理,而将此Intent封装后传递给其他的Activity程序,而其他的Activity程序在需要使用此Intent时才进行操作。(更简单来讲:PendingIntent就是Intent的延迟包装类)

下面是PendingIntent的一些常用API:


No.

方法及常量

类型

描述

1

public static final int FLAG_CANCEL_CURRENT

常量

重新生成一个新的PendingIntent对象

2

public static final int FLAG_NO_CREATE

常量

如果不存在PendingIntent对象,则创建一个新的

3

public static final int FLAG_ONE_SHOT

常量

创建的PendingIntent对象只使用一次

4

public static final int FLAG_UPDATE_CURRENT

常量

如果PendintIntent对象已经存在,则直接使用,并且实例化一个新的Intent对象

5

public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags)

普通

通过PendingIntent启动一个新的Activity

6

public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)

普通

通过PendingIntent启动一个新的Broadcast

7

public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags)

普通

通过PendingIntent启动一个新的Service

好了,直接代码说话吧,国际惯例先看下效果图:

  

上图的效果是利用PendingIntent包装一个意图为系统闹钟的Intent延迟到指定时间发送广播,然后定义了一个广播接收器不断扫描系统,一旦接收到此广播立即在广播接受器的OnReceive方法里调用另一个Activity,而这个Activity仅仅是一个对话框用来显示信息,如二图。由于使用到了广播机制,所以就算不开着这个Activity也可以在后台监控着这个广播。

看下具体代码吧,首先是这个对话框类,很简单的一个AlertDialog

 1 package com.example.alarmtest;
 2
 3 import java.text.SimpleDateFormat;
 4 import java.util.Date;
 5
 6 import android.app.Activity;
 7 import android.app.AlertDialog;
 8 import android.content.DialogInterface;
 9 import android.os.Bundle;
10
11 /**
12  *
13  * 闹钟警报类(对话框显示)
14  *
15  */
16 public class AlarmActivity extends Activity {
17     @Override
18     protected void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         new AlertDialog.Builder(AlarmActivity.this)
21                 .setIcon(R.drawable.ic_launcher)
22                 .setTitle("闹钟提醒")
23                 .setMessage(
24                         "闹钟响起,当前时间为:"
25                                 + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
26                                         .format(new Date()))
27                 .setPositiveButton("关闭", new DialogInterface.OnClickListener() {
28
29                     @Override
30                     public void onClick(DialogInterface dialog, int which) {
31                         AlarmActivity.this.finish();
32                     }
33                 }).show();
34     }
35 }

再来看下广播接收器类,这里只是在Receive方法里调用上面那个Activity

 1 package com.example.alarmtest;
 2
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 /**
 7  *
 8  * 广播接收类(跳转闹钟提醒类)
 9  *
10  */
11 public class AlarmBroadcastReceiver extends BroadcastReceiver {
12
13     @Override
14     public void onReceive(Context context, Intent intent) {
15             Intent intent2=new Intent(context,AlarmActivity.class);
16             intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
17             context.startActivity(intent2);
18     }
19
20 }

看下主程序类

  1 package com.example.alarmtest;
  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.content.Intent;
  9 import android.os.Bundle;
 10 import android.view.View;
 11 import android.view.View.OnClickListener;
 12 import android.widget.Button;
 13 import android.widget.TextView;
 14 import android.widget.TimePicker;
 15 import android.widget.Toast;
 16 import android.widget.TimePicker.OnTimeChangedListener;
 17
 18 public class MainActivity extends Activity {
 19     // 声明界面控件
 20     private TimePicker timePicker;
 21     private TextView textView;
 22     private Button set;
 23     private Button cancel;
 24
 25     // 变量
 26     private int hourOfDay = 0;
 27     private int minute = 0;
 28
 29     // 日期操作
 30     private Calendar calendar;
 31
 32     // 闹钟管理
 33     private AlarmManager alarmManager;
 34
 35     @Override
 36     protected void onCreate(Bundle savedInstanceState) {
 37         super.onCreate(savedInstanceState);
 38         setContentView(R.layout.activity_main);
 39         initView();// 初始化控件
 40         initAction();// 初始化事件
 41     }
 42
 43     private void initAction() {
 44         this.timePicker.setOnTimeChangedListener(new OnTimeChangedListener() {// 设置时间控件监听
 45
 46                     @Override
 47                     public void onTimeChanged(TimePicker view, int hourOfDay,
 48                             int minute) {// 这是回调函数,hourOfDay指当前选中时间,minute指当前选中分钟
 49                         // 实例化并设置Calendar类
 50                         MainActivity.this.calendar = Calendar.getInstance();
 51                         MainActivity.this.calendar.setTimeInMillis(System
 52                                 .currentTimeMillis());
 53                         MainActivity.this.calendar.set(Calendar.HOUR_OF_DAY,
 54                                 hourOfDay);
 55                         MainActivity.this.calendar.set(Calendar.MINUTE, minute);
 56                         MainActivity.this.calendar.set(Calendar.SECOND, 0);
 57                         // 存储变量值,便于一会更新TextView控件
 58                         MainActivity.this.hourOfDay = hourOfDay;
 59                         MainActivity.this.minute = minute;
 60
 61                     }
 62                 });
 63
 64         this.set.setOnClickListener(new OnClickListener() {// 设置确定按钮监听
 65
 66             @Override
 67             public void onClick(View v) {
 68                 Intent intent = new Intent(MainActivity.this,
 69                         AlarmBroadcastReceiver.class);
 70                 intent.setAction("com.lcw.alarm");
 71                 PendingIntent operation = PendingIntent.getBroadcast(
 72                         MainActivity.this, 0, intent,
 73                         PendingIntent.FLAG_UPDATE_CURRENT);// 启动一个广播,PendingIntent为Intent的包装
 74                 MainActivity.this.alarmManager
 75                         .set(AlarmManager.RTC_WAKEUP,
 76                                 MainActivity.this.calendar.getTimeInMillis(),
 77                                 operation);
 78                 MainActivity.this.textView.setText("闹钟时间:"
 79                         + MainActivity.this.hourOfDay + "时"
 80                         + MainActivity.this.minute + "分" + "00秒");
 81                 Toast.makeText(MainActivity.this, "闹钟设置完毕!", Toast.LENGTH_SHORT)
 82                         .show();
 83
 84             }
 85         });
 86
 87         this.cancel.setOnClickListener(new OnClickListener() {// 取消按钮监听
 88
 89                     @Override
 90                     public void onClick(View v) {
 91                         Intent intent = new Intent(MainActivity.this,
 92                                 AlarmBroadcastReceiver.class);
 93                         intent.setAction("com.lcw.alarm");
 94                         PendingIntent operation = PendingIntent.getBroadcast(
 95                                 MainActivity.this, 0, intent,
 96                                 PendingIntent.FLAG_UPDATE_CURRENT);
 97                         MainActivity.this.alarmManager.cancel(operation);
 98                         MainActivity.this.textView.setText("当前闹钟未设置");
 99                         Toast.makeText(MainActivity.this, "闹钟已删除!",
100                                 Toast.LENGTH_SHORT).show();
101                     }
102                 });
103
104     }
105
106     private void initView() {
107         this.timePicker = (TimePicker) findViewById(R.id.timepicker);
108         this.timePicker.setIs24HourView(true);// 设置时间控件24小时制
109         this.textView = (TextView) findViewById(R.id.timetext);
110         this.set = (Button) findViewById(R.id.set);
111         this.cancel = (Button) findViewById(R.id.cancel);
112
113         MainActivity.this.alarmManager = (AlarmManager) MainActivity.this
114                 .getSystemService(ALARM_SERVICE);// 获取系统闹钟管理实例
115     }
116
117 }
时间: 2024-10-27 18:26:27

安卓开发笔记——Broadcast广播机制(实现自定义小闹钟)的相关文章

安卓开发笔记——高仿新浪微博文字处理(实现关键字高亮,自定义表情替换并加入点击事件实现)

先让大家看下效果图,这个是我自己在闲暇时间仿写的新浪微博客户端: 今天来讲讲如何实现上图的效果,这里需要用到SpannableString这个工具类,如果你对这个类并不熟悉,可以先看下我之前写的2篇文章: <安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607.html <安卓开发笔记——丰富多彩的TextView>:http://www.cnblogs.com/lichenwei/p/46120

安卓开发笔记——自定义广告轮播Banner(无限循环实现)

关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户"友好性",下面来看几个示例图:     再来看下我仿写的效果: 关于广告轮播Banner这个东西,GitHub上面应该有现成的开源组件,不过我没去找过,觉得实现起来不会太难,就自己去仿写了,下面我说下实现的思路: 1.首先看到这个可以滑动切换图片的界面,我们很自然就会想到ViewPager

安卓开发笔记——丰富多彩的TextView

随手笔记,记录一些东西~ 记得之前写过一篇文章<安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607.html 文章里实现个性化TextView的主要方法是通过替换的方式,对关键字进行一些个性化处理,晚上再来补充一种实现方式. 老规矩,先看下效果图: 晚上带来的这种实现方式是通过Android官方给我们提供的Html类下面的fromHtml方法,这个方法可以对字符串进行HTML格式化,让TextView等一些

安卓开发笔记——关于Handler的一些总结(上)

接上篇文章<安卓开发笔记——关于AsyncTask的使用>,今天来讲下在安卓开发里"重中之重"的另一个异步操作类Handler. 今天打算先讲下关于Handler的一些基本定义和使用方式 还是以一个下载图片为例,先看下实例效果: 好了,先来看下关于Handler的定义: 以上是官方对于Hanler类的描述,大致意思是说:Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息

安卓开发笔记——打造属于自己的博客园APP(四)

在上篇文章<安卓开发笔记——打造属于自己的博客园APP(三)>中,我们对博客文章的详情页和评论页进行了实现,慢慢的一个APP已经出现雏形了,当然这只是完成了"表面效果",要真正做好一个APP并不是一件很轻松的事情,有很多细节需要我们一点一滴的去完善. 好了,来讲下今天要完成的效果,在优化了之前部分代码的前提下,今天来说下关于博客搜索和博客详情页的实现,依旧国际惯例,来看下效果图:(动态图片比较大,加载需要点时间) 效果比较简单,很多东西我们还是可以复用之前的代码,毕竟这种列

安卓开发笔记——打造万能适配器(Adapter)

为什么要打造万能适配器? 在安卓开发中,用到ListView和GridView的地方实在是太多了,系统默认给我们提供的适配器(ArrayAdapter,SimpleAdapter)经常不能满足我们的需要,因此我们时常要去继承BaseAdapter类去实现一个自定义的适配器来满足我们的场景需要. 如果你是开发一个简单点的APP还好,可能ListView和GridView的数量不会太多,我们只要去写几个BaseAdapter实现类就可以了. 但如果有一天,你需要开发一个APP里面具有几十个ListV

安卓开发笔记——打造属于自己的博客园APP(二)

在上一篇文章<安卓开发笔记——打造属于自己的博客园APP(一)>中,我们基本上实现了博客园的主体UI框架(后面可能会有些小变化,等遇到了再说).今天来讲讲博客园首页模块的大体实现,国际惯例,先来看下效果图: 整体UI效果: 下拉刷新和上拉加载的动画效果: 在上篇文章中,我们定义的Tabs主题文字分别是(首页,精华,候选,推荐),这边的命名我是根据博客园网站首页的栏目来命名的,那时候我还没仔细看过博客园的开放接口,后来才发现原来博客园没有对应开放这些栏目的接口,博客园只开放了(文章列表,48小时

[开发技巧]&#183;Numpy广播机制的深入理解与应用

[开发技巧]·Numpy广播机制的深入理解与应用 1.问题描述 我们在使用Numpy进行数据的处理时,经常会用到广播机制来简化操作,例如在所有元素都加上一个数,或者在某些纬度上作相同的操作.广播机制很方便,但是概念却也有些复杂,可能会让一些初学者感到困惑,在使用过程中,产生一些错误. 本文以实战演练的方式来讲解广播机制的概念与应用,不仅仅适用于Numpy,在TensorFlow,PyTorch,MxNet的广播机制中同样适用. 2.原理讲解 广播机制遵循一下准则: 1.首先以最长纬度为准拓展为相

安卓 开发笔记目录

安卓 开发笔记index 安卓基础 Fragment总结 安卓 BroadcastReceiver笔记 安卓 Notification-通知总结 开源框架笔记 安卓 okhttp小结 EventBus框架总结 安卓 图片加载框架ImageLoader 第三方SDK 安卓 短信验证MobSMS集成 开源项目 其他 安卓 常用属性设置代码笔记 安卓 代码混淆与打包 AOSP开发笔记 开发工具 SecureCRT连接Ubuntu配置 Ubuntu开发环境搭建 开发环境 AOSP android7.1.