1.发送标准广播
步骤一:新建MyBroadcastActivity,布局如下:
现在我们要实现的是:输入要发送的广播内容,点击发送按钮后,该条广播被接收,并在日志处打印出来。
MyBroadcastActivity的代码如下:
//采用静态注册的方式
public class MyBroadcastActivity extends AppCompatActivity {
private EditText message ;
private Button send_message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_broadcast_receiver);
message = findViewById(R.id.message);
send_message = findViewById(R.id.send_message);
send_message.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = message.getText().toString();//获取输入的广播内容
Intent intent = new Intent(); //靠intent进行数据传递
//添加广播的action,自定义为com.java.androidtest.SEND_MESSAGE,表示发送信息的广播
intent.setAction("com.java.androidtest.SEND_MESSAGE");
intent.putExtra("content",content);//将输入内容也传递过去
//Android8.0以后,静态注册的BroadcastReceiver是无法接收隐式广播的,而默认情况下我们发出的自定义广播恰恰都是隐式广播。
//因此这里一定要调用setPackage()方法,指定这条广播是发送给那个应用程序的,从而让它变成一条显示广播。否则,静态注册的BroadcastReceiver将无法接收这条广播。
intent.setPackage(getPackageName());
sendBroadcast(intent);
}
});
}
}
步骤二:创建MyBroadcastReceiver,用于接收广播。代码如下:
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG,"action ==>"+action);
String content = intent.getStringExtra("content");
Log.d(TAG,"content is = >"+content);//将广播内容在日志中打印出来
}
}
步骤三:静态注册该广播。在AndroidManifest.xml文件application标签中,对MyBroadcastReceiver进行静态注册。如下:
<receiver android:name="com.kotlin.androidtest.MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.java.androidtest.SEND_MESSAGE"/>
</intent-filter>
</receiver>
现在,发送一条广播,看看运行结果吧。
点击发送按钮后,查看日志的打印情况:
com.java.androidtest.SEND_MESSAGE,也成功将输入的信息通过广播的方式传输并接收。
.发送有序广播
和标准广播不同,有序广播是一种同步执行的广播,并且可以被截断。
新建LowBroadcastReceiver,代码如下:
public class LowBroadcastReceiver extends BroadcastReceiver {
private static final String TAG ="LowBroadcastReceiver" ;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG,"action ==>"+action);
String content = intent.getStringExtra("content");
Log.d(TAG,"content is = >"+content);
}
}
和MyBroadcastReceiver内容一致,现在我们对LowBroadcastReceiver进行静态注册。
代码如下:(这里将MyBroadcastReceiver也展示了出来。)
<receiver android:name=".LowBroadcastReceiver">
<intent-filter>
<action android:name="com.java.androidtest.SEND_MESSAGE"/>
</intent-filter>
</receiver>
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.java.androidtest.SEND_MESSAGE"/>
</intent-filter>
</receiver>
到目前为止,程序发出的都是标准广播。现在需要发送有序广播,需要两步:
第一步:修改MyBroadcastActivity中发送广播的源代码:
将sendBroadcast(intent,null) 改为:sendOrderedBroadcast(intent,null);
该完后的源代码如下所示:
//采用静态注册的方式
public class MyBroadcastActivity extends AppCompatActivity {
private EditText message ;
private Button send_message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_broadcast_receiver);
message = findViewById(R.id.message);
send_message = findViewById(R.id.send_message);
send_message.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = message.getText().toString();//获取输入的广播内容
Intent intent = new Intent(); //靠intent进行数据传递
//添加广播的action,自定义为com.kotlin.androidtest.SEND_MESSAGE,表示发送信息的广播
intent.setAction("com.java.androidtest.SEND_MESSAGE");
intent.putExtra("content",content);//将输入内容也传递过去
//Android8.0以后,静态注册的BroadcastReceiver是无法接收隐式广播的,而默认情况下我们发出的自定义广播恰恰都是隐式广播。
//因此这里一定要调用setPackage()方法,指定这条广播是发送给那个应用程序的,从而让它变成一条显示广播。否则,静态注册的BroadcastReceiver将无法接收这条广播。
intent.setPackage(getPackageName());
sendOrderedBroadcast(intent,null); //发送有序广播
}
});
}
}
第二步:有序广播是有顺序的,并且前面的BroadcastReceiver还可以将广播截断。现在我们给广播接收者设定优先级,优先级高的先接收到广播。
修改静态注册中的代码,增加priority优先级的设定,修改后的代码如下:
<receiver android:name=".LowBroadcastReceiver">
<intent-filter android:priority="10"> <!--优先级设定为10-->
<action android:name="com.java.androidtest.SEND_MESSAGE"/>
</intent-filter>
</receiver>
<receiver android:name=".MyBroadcastReceiver">
<intent-filter android:priority="100"> <!--优先级设定为100-->
<action android:name="com.java.androidtest.SEND_MESSAGE"/>
</intent-filter>
</receiver>
priority的取值范围为:-1000~1000
可以看到,现在MyBroadcastReceiver的优先级高于LowBroadcastReceiver的优先级,所以广播会先发送给前者,再发送给后者。
运行后,如下所示:
现在,转换二者的优先级,使MyBroadcastReceiver的优先级低于LowBroadcastReceiver的优先级。运行后,如下所示:
已经成功获取到了广播的优先级,那么终止广播需要怎么做呢?
只需要在优先级高的BroadcastReceiver中加上:abortBroadcast(),便能截断广播了。现在我们对优先级高的LowBroadcastReceiver进行修改,修改后的代码如下:
public class LowBroadcastReceiver extends BroadcastReceiver {
private static final String TAG ="LowBroadcastReceiver" ;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG,"action ==>"+action);
String content = intent.getStringExtra("content");
Log.d(TAG,"content is = >"+content);
abortBroadcast(); //截断广播
}
}
运行后,日志如下:
已经成功截断广播。
既然可以截断广播,那么可以修改广播内容再继续传递吗?
当然可以。
我们再捋一下前面逻辑:在MyBroadcastActivity中获取界面输入的内容,并通过intent来传递给下一个广播。优先级高(LowBroadcastReceiver)的优先接收到广播,优先级低(MyBroadcastReceiver)的后接收到广播。
知识点:
在发送广播时 使用 sendOrderedBroadcast的重载方法来修改广播内容。
sendOrderedBroadcast(Intent intent, receiverPermission,BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras);
对应参数的解释:
第一个参数,意图对象,用于封装数据和设置过滤。
第二个参数,权限
第三个参数是广播接收者,这个广播接收者是最终接收的广播接收者,用于检查数据是否有传达或者数据被修改
第四个参数是一个自定义的Hanlder,用于处理结果接收者,也就是上面那个接收者的回调。
第五个参数是初始码,这个会作为结果码,通常是Activity.RESULT_OK,也就是-1。
第六个参数是用于传递数据的,这个数据在各个Receiver里获取到,通过getResultData方法获取。
第七个参数也是用于封装数据的,不同的是,这个用于封装数据集合,通过getResultExtras方法获取
OK,现在开始实战。
第一步:修改MyBroadcastActivity中的代码。
send_message.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = message.getText().toString();//获取输入的广播内容
Intent intent = new Intent(); //靠intent进行数据传递
Bundle bundle = new Bundle();
//添加广播的action,自定义为com.kotlin.androidtest.SEND_MESSAGE,表示发送信息的广播
intent.setAction("com.java.androidtest.SEND_MESSAGE");
bundle.putCharSequence("content",content);//将输入内容也传递过去
//Android8.0以后,静态注册的BroadcastReceiver是无法接收隐式广播的,而默认情况下我们发出的自定义广播恰恰都是隐式广播。
//因此这里一定要调用setPackage()方法,指定这条广播是发送给那个应用程序的,从而让它变成一条显示广播。否则,静态注册的BroadcastReceiver将无法接收这条广播。
intent.setPackage(getPackageName());
sendOrderedBroadcast(intent,null,null,null, Activity.RESULT_OK,null,bundle);
}
});
可以看到,这里用bundle传递广播内容。
第二步:修改BroadcastReceiver中接收广播的内容。
public class LowBroadcastReceiver extends BroadcastReceiver {
private static final String TAG ="LowBroadcastReceiver" ;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG,"action ==>"+action);
//abortBroadcast();
Bundle resultExtras = getResultExtras(true);
String content = resultExtras.getCharSequence("content").toString();
Log.d(TAG,"content is = >"+content);
resultExtras.putCharSequence("content","我是一条被修改过的广播。");
setResultExtras(resultExtras);
}
}
这里我们将接收到的广播进行了修改,再往下传递。
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG,"action ==>"+action);
Bundle resultExtra = getResultExtras(true);
String content = resultExtra.getCharSequence("content").toString();
Log.d(TAG,"content is = >"+content);
}
}
此处就是修改了一下接收广播内容的方式。
运行后,日志如下:
可以看到,已经成功修改了广播内容。