A. 发送广播借助Intent
B. 接收广播借助广播接收器(Broadcast Receiver)
A. 标准广播: 完全异步执行,广播发出后,所有的广播接收器几乎会同时接收到该广播消息。效率高但无法被截断。
B. 有序广播: 同步执行,广播发出后,同一时刻仅有一个广播接收器接收到该广播消息,相应逻辑执行完毕后,广播才会继续传递。优先级高的广播接收器优先接收,可被截断。
广播接收器对感兴趣的的广播进行注册,方可在目标广播发出后接收。注册广播的方式有两种:动态注册(在代码中注册)静态注册(在AndroidManifest.xml中注册)
动态注册的广播接收器一定要取消注册。
静态注册可让程序未启动时便接收广播消息。
如何创建一个广播接收器?新建一个类继承BroadcastReceiver,并重写父类的onReceive()方法,逻辑可在该方法中处理。
AndroidMainfest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.thinkpad.broadcasttest">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
intent-filter>
receiver>
application>
manifest>
MainActivity.java(监听网络变化)
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private IntentFilter mIntentFilter;
private NetworkChangeReceiver mNetworkChangeReceiver; //广播接收器对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIntentFilter = new IntentFilter(); //创建一个IntentFilter实例
//当网络状态发生变化时,系统发出的正是值为此的广播
mIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
mNetworkChangeReceiver = new NetworkChangeReceiver();//创建一个广播接收器的实例
registerReceiver(mNetworkChangeReceiver,mIntentFilter);//注册广播,传入广播接收器实例和IntentFilter
}
@Override
protected void onDestroy() {
super.onDestroy();
//动态注册的广播接收器一定要取消注册。
unregisterReceiver(mNetworkChangeReceiver);
}
//内部类NetworkChangeReceiver继承自BroadcastReceiver,用于创建广播接收器
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//通过getSystemService()获得ConnectivityManager,这个类是一个系统服务类,专门用于管理网络连接的。
ConnectivityManager connectivityManager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
//通过getActiveNetworkInfo()可以得到NetworkInfo的实例。
//访问网络状态的权限需要在AndroidManifest.xml声明一下。
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
//通过NetworkInfo的isAvailable()判断当前是否有网络
if(networkInfo != null && networkInfo.isAvailable()){
Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show();
}
}
}
}
BootCompleteReceiver.java(监听开机启动)
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_SHORT).show();
}
}
书上使用的安卓版本过低,目前的高版本安卓会出现一定的bug
解决方法:BUG解决参考博客
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,"接收到了自定义的广播",Toast.LENGTH_SHORT).show();
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.thinkpad.broadcasttest2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
intent-filter>
receiver>
application>
manifest>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.thinkpad.broadcasttest2.MainActivity">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送广播消息"/>
android.support.constraint.ConstraintLayout>
import android.content.ComponentName;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
intent.setComponent(new ComponentName("com.example.thinkpad.broadcasttest2",
"com.example.thinkpad.broadcasttest2.MyBroadcastReceiver"));
//该方法将广播发送出去
sendBroadcast(intent);
}
});
}
}
在项目一中点击按钮发送广播,项目二接收并截断,使项目三接收不到广播。
仅展示项目二代码:
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,"BroadcastReceiver接收到了广播!",Toast.LENGTH_SHORT).show();
//调用abortBroadcast();方法将广播截断
abortBroadcast();
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.thinkpad.broadcastordertest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="com.example.broadcastordertest.MY_BROADCAST"/>
intent-filter>
receiver>
application>
manifest>
将sendBroadcast(intent);方法改成
sendOrderBroadcast(intent,null);//该方法带有两个参数,第一个为Intent,第二个为与权限有关的字符串。
A. 正在发送的广播不会离开本程序,安全。
B. 其他程序的广播送不到本程序内,安全。
C. 比系统全局广播更加高效。
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
//使用LocalBroadcastManager来对广播进行管理,该类提供了发送广播和注册广播接收器的方法。
private IntentFilter mIntentFilter;
private LocalBroadcastManager mLocalBroadcastManager;
private LocalReceiver mLocalReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);//获取实例
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.example.thinkpad.localbroadcast.LOCAL_BROADCAST");
mLocalBroadcastManager.sendBroadcast(intent);//发送本地广播
}
});
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("com.example.thinkpad.localbroadcast.LOCAL_BROADCAST");
mLocalReceiver = new LocalReceiver();
mLocalBroadcastManager.registerReceiver(mLocalReceiver,mIntentFilter);//注册本地广播监听器
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocalBroadcastManager.unregisterReceiver(mLocalReceiver);//动态注册的广播接收器一定要取消注册
}
//内部类 广播接收器
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"接收到了本地广播",Toast.LENGTH_SHORT).show();
}
}
}
整理学习自郭霖大佬的《第一行代码》
目前小白一名,持续学习Android中,如有错误请批评指正!