赞
踩
广播是一个消息通知机制,Android提供了一套完整的API,允许应用程序自由地发送和接收广播。就是我们常说的Android 四大组件之一的广播接收器(Broadcast Receiver).
广播其实不单可以监听到APP内的广播,同时也可以监听到系统和其他应用发来的广播,如下示例就是通过动态注册的方式监听系统网络变化
接收器是需要继承BroadcastReceiver 并重写onReceive()方法
package com.example.boardcasttest; import androidx.appcompat.app.AppCompatActivity; 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.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.util.logging.Logger; public class MainActivity extends AppCompatActivity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(v -> { Intent intent = new Intent("com.example.boardcasttest.MY_BROADCAST"); sendBroadcast(intent); }); intentFilter = new IntentFilter(); //想要监听什么广播,在每个地方添加相应的action intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkChangeReceiver = new NetworkChangeReceiver(); // 注册广播 registerReceiver(networkChangeReceiver, intentFilter); } @Override protected void onDestroy() { super.onDestroy(); // 注销广播 unregisterReceiver(networkChangeReceiver); } /** * 网络变化广播接收器 * * @author huanglin * @since 2021/7/18 */ class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); // 获取网络信息 NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 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(); } } } }
访问系统的网络状态是需要声明权限的,在AndroidManifest.xml加入相应权限即可
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.boardcasttest">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
</manifest>
静态广播可以在程序未启动时就能接收到广播,如下所示,我们在AndroidMenifest.xml定义相应拦截信息并自定义一个对应的广播接收器
到目前为止,我们在广播接收器中的onReceive()方法都是简单使用Toast,真正使用时则可以在里面添加自己的业务逻辑。但是,**不要在onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开线程的,当onReceive()方法运行了较长时间而没有结束时,程序就会报错。
/**
* 开机启动广播接收器
*
* @author huanglin
* @since 2021/7/18
*/
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();
}
}
AndroidManifest定义相应权限及拦截filter
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.boardcasttest"> <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/Theme.BoardcastTest"> <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>
广播又称为无序(标准)广播和无序广播,他们的区别前面已经介绍,他们的启动方法如下所示:
标准广播通过sendBroadcast()
来发送广播,而有序广播则是通过sendOrderedBroadcast()
来发送广播,并且有序广播需要指定优先级并区分接收器收到广播的优先级
创建MyBroadcastReceiver去接收广播
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in MyBoardcastReceiver",Toast.LENGTH_SHORT).show();
// 中止广播
abortBroadcast();
}
}
并在AndroidManifest.xml增加对其的MY_BROADCAST广播的接收,并设置优先级为100,保证一定比AnotherBroadcastReceiver先收到广播
<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="100"> <action android:name="com.example.boardcasttest.MY_BROADCAST" /> </intent-filter> </receiver> ```java 创建另一个BroadcastTest2 项目,新建一个AnotherBroadcastReceiver 去接收广播 ```java /** * 另一个广播接收器 * * @author huanglin * @since 2021/7/18 */ public class AnotherBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "received in Another BroadcastReceiver", Toast.LENGTH_SHORT).show(); } }
并AndroidManifest.xml项目中进行增加对于MY_BROADCAST的广播拦截
<receiver
android:name=".AnotherBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
需要注意的是,上面发送和接收的广播全部属于系统全局广播,**即发出的广播可以被其他任何应用程序接收到**,并且我们也可以接收到来自其他程序的广播。这样很容易引起安全性的问题,比如我们改送一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他的程序不停地向我们的广播接收器发送各种垃圾广播。
为了能够简单地解决广播的安全性问题,Android引入了一套本地广播机制。具体请参考下一节学习笔记
《第一行代码Android(第2版)》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。