Android四大组件——BroadcastReceiver——自定义广播
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>
现在,发送一条广播,看看运行结果吧。
点击发送按钮后,查看日志的打印情况:
可以看到,该条广播的action正是我们自定义的com.java.androidtest.SEND_MESSAGE,也成功将输入的信息通过广播的方式传输并接收。
2.发送有序广播
和标准广播不同,有序广播是一种同步执行的广播,并且可以被截断。
新建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); } }
此处就是修改了一下接收广播内容的方式。
运行后,日志如下:
可以看到,已经成功修改了广播内容。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程