Android 四大组件 之 BroadcastReceiver(广播接收者)
BroadcastReceiver(广播接收者) 简介
- BroadcastReceiver(广播接收者) 属于 Android 四大组件中的第三个
- BroadcastReceiver 官方对应文档地址:http://androiddoc.qiniudn.com/reference/android/content/BroadcastReceiver.html
- 举个例子:学校读书的时候,学校通常都会有一个大喇叭,用来广播一些通知,比如开学要去搬书的时候,学校会广播: "每个班级找几个同学教务处拿书",发出这个广播后,所有同学都会在同一时刻收到这条广播通知, 于是班级里面会派人一般去搬书回来。大喇叭--> 发送广播 --> 所有学生都能收到广播 --> 学生去搬书(处理广播)
- BroadcastReceiver 就是应用程序间的全局大喇叭,通信的一个手段, 系统自己在很多时候都会发送广播,比如电量低或者充电已满、系统启动完、插入耳机等, 发生这些事件,系统都会发送广播,即系统广播,每个 APP 都会收到,如果想让应用在接收到这些广播的时候做一些操作,比如:系统开机后,偷偷后台跑服务啥的,这个时候只需要为应用注册一个用于监视开机的 BroadcastReceiver 即可。
- 同时自己也可以发送广播,比如:接到服务端推送信息,用户在别处登录,然后应该强制用户下线回到登陆界面,或者提示在别处登录等
广播类型
注册广播的两种方式
- 系统在某些时刻会发送相应的系统广播,自己的 APP 接收系统广播之前,需要注册广播接收器,注册的方法分为以下两种:动态与静态!
- 不建议在广播中进行耗时操作,广播更多的时候扮演的是一个打开其它组件的角色,比如启动 Service,Notification 提示, 启动 Activity等
操作举例
动态注册广播
- 环境:minSdkVersion 17、targetSdkVersion 28,现在演示动态注册广播,以监听手机网络状态为例进行说明,效果如下,当手机网络发送变化时,给出提示。
- 布局文件 activity_main.xml 内容如下,就是生成的 helloWorld 项目默认的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
- 自定义 广播接收者 MyBroadcastReceiver 继承 android.content.BroadcastReceiver
package com.lct.www.yuan.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;
/**
* 自定义 广播接收者
* 继承 android.content.BroadcastReceiver
*/
public class MyBroadcastReceiver extends BroadcastReceiver {
/**
* 接收广播消息后都会进入 onReceive 方法,然后要做的就是对相应的消息做出相应的处理
*
* @param context
* @param intent
*/
@Override
public void onReceive(Context context, Intent intent) {
/**
* android.net.ConnectivityManager 专门用于处理系统网络的管理器
*/
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
/**
* 获取活动网络信息,此时需要在 AndroidManifest.xml 添加获取网络状态的权限:
* <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
*/
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
/**判断是否有网络连接*/
if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {
/**
* TYPE_WIFI = 1:表示 WIFI
* TYPE_MOBILE = 0:表示手机流量
* -1:表示未知的
* 2:An MMS-specific Mobile data connection
* ...
* TYPE_BLUETOOTH = 7:表示蓝牙
*/
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
Toast.makeText(context, "无线网络已连接", Toast.LENGTH_SHORT).show();
} else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
Toast.makeText(context, "流量网络已连接", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show();
}
}
}
- 主活动 MainActivity.java 内容如下:
package com.lct.www.yuan;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import com.lct.www.yuan.broadcastReceiver.MyBroadcastReceiver;
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("Wmx logs::", "活动创建...");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 动态注册广播------用于接收系统网络变化状态广播信息
*/
IntentFilter itFilter = new IntentFilter();
itFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
myReceiver = new MyBroadcastReceiver();
this.registerReceiver(myReceiver, itFilter);
}
/**
* 当活动被销毁时
*/
@Override
protected void onDestroy() {
Log.i("Wmx logs::", "活动销毁...");
super.onDestroy();
/**注销 unregisterReceiver(),否则可能引起内存泄露。*/
unregisterReceiver(myReceiver);
}
}
- 全局配置文件 AndroidManifest.xml 内容如下,动态注册广播时可以不用在下面注册 BroadcastReceiver:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lct.www.yuan">
<!--添加获取网络状态的权限-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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>
</application>
</manifest>
静态注册广播
- 静态注册广播同样需要继承 android.content.BroadcastReceiver,但之后不是在 Java 代码进行注册,而是在全局配置文件 AndroidManifest.xml 中进行配置。
- 这里以接收开机广播为例进行说明,可以参考《Android 程序随开机自动运行》