一、广播接收器
- 广播类型
- 有序广播
- 特点:
- 可以截断传播的广播
- 数据可以被修改
- 特点:
- 无序广播
- 特点:
- 无法截断传播的广播
- 数据不可以被修改
- 特点:
- 有序广播
- 使用广播接收器注意事项:
在我们使用广播接收器的时候,不要在 onReceive() 方法中去执行太多耗时的操作或者逻辑,因为在广播接收器中是不允许开启线程的,当 onReceive() 方法长时间运行后程序就会报错。因此,广播接收器更多的作用是打开其他组件。 - 广播接收器数据传输方法:
- 传数据方法
- 标准广播:
- 通过 Intent 类的 putExtra() 方法
- 有序广播
- 通过 Intent 类的 putExtra() 方法
- 通过 sendOrderedBroadcast() 的构造方法
- 标准广播:
- 获取数据方法
- 标准广播:
- 通过 getXxxExtra() 方法
- 有序广播:
- 通过 getXxxExtra() 方法
- 通过 getResultData() 方法
- 标准广播:
- 传数据方法
二、接收系统广播方式:
-
动态注册
- 动态注册实现步骤:
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
package com.example.chenzhaoyu.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.widget.Toast; public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 获取 ConnectivityManager 对象 ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); // 获取 NetworkInfo 对象 NetworkInfo info = manager.getActiveNetworkInfo(); // 对 NetworkInfo 对象的状态进行判断 if (info != null && info.isAvailable()) { Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show(); } } }
- 在 onCreate() 方法中调用 registerReceiver(BroadcastReceiver receiver, IntentFilter filter) 方法,注册广播接收者
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * registerReceiver中有两个参数 * 参数一:一个BroadcastReceiver对象 * 参数二:IntentFilter对象 * */ IntentFilter filter = new IntentFilter(); // 添加action时,需要在AndroidManifest.xml中添加对应的权限 filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); ncr = new NetworkChangeReceiver(); registerReceiver(ncr,filter); }
- 在 onDestroy() 方法中调用 unregisterReceiver(),取消注册广播接收者
@Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(ncr); }
- 添加相应的权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
- 弊端:
程序必须在启动后才能接收到广播 - 动态注册广播接收者注意事项:
- 动态注册广播接收者时必须在 onDestroy() 方法中取消注册,否则会报错
- 动态注册广播适用范围:
操作特别频繁的广播事件,必须通过动态注册的方式进行注册。比如电池电量的变换、锁屏和解锁的操作等
- 动态注册实现步骤:
-
静态注册
- 静态注册实现步骤
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
package com.example.chenzhaoyu.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class BootCompleteReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show(); } }
- 在 AndroidManifest.xml 中配置广播接收者
<receiver android:name=".BootCompleteReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
- 添加相应的权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
- 优点:程序可以在不启动的时候就能接收到广播
- 静态注册实现步骤
三、自定义广播(使用自定义广播,程序必须是启动后才能收到广播信息)
- 自定义广播类型:
- 标准广播
- 有序广播
- 如何发送自定义广播?
发送自定义广播我们需要两个程序,一个是发送广播消息的程序 ,一个是接收广播消息的程序 - 发送标准广播
- 发送端:
- 创建一个xml布局
<?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:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/send_broadcast" android:textSize="18sp" android:textColor="#000" android:gravity="center" android:onClick="click"/> </LinearLayout>
- 为按钮添加点击事件
public void click(View view) { }
- 调用 sendBroadcast() 方法发送一个广播
public void click(View view) { Intent intent = new Intent("com.example.MY_BROADCAST"); sendBroadcast(intent); }
- 创建一个xml布局
- 接收端
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
package com.example.chenzhaoyu.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"My BroadCast",Toast.LENGTH_SHORT).show(); } }
- 在AndroidManifest.xml中配置广播接收者
<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="100"> <action android:name="com.example.MY_BROADCAST" /> </intent-filter> </receiver>
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
- 发送自定标准广播注意事项:
- 发送端 Intent 的 action属性值必须与接收端 AndroidManifest.xml 文件中<intent-filter>配置的 action 值相同
- 发送端:
- 发送有序广播
- 发送端
- 创建一个xml布局
<?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:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/send_broadcast" android:textSize="18sp" android:textColor="#000" android:gravity="center" android:onClick="click"/> </LinearLayout>
- 为按钮添加点击事件
public void click(View view) { }
- 调用 sendOrderedBroadcast() 方法发送一个广播
public void click(View view) { Intent intent = new Intent("com.example.MY_BROADCAST"); sendOrderedBroadcast(intent,null); }
- 创建一个xml布局
- 接收端
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
package com.example.chenzhaoyu.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MyOrderBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"Order BroadcastReceiver",Toast.LENGTH_SHORT).show(); // 在此处截断后,比自己优先级小的广播都不会再接收到广播消息 abortBroadcast(); } }
- 在AndroidManifest.xml中配置广播接收者
<receiver android:name=".MyOrderBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.example.MY_BROADCAST" /> </intent-filter> </receiver>
- 创建一个类继承 BroadcastReceiver 类,并重写 onReceive()方法
- 发送自定有序广播注意事项:
- 发送端 Intent 的 action属性值必须与接收端 AndroidManifest.xml 文件中<intent-filter>配置的 action 值相同
- 发送端 Intent 的 action属性值必须与接收端 AndroidManifest.xml 文件中<intent-filter>配置的 action 值相同
- 发送端
四、本地广播
-
本地广播实现步骤
- 创建一个类继承 BroadcastReceiver 类
package com.example.chenzhaoyu.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class LocalBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"Local Broadcast",Toast.LENGTH_SHORT).show(); } }
- 在 onCreate() 方法中注册广播接收者
public class MainActivity extends Activity { private LocalBroadcastManager manager; private LocalBroadcastReceiver lbr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("com.example.LOCAL_BROADCAST"); lbr = new LocalBroadcastReceiver(); manager = LocalBroadcastManager.getInstance(this); // 调用LocalBroadcastManager的注册方法 manager.registerReceiver(lbr,intentFilter); } }
- 在 onDestroy() 方法中取消注册
@Override protected void onDestroy() { super.onDestroy(); // 取消注册,也必须调用LocalBroadcastManager中的unregisterReceiver()方法 manager.unregisterReceiver(lbr); }
- 创建一个类继承 BroadcastReceiver 类
-
使用本地广播优点
- 明确知道正在发送的广播不会离开我们的程序,不用担心机密数据会被泄露
- 其他程序无法发送广播到我们程序内部,不用担心安全漏洞隐患
- 发送本地广播比发送系统广播更高效