一、BroadcastReceiver概述:
1、广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码的──比如,通知时区改变、电池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播──比如说,通知其它应用程序一些数据下载完成并处于可用状态。
2、应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应。所有的接收器均继承自BroadcastReceiver基类。
3、广播接收器没有用户界面。然而,它们可以启动一个activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
二、BroadcastReceiver事件分类
1、系统广播事件,比如:ACTION_BOOT_COMPLETED(系统启动完成后触发),ACTION_TIME_CHANGED(系统时间改变时触发),ACTION_BATTERY_LOW(电量低时触发)等等。
2、用户自定义的广播事件。
三、BroadcastReceiver事件的编程流程
1、注册广播事件:注册方式有两种,
一种是静态注册,就是在 AndroidManifest.xml文件中定义,注册的广播接收器必须要继承BroadcastReceiver类;
在AndroidManifest.xml中用标签生命注册,并在标签内用标签设置过滤器:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lanxin.testreceiver" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".TestReceiver1"> <intent-filter> <action android:name="com.testreceiver.test1"></action> </intent-filter> </receiver> <receiver android:name=".TestReceiver2"> <intent-filter> <action android:name="com.testreceiver.test1"></action> </intent-filter> </receiver> <service android:name=".TestIntentService"/> </application> <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission> </manifest>
启动一条广播通知:
but1 = (Button)findViewById(R.id.button); but1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent mIntent = new Intent("com.testreceiver.test1"); Bundle b = new Bundle(); b.putString("msg","测试一条消息:"+count); count++; Log.i(TAG,"before"+count); mIntent.putExtras(b); sendBroadcast(mIntent); Log.i(TAG, "after:" + count); } });
如何在广播接收器中处理通知:
package com.lanxin.testreceiver; import android.app.Notification; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; /** * Created by Administrator on 2016/6/5 0005. */ public class TestReceiver1 extends BroadcastReceiver { private static final String TAG = "TestReceiver1"; private static final int _ID = 0x11242; @Override public void onReceive(Context context, Intent intent) { Utils.logThreadSignature(TAG); Bundle b = intent.getExtras(); Log.i(TAG, b.getString("msg")); sendNotification(context,b.getString("msg")); //Intent intent1 = new Intent(context,TestIntentService.class); //context.startService(intent1); Utils.logThreadSignature(TAG); } private static void sendNotification(Context mContext,String msg){ NotificationManager nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = new Notification.Builder(mContext) .setAutoCancel(true) //notification.setLargeIcon(R.drawable.notification) .setSmallIcon(R.drawable.notification) .setSubText("新消息") .setTicker(msg) .setContentText(msg) .setDefaults(Notification.DEFAULT_SOUND).build(); nm.notify(_ID,notification); } }
如果工作量少,执行时间短,那么我们可以直接在onReceive实现工作的逻辑代码就可以了,但如果多的就需要启动一个intentService的服务来执行,红色的代码就是启动服务执行。
启用服务执行,我们可能需要一把唤醒锁,首先我们贴出服务代码:
package com.lanxin.testreceiver; import android.app.IntentService; import android.app.Service; import android.content.Intent; import android.support.v4.content.WakefulBroadcastReceiver; import android.util.Log; /** * Created by Alan on 2016/6/5 0005. */ public class TestIntentService extends IntentService { private static final String TAG = "TestIntentService"; /** * Creates an IntentService. Invoked by your subclass's constructor. */ public TestIntentService() { super("TestIntentService"); } public void onCreate() { super.onCreate(); Log.i(TAG, "Service onCreate"); //唤醒锁安装 LightedGreenRoom.setup(this.getApplicationContext()); //唤醒锁注册 LightedGreenRoom.s_registerClient(); } public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); Log.i(TAG, "Service onStartCommand"); //唤醒锁进入 LightedGreenRoom.s_enter(); return Service.START_NOT_STICKY; } public void onDestroy() { super.onDestroy(); //唤醒锁卸载 LightedGreenRoom.s_unregisterClient(); Log.i(TAG,"Service onDestroy"); } @Override protected void onHandleIntent(Intent intent) { for (int i = 0; i < 2; i++){ Utils.logThreadSignature(TAG); Log.i(TAG,"onHandleIntent:"+i); //Utils.sleep(20); } //工作完成,释放 LightedGreenRoom.s_leave(); } }
唤醒锁的执行周期:
//唤醒锁安装 LightedGreenRoom.setup(this.getApplicationContext()); //唤醒锁注册 LightedGreenRoom.s_registerClient();
//唤醒锁进入 LightedGreenRoom.s_enter();
//工作完成,释放 LightedGreenRoom.s_leave();
//唤醒锁卸载 LightedGreenRoom.s_unregisterClient(); 以下是唤醒锁的代码:
package com.lanxin.testreceiver; import android.content.Context; import android.os.PowerManager; import android.util.Log; /** * Created by Alan on 2016/6/5 0005. */ public class LightedGreenRoom { private static final String TAG = "LightedGreenRoom"; private int count; private int clientCount = 0; private Context mContext; private static LightedGreenRoom _self = null; PowerManager.WakeLock wl = null; /** * 初始化,传递一个上下文 * @param ctx */ public LightedGreenRoom(Context ctx){ mContext = ctx; wl = this.createWakeLock(ctx); } public static void setup(Context ctx){ if(_self == null){ Log.d(LightedGreenRoom.TAG, "正在创建一个房间,并且开灯."); _self = new LightedGreenRoom(ctx); _self.turnOnLights(); } } public static boolean is_setup(){ return _self == null ? false : true; } public static int s_enter(){ assertSetup(); return _self.enter(); } public static int s_leave(){ assertSetup(); return _self.leave(); } public static int s_registerClient(){ assertSetup(); return _self.registerClient(); } public static int s_unregisterClient(){ assertSetup(); return _self.unregisterClient(); } private PowerManager.WakeLock createWakeLock(Context ctx){ PowerManager pm = (PowerManager) ctx.getSystemService(ctx.POWER_SERVICE); PowerManager.WakeLock pw = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,TAG); return pw; } private void turnOnLights(){ Log.d(TAG, "正在开灯... 计数:" + count); wl.acquire(); } private void turnOffLights(){ if(wl.isHeld()){ Log.d(TAG, "正在关灯... 计数:" + count); wl.release(); } } private static void assertSetup(){ if (LightedGreenRoom._self == null){ Log.w(LightedGreenRoom.TAG, "assertSetup:你必须先执行setup的方法"); throw new RuntimeException("assertSetup:你必须先执行setup的方法"); } } private int registerClient(){ this.clientCount++; Utils.logThreadSignature(TAG); Log.d(TAG,"registerClient client:count:" + clientCount); return clientCount; } private int unregisterClient(){ Utils.logThreadSignature(TAG); Log.d(TAG, "unregisterClient client:count:" + clientCount); if(clientCount == 0){ Log.w(TAG,"没有client需要卸载"); return 0; } clientCount--; if(clientCount == 0){ emptyTheRoom(); return 0; } return clientCount; } synchronized private int enter(){ count++; Log.d(TAG,"enter: count:" + count); return count; } synchronized private int leave(){ Log.d(TAG,"leave:count at the call:" + count); if(count == 0){ Log.w(TAG,"没有人进入.count:"+count); return count; } count--; if(count == 0){ turnOffLights(); } return count; } synchronized private int getCount(){ return count; } synchronized private void emptyTheRoom(){ count = 0; turnOffLights(); Log.i(TAG,"emptyTheRoom"); } }
以下是执行后Log的日志:
06-05 10:51:59.176 16111-16111/com.lanxin.testreceiver I/TestReceiver: before7
06-05 10:51:59.186 16111-16111/com.lanxin.testreceiver I/TestReceiver: after:7
06-05 10:51:59.226 16111-16111/com.lanxin.testreceiver D/TestReceiver1: main:(id)1:(priority)5:(group)main
06-05 10:51:59.226 16111-16111/com.lanxin.testreceiver I/TestReceiver1: 测试一条消息:6
06-05 10:51:59.276 16111-16111/com.lanxin.testreceiver D/TestReceiver1: main:(id)1:(priority)5:(group)main
06-05 10:51:59.626 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onCreate
06-05 10:51:59.626 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: main:(id)1:(priority)5:(group)main
06-05 10:51:59.626 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: registerClient client:count:1
06-05 10:51:59.636 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onStartCommand
06-05 10:51:59.636 16111-20042/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)120:(priority)5:(group)main
06-05 10:51:59.636 16111-20042/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:0
06-05 10:51:59.636 16111-20042/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)120:(priority)5:(group)main
06-05 10:51:59.636 16111-20042/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:1
06-05 10:51:59.646 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: enter: count:1
06-05 10:51:59.646 16111-20042/com.lanxin.testreceiver D/LightedGreenRoom: leave:count at the call:1
06-05 10:51:59.646 16111-16111/com.lanxin.testreceiver D/TestReceiver2: main:(id)1:(priority)5:(group)main
06-05 10:51:59.646 16111-16111/com.lanxin.testreceiver I/TestReceiver2: 测试一条消息:6
06-05 10:51:59.696 16111-16111/com.lanxin.testreceiver D/TestReceiver2: main:(id)1:(priority)5:(group)main
06-05 10:51:59.696 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: main:(id)1:(priority)5:(group)main
06-05 10:51:59.706 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: unregisterClient client:count:1
06-05 10:51:59.706 16111-16111/com.lanxin.testreceiver I/LightedGreenRoom: emptyTheRoom
06-05 10:51:59.706 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onDestroy
06-05 10:51:59.726 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onCreate
06-05 10:51:59.726 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: main:(id)1:(priority)5:(group)main
06-05 10:51:59.726 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: registerClient client:count:1
06-05 10:51:59.746 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onStartCommand
06-05 10:51:59.746 16111-20043/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)121:(priority)5:(group)main
06-05 10:51:59.746 16111-20043/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:0
06-05 10:51:59.756 16111-20043/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)121:(priority)5:(group)main
06-05 10:51:59.756 16111-20043/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:1
06-05 10:51:59.756 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: enter: count:1
06-05 10:51:59.756 16111-20043/com.lanxin.testreceiver D/LightedGreenRoom: leave:count at the call:1
06-05 10:51:59.776 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: main:(id)1:(priority)5:(group)main
06-05 10:51:59.796 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: unregisterClient client:count:1
06-05 10:51:59.796 16111-16111/com.lanxin.testreceiver I/LightedGreenRoom: emptyTheRoom
06-05 10:51:59.796 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onDestroy
06-05 11:03:54.126 16111-16117/com.lanxin.testreceiver D/dalvikvm: GC_FOR_ALLOC freed 460K, 14% free 3573K/4108K, paused 221ms, total 257ms
06-05 11:05:34.806 16111-17932/com.lanxin.testreceiver I/TestReceiver: Run Timer
06-05 11:05:34.806 16111-17932/com.lanxin.testreceiver I/TestReceiver: before8
06-05 11:05:34.836 16111-17932/com.lanxin.testreceiver I/TestReceiver: after:8
06-05 11:05:34.906 16111-16111/com.lanxin.testreceiver D/TestReceiver1: main:(id)1:(priority)5:(group)main
06-05 11:05:34.906 16111-16111/com.lanxin.testreceiver I/TestReceiver1: 测试一条消息:7
06-05 11:05:34.986 16111-16111/com.lanxin.testreceiver D/TestReceiver1: main:(id)1:(priority)5:(group)main
06-05 11:05:35.086 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onCreate
06-05 11:05:35.086 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: main:(id)1:(priority)5:(group)main
06-05 11:05:35.086 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: registerClient client:count:1
06-05 11:05:35.096 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onStartCommand
06-05 11:05:35.096 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: enter: count:1
06-05 11:05:35.136 16111-16111/com.lanxin.testreceiver D/TestReceiver2: main:(id)1:(priority)5:(group)main
06-05 11:05:35.136 16111-16111/com.lanxin.testreceiver I/TestReceiver2: 测试一条消息:7
06-05 11:05:35.176 16111-16111/com.lanxin.testreceiver D/TestReceiver2: main:(id)1:(priority)5:(group)main
06-05 11:05:35.206 16111-28487/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)122:(priority)5:(group)main
06-05 11:05:35.206 16111-28487/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:0
06-05 11:05:35.206 16111-28487/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)122:(priority)5:(group)main
06-05 11:05:35.206 16111-28487/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:1
06-05 11:05:35.206 16111-28487/com.lanxin.testreceiver D/LightedGreenRoom: leave:count at the call:1
06-05 11:05:35.236 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onStartCommand
06-05 11:05:35.236 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: enter: count:1
06-05 11:05:35.236 16111-28487/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)122:(priority)5:(group)main
06-05 11:05:35.266 16111-28487/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:0
06-05 11:05:35.266 16111-28487/com.lanxin.testreceiver D/TestIntentService: IntentService[TestIntentService]:(id)122:(priority)5:(group)main
06-05 11:05:35.266 16111-28487/com.lanxin.testreceiver I/TestIntentService: onHandleIntent:1
06-05 11:05:35.266 16111-28487/com.lanxin.testreceiver D/LightedGreenRoom: leave:count at the call:1
06-05 11:05:35.276 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: main:(id)1:(priority)5:(group)main
06-05 11:05:35.276 16111-16111/com.lanxin.testreceiver D/LightedGreenRoom: unregisterClient client:count:1
06-05 11:05:35.276 16111-16111/com.lanxin.testreceiver I/LightedGreenRoom: emptyTheRoom
06-05 11:05:35.286 16111-16111/com.lanxin.testreceiver I/TestIntentService: Service onDestroy
1 Comment
源码下载地址:链接:http://pan.baidu.com/s/1qYH13mG 密码:0fxm