文章目录
五 广播 (Broadcasts)
学习过Java的观察者模式,对于这一块可能好理解一点
5.1 广播的应用(通信)
- 同一app内部的同一组件内的消息通信(单个或多个线程之间)
- 同一app内部的不同组件之间的消息通信(单个进程)
- 同一app具有多个进程的不同组件之间的消息通信
- 不同app之间的组件之间消息通信
- Android系统在特定情况下与App之间的消息通信
5.2 常用广播事件
- Intent.ACTION_AIRPLANE_MODE_CHANGED:关闭或打开飞行模式时的广播
- Intent.ACTION_BATTERY_CHANGED:充电状态,或者电池的电量发生变化
- Intent.ACTION_BATTERY_LOW:表示电池电量低
- Intent.ACTION_BATTERY_OKAY:表示电池电量充足,即从电池电量低变化到饱满时会发出广播
- Intent.ACTION_BOOT_COMPLETED:在系统启动完成后,这个动作被广播一次(只有一次)
- Intent.ACTION_CAMERA_BUTTON:按下照相时的拍照按键(硬件按键)时发出的广播
- Intent.ACTION_CLOSE_SYSTEM_DIALOGS:当屏幕超时进行锁屏时,当用户按下电源按钮,长按或短按(不管有没跳出话框),进行锁屏时,android系统都会广播此Action消息
- Intent.ACTION_HEADSET_PLUG:在耳机口上插入耳机时发出的广播
- ntent.ACTION_PACKAGE_ADDED:成功的安装APK之后
- Intent.ACTION_PACKAGE_INSTALL:触发一个下载并且完成安装时发出的广播,比如在电子市场里下载应用?
- Intent.ACTION_PACKAGE_REMOVED:成功的删除某个APK之后发出的广播
5.3 广播分类
Android中的广播主要可以分为两种类型:标准广播和有序广播。
- 标准广播:是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。这种广播的效率会比较高,
- **有序广播:**则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。当然我们可以设置广播的优先级,优先执行某广播
5.4 入门案例
需求:我们需要通过点击来打开或关闭系统的蓝牙
分析:我们要用广播就离不开广播接收器
-
首先,我们在初始化到时候,创建一个IntentFiltert监听器实例,完成对系统广播的监听
-
为监听器实例添加需要监听的广播事件
-
当系统发生变化,广播接收器会接受到广播事件,从而完成相应的逻辑编写
-
页面构建
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/open_ble"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="打开蓝牙"/>
<Button
android:id="@+id/close_ble"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭蓝牙"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="蓝牙设备的连接状态,可以使用两部手机进行试验,先对两部手机进行配对,然后再
进行手动连接,就会显示连接状态!"/>
</LinearLayout>
- 蓝牙广播
package com.shu;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* @author shu
* @date 2021/7/19
* @description 蓝牙广播接收器
*/
public class BluetoothMonitorReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action != null){
switch (action) {
case BluetoothAdapter.ACTION_STATE_CHANGED:
int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
switch (blueState) {
case BluetoothAdapter.STATE_TURNING_ON:
Toast.makeText(context,"蓝牙正在打开", Toast.LENGTH_SHORT).show();
break;
case BluetoothAdapter.STATE_ON:
Toast.makeText(context,"蓝牙已经打开",Toast.LENGTH_SHORT).show();
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Toast.makeText(context,"蓝牙正在关闭",Toast.LENGTH_SHORT).show();
break;
case BluetoothAdapter.STATE_OFF:
Toast.makeText(context,"蓝牙已经关闭",Toast.LENGTH_SHORT).show();
break;
}
break;
case BluetoothDevice.ACTION_ACL_CONNECTED:
Toast.makeText(context,"蓝牙设备已连接",Toast.LENGTH_SHORT).show();
break;
case BluetoothDevice.ACTION_ACL_DISCONNECTED:
Toast.makeText(context,"蓝牙设备已断开",Toast.LENGTH_SHORT).show();
break;
}
}
}
}
- 主界面
package com.shu;
import androidx.appcompat.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
/**
* 动态注册
*/
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private Button openBle = null;
private Button closeBle = null;
private BluetoothMonitorReceiver bleListenerReceiver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化广播
this.bleListenerReceiver = new BluetoothMonitorReceiver();
IntentFilter intentFilter = new IntentFilter();
// 监视蓝牙关闭和打开的状态
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
// 监视蓝牙设备与APP连接的状态
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
// 注册广播
registerReceiver(this.bleListenerReceiver, intentFilter);
// 初始化控件
this.closeBle = findViewById(R.id.close_ble);
this.openBle = findViewById(R.id.open_ble);
// 关闭蓝牙
this.closeBle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//隐式关闭蓝牙
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.disable();
}
});
// 打开蓝牙
this.openBle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 隐式打开蓝牙
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.enable();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(this.bleListenerReceiver);
}
}
- 权限开启
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- 真机调试
注意:动态注册的广播接收器一定都要取消注册才行,这里我们是在onDestroy()方法中通过调用unregisterReceiver()方法来实现的。
5.5 自定义广播
- 自定义广播就是继承广播,重写里面的方法,完成自己的逻辑代码编写
package com.shu;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* @author shu
* @date 2021/7/19
* @description 自定义广播
*/
public class MyMonitorReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"收到消息",Toast.LENGTH_LONG).show();
}
}
- 清单文件中注册
<receiver
android:name=".MyMonitorReceiver"
//是否启用
android:enabled="true"
//是否对外访问
android:exported="true">
<intent-filter>
<action android:name="com.shu.MyMonitorReceiver" />
</intent-filter>
</receiver>
- 主页面
package com.shu;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Button button = (Button) findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.shu.MyMonitorReceiver");
//标准广播
sendBroadcast(intent);
//发送有序广播
//有序广播可以设置广播的权重,来优先启动android:priority="100"
sendOrderedBroadcast(intent,null);
}
});
}
}