BroadcastReceiver
来源:互联网 发布:get it beauty self 编辑:程序博客网 时间:2024/06/03 15:00
创建BroadcastReceiver
package com.hang.androidtestdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.util.Log;public class MyReceiver extends BroadcastReceiver { public static final String TAG = MyReceiver.class.getSimpleName(); public static final String ACTION = MyReceiver.class.getName(); public MyReceiver() { } @Override public void onReceive(Context context, Intent intent) { // This method is called when this BroadcastReceiver receives an Intent broadcast. Log.d(TAG, "name: " + intent.getStringExtra("name")); System.out.println(); }}
- extends BroadcastReceiver interface
- implement onReceive()
注册BroadCastReciver
1在Manifest中进行注册
<receiver android:name="com.hang.androidtestdemo.MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.hang.androidtestdemo.MyReceiver" /> </intent-filter> </receiver>
2在java中注册
@Override protected void onResume() { super.onResume(); IntentFilter intentFilter = new IntentFilter(MyReceiver.ACTION); registerReceiver(myReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(myReceiver); }
为了减少手机系统的负载,一般会在onResume中进行注册,在onPause中进行取消
选择注册BroadcastReceiver方法
不论APP是否在前台运行,你都想监听系统事件,一定要在Manifest中进行注册;如果仅仅在APP某一个页面,对某些事件感兴趣的时候,在java代码中注册是一个不错的选择——节省系统开销。
注意:系统为了延长手机电池寿命,节省系统开销,在Manifest中注册的TIME_TICK广播监听无效。
发送广播的方法
- 通过Action间接启动
Intent intent = new Intent(MyReceiver.ACTION); intent.putExtra("name", "guchuanhang2"); sendBroadcast(intent);
通过Intent的action指向Broadcast注册的Action
- 通过BroadcastReceiver组件名称直接启动
这里面要注意以下,BroadcastReceiver组件必须要在Manifest中进行声明
Intent intent = new Intent(this,MyReceiver.class); intent.putExtra("name", "guchuanhang3"); sendBroadcast(intent);
有序广播
可以指定广播接收顺序的广播,高优先级先接受,同优先级不确定,没有指定priority的默认为0.高优先级的BroadcastReceiver接收到广播后,可以对接收到的参数进行修改,写一个优先级接收到的就是修改后的参数。
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
参数太复杂了,让我们通过一个例子,来一个感性的认识吧。
- 创建两个不同优先级的BroadcastReceiver
package com.hang.androidtestdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.util.Log;// MyReceiver.javapublic class MyReceiver extends BroadcastReceiver { public static final String ACTION = MyReceiver.class.getName(); public static final String TAG = MyReceiver.class.getSimpleName(); public MyReceiver() { } @Override public void onReceive(Context context, Intent intent) { //通过 getResultExtras(true)接收传递过来的参数,没有则会创建一个对象 Bundle results = getResultExtras(true); String hierarchy = results.getString("hierarchy"); results.putString("hierarchy", hierarchy + "->" + TAG); Log.d(TAG, TAG); }}
package com.hang.androidtestdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.util.Log;// MySecondReceiver .javapublic class MySecondReceiver extends BroadcastReceiver { private String TAG = MyReceiver.class.getSimpleName(); public MySecondReceiver() { } @Override public void onReceive(Context context, Intent intent) { Bundle results = getResultExtras(true); String hierarchy = results.getString("hierarchy"); results.putString("hierarchy", hierarchy + "->" + "MySecondReceiver"); Log.d(TAG, "MySecondReceiver"); }}
MySecondReceiver的优先级比MyReceiver的优先级要高
<receiver android:name="com.hang.androidtestdemo.MyReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="1"> <action android:name="com.hang.androidtestdemo.MyReceiver" /> </intent-filter> </receiver> <receiver android:name="com.hang.androidtestdemo.MySecondReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="2"> <action android:name="com.hang.androidtestdemo.MyReceiver" /> </intent-filter> </receiver>
MainActivity主代码:
package com.hang.androidtestdemo;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity { public static final String TAG = MainActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); IntentFilter filter = new IntentFilter(MyReceiver.ACTION); //default priority 0 //filter.setPriority(0); registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //通过这种方式,获取传递过来的参数,没有会创建一个对象 Bundle results = getResultExtras(true); String hierarchy = results.getString("hierarchy"); results.putString("hierarchy", hierarchy + "->" + TAG); Log.d(MyReceiver.TAG, "Anonymous class broadcast receiver"); } }, filter); Intent intent = new Intent(MyReceiver.ACTION); sendOrderedBroadcast(intent, null, new BroadcastReceiver() { //this will receiver last @Override public void onReceive(Context context, Intent intent) { Bundle results = getResultExtras(true); String hierarchy = results.getString("hierarchy"); System.out.println(hierarchy); Log.d(MyReceiver.TAG, "Final Receiver"); Log.d(MyReceiver.TAG, "hierarchy: "+hierarchy); } }, null, Activity.RESULT_OK, null, null); }}
本地广播
为了APP数据的安全性,尽可能的使用本地广播
package com.hang.androidtestdemo;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.support.v4.content.LocalBroadcastManager;import android.util.Log;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void onResume() { super.onResume(); // Generally in your onResume() LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter("my-custom-event")); // Send Intent intent = new Intent("my-custom-event"); intent.putExtra("foo", "bar"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String message = intent.getStringExtra("foo"); Log.d("LocalBroadcastManager", "foo : " + message); System.out.println(); } }; @Override protected void onPause() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); super.onPause(); }}
相对于全局广播,
在发送广播的方法修改为:
LocalBroadcastManager.getInstance(this).sendBroadcast
接收广播的方法修改为:
LocalBroadcastManager.getInstance(this).registerReceiver
反注册广播的方法修改为:
LocalBroadcastManager.getInstance(this).unregisterReceiver
通过java代码控制Manifest中声明的BroadcastReceiver
默认情况下,Manifest中声明的BroadcastReceiver会一直有效。
可是在APP Manifest声明一个监听系统广播的BroadcastReceiver &&在onReceive中打印日志,为什么在我的APP退出后,系统广播有变化没有打印日志呢?
是Manifest中声明的BroadcastReceiver的生命周期,仅限于APP运行?
对于这个问题,我认为是安卓系统广播,都采用的默认设置
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
也就是排除了停止的APP接收。
验证这个问题,可以做两个小Demo:
Demo1 在Manifest中声明BroadcastReceiver
Demo2发送广播(当然是Demo1中监听的action).
1.在Demo1&&Demo2都运行的时候,Demo1可以接收到
2.在Demo1关闭,Demo2发送默认广播,Demo1无法接收
2.在Demo1关闭,Demo2发送广播(设置
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES))
Demo1可以接收
转入正题,如何控制Manifest中声明的 BroadcastReceiver的作用域?
1.启动
ComponentName componentName = new ComponentName(this, MyReceiver.class); PackageManager packageManager = getPackageManager(); packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP);
2.关闭
ComponentName componentName = new ComponentName(this, MyReceiver.class); PackageManager packageManager = getPackageManager(); packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
APP使用广播的建议&&注意事项
- 尽可能使用本地广播——LocalBroadcastManager
- 即使在同一个APP内,Manifest中声明的BroadcastReceiver 不能 收到LocalBroadcastManager发送的广播
- 尽可能通过java代码注册广播,而不是通过Manifest进行声明
- 通过java代码控制Manifest中声明的广播的作用范围
翻译地址
http://codetheory.in/android-broadcast-receivers/
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadCastReceiver
- BroadcastReceiver
- broadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- BroadcastReceiver
- 【APIO2016】字符串匹配
- imx6设备树中断说明
- System、Runtime及字符串相关操作
- js将数字每3位之间用逗号分割
- LeetCode - 53. Maximum Subarray
- BroadcastReceiver
- 三消游戏(检查游戏是否死局)
- 新手策划面试常见踩雷区
- SAP--用BAPI-实现销售订单修改-Cond-Value
- iMX6 USB OTG功能开发与测试
- BlockChain 与 Ethereum 介绍
- 工程师写Code的聪明省力法
- 关于Linux内核的一些算法
- 频道与菜单栏关联-----fragment