1、Android中广播分为静态注册和动态注册 2、下面是一个简单静态注册的例子 创建一个继承 BroadcastReceiver 的子类 public class DeviceBootReceiver extends BroadcastReceiver { private static final String TAG
1、Android中广播分为静态注册和动态注册
2、下面是一个简单静态注册的例子
- 创建一个继承
BroadcastReceiver
的子类
public class DeviceBootReceiver extends BroadcastReceiver { private static final String TAG = DeviceBootReceiver.class.getName(); @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "开机了:" + intent.getAction()); } }
该类的功能用于接收手机开机的广播。
- 在
AndroidManifest.xml
中注册该组件
<receiver android:name=".DeviceBootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
action
标签中的值用于匹配广播的类型,这里是开机广播。
这样当手机开机时,便会收到来自系统的消息。
同样,我们也可以监听应用安装,应用卸装,USB插拔等系统广播。只是action
的值稍有不同。
<receiver android:name=".OtherStateReceiver"> <intent-filter> <!--电量过低--> <action android:name="android.intent.action.BATTERY_LOW" /> <!--USB连接--> <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> <!--USB断开--> <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /> <!--软件包安装--> <action android:name="android.intent.action.PACKAGE_ADDED" /> <!--软件包卸装--> <action android:name="android.intent.action.PACKAGE_REMOVED" /> </intent-filter> </receiver>
上面除了开机广播,其他广播这样注册能成功的前提是 API Level < 26(Android8.0以下)
。Google为了防止接收者程序常驻内存消耗资源,禁止了一些Manifest declared receiver
。我们想要继续监听,就要使用动态注册的方式。
3、下面是一个动态注册的例子:
public class SystemBroadcastReceiverActivity extends AppCompatActivity { private SystemBroadcastReceiver receiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_system_broadcast_receiver); IntentFilter filter = new IntentFilter(); //USB连接 filter.addAction(Intent.ACTION_POWER_CONNECTED); //USB断开 filter.addAction(Intent.ACTION_POWER_DISCONNECTED); receiver = new SystemBroadcastReceiver(); registerReceiver(receiver, filter); } private class SystemBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { System.out.println(intent.getAction()); } } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); } }
然后在AndroidManifest.xml
注册该Activity
即可。
4、自定义广播
前面说的都是接收系统广播,我们也可以发送自定义的广播,然后在同一个应用或不同应用中接收。
下面是一个静态注册的自定义广播:
- 建立一个
Activity
,提供一个Button
,点击后发送广播
public class CustomSenderActivity extends AppCompatActivity { public static final String BROADCAST_ACTION = "com.hncj.android.manifest.CustomSenderActivity"; public static final String BROADCAST_CONTENT = "broadcast_content"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_sender); } @SuppressLint("WrongConstant") public void sendBroadcast(View view) { Intent intent = new Intent(); intent.setAction(BROADCAST_ACTION); intent.putExtra(BROADCAST_CONTENT, "我发送了广播,你看收没收到?"); //解决API26及以上的Android静态注册的Receiver收不到广播 //第一种解决方案:设置标志 Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND intent.addFlags(0x01000000); //不论是一个应用自己发自己收还是一个应用发一个应用收,都可以实现效果 //第二种解决方案:指定包名(这里是一个应用,自己发,自己收,都在一个包下) //intent.setPackage(getPackageName()); //如果是给另一个应用发广播 则写成intent.setPackage("另一个项目应用接收者的包名"); //第三种解决方案: 明确指定包名,类名 //intent.setComponent(new ComponentName(this, CustomReceiver.class)); //如果是给另一个应用发广播 则写成 intent.setComponent(new ComponentName("另一个应用接收者包名", "另一个应用接收者类名")); //发送广播 sendBroadcast(intent); } }
- 布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" android:padding="40dp"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="sendBroadcast" android:background="#008080" android:textSize="30dp" android:text="发送广播"></Button> </LinearLayout>
- 接收者
public class CustomReceiver extends BroadcastReceiver { private static final String TAG = CustomReceiver.class.getName(); @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG, "我收到了来自" + action + "的广播"); } }
AndroidManifest.xml
文件
<activity android:name=".manifest.CustomSenderActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".manifest.CustomReceiver"> <intent-filter> <action android:name="com.hncj.android.manifest.CustomSenderActivity" /> </intent-filter> </receiver>
这里的一个接收者是在当前项目,还有一个接收者在另一个项目,代码基本是一致的。
相关的API:
发送有序广播:
<!--广播中携带数据--> Bundle bundle = new Bundle(); bundle.putString("username", "nacy"); sendOrderedBroadcast(intent, null, null, null, Activity.RESULT_OK, null, bundle);
为接收者设置优先级:(-1000-1000),即定义哪个接收者先收到,优先级越大,越早收到广播
<receiver android:name=".manifest.CustomReceiver"> <!--priority可以设置优先级--> <intent-filter android:priority="9"> <action android:name="com.hncj.android.manifest.CustomSenderActivity" /> </intent-filter> </receiver>
终止广播:
<!--广播不再向下传递--> abortBroadcast();
取出广播中的数据:
//取出Bundle对象,类似于一个map Bundle bundle = getResultExtras(true);
设置接收者权限:(谁能收到)
- 先在发送方
AndroidManifest.xml
中声明一个权限(包名+权限名)
<permission android:name="com.hncj.android.RECEIVER_PERMISSION" />
- 发送时定义接收者需要拥有的权限:
sendOrderedBroadcast(intent, Manifest.permission.RECEIVER_PERMISSION, null, null, Activity.RESULT_OK, null, bundle);
- 接收者需要在
AndroidManifest.xml
使用权限:
<uses-permission android:name="com.hncj.android.RECEIVER_PERMISSION" />
设置发送者权限:(谁能给我发)
- 先在接收方
AndroidManifest.xml
声明一个权限
<permission android:name="com.hncj.android.SENDER_PERMISSION" />
- 在Receiver标签中说明发送者要拥有的权限:
<receiver android:name=".manifest.CustomReceiver" android:permission="com.hncj.android.SENDER_PERMISSION"> <intent-filter android:priority="9"> <action android:name="com.hncj.android.manifest.CustomSenderActivity" /> </intent-filter> </receiver>
- 在发送方
AndroidManifest.xml
中使用权限
<uses-permission android:name="com.hncj.android.SENDER_PERMISSION" />
还有动态注册的自定义广播,与上面提到的动态注册的例子差不多,只是自定义action的内容。