Android 蓝牙相关广播介绍
Android 蓝牙相关广播介绍
一、前言
本文主要介绍Android 蓝牙相关的广播,并非硬件相关的蓝牙广播信号,而是蓝牙app中的广播接收器onReceive 的蓝牙相关广播。
最近刚好开发了一下蓝牙相关的功能,所以进行一些知识总结和介绍,本文应该是全网最面的接收Android广播介绍知识的文章。
Android 蓝牙广播是系统应用或者蓝牙功能应用必备知识,网上介绍的较少或者比较片面,所以Android蓝牙相关开发的可以了解和收藏。
二、相关广播
蓝牙相关广播都是在 BluetoothDevice.java 和 BluetoothAdapter.java 中进行了定义。
蓝牙相关广播主要包括:蓝牙开关,蓝牙连接,蓝牙状态改变,蓝牙配对等等等等。
//Android13 中的源码地址:
packages\modules\Bluetooth\framework\java\android\bluetooth\BluetoothDevice.java
packages\modules\Bluetooth\framework\java\android\bluetooth\BluetoothAdapter.java
1、蓝牙相关广播
(1)蓝牙开关
BluetoothAdapter.java 的代码
BluetoothAdapter.ACTION_STATE_CHANGED
/**
* Broadcast Action: The state of the local Bluetooth adapter has been
* changed.
* <p>For example, Bluetooth has been turned on or off.
* <p>Always contains the extra fields {@link #EXTRA_STATE} and {@link
* #EXTRA_PREVIOUS_STATE} containing the new and old states
* respectively.
*/
@RequiresLegacyBluetoothPermission
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String
ACTION_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
/**
* Used as an int extra field in {@link #ACTION_STATE_CHANGED}
* intents to request the current power state. Possible values are:
* {@link #STATE_OFF}, //10
* {@link #STATE_TURNING_ON}, //11
* {@link #STATE_ON}, //12
* {@link #STATE_TURNING_OFF}, //13
*/
public static final String EXTRA_STATE = "android.bluetooth.adapter.extra.STATE";
这里说明了,广播里面包含 EXTRA_STATE 数据,里面包含蓝牙的状态。
(2)蓝牙断开/连接
BluetoothDevice.java 的代码
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACL_DISCONNECTED
//①蓝牙连接Action
/**
* Broadcast Action: Indicates a low level (ACL) connection has been
* established with a remote device.
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link #EXTRA_TRANSPORT}.
* <p>ACL connections are managed automatically by the Android Bluetooth
* stack.
*/
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ACL_CONNECTED =
"android.bluetooth.device.action.ACL_CONNECTED";
//②蓝牙断开Action
/**
* Broadcast Action: Indicates a low level (ACL) disconnection from a
* remote device.
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link #EXTRA_TRANSPORT}.
* <p>ACL connections are managed automatically by the Android Bluetooth
* stack.
*/
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ACL_DISCONNECTED =
"android.bluetooth.device.action.ACL_DISCONNECTED";
//③蓝牙断开/连接 可以获取到的额外信息BluetoothDevice ,里面有很多数据,比如名称,MAC地址
/**
* Used as a Parcelable {@link BluetoothDevice} extra field in every intent
* broadcast by this class. It contains the {@link BluetoothDevice} that
* the intent applies to.
*/
public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
//④蓝牙断开/连接 可以获取到的额外信息,普通蓝牙还是低功耗LE蓝牙
/**
* Used as an int extra field in {@link #ACTION_ACL_CONNECTED} and
* {@link #ACTION_ACL_DISCONNECTED} intents to indicate which transport is connected.
* Possible values are: {@link #TRANSPORT_BREDR} and {@link #TRANSPORT_LE}.
*/
@SuppressLint("ActionValue")
public static final String EXTRA_TRANSPORT = "android.bluetooth.device.extra.TRANSPORT";
(3)蓝牙状态
BluetoothDevice.java 的代码
BluetoothDevice.ACTION_BOND_STATE_CHANGED
这里的状态并非蓝牙断开连接,主要是保存和忘记
/**
* Broadcast Action: Indicates a change in the bond state of a remote
* device. For example, if a device is bonded (paired).
* <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
* #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
*/
// Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
// contain a hidden extra field EXTRA_UNBOND_REASON with the result code.
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_BOND_STATE_CHANGED =
"android.bluetooth.device.action.BOND_STATE_CHANGED";
/**
* Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
* Contains the previous bond state of the remote device.
* <p>Possible values are:
* {@link #BOND_NONE}, //10
* {@link #BOND_BONDING}, //11
* {@link #BOND_BONDED}. //12
*/
public static final String EXTRA_PREVIOUS_BOND_STATE =
"android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
配对设备和忘记设备成功都是有绑定状态的改变,而断开设备和重新连接设备不一定有bond的改变。
上面也说明了使用 EXTRA_DEVICE 额外信息可以获取到 BluetoothDevice 对象,但是要注意如果是忘记设备有可能获取到的 BluetoothDevice 对象为null。
(4)蓝牙配对/取消配对
BluetoothDevice.ACTION_PAIRING_REQUEST
BluetoothDevice.ACTION_PAIRING_CANCEL
//①蓝牙配对
/**
* Broadcast Action: This intent is used to broadcast PAIRING REQUEST
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to
* receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PAIRING_REQUEST =
"android.bluetooth.device.action.PAIRING_REQUEST";
//② 取消配对
/** @hide */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@UnsupportedAppUsage
public static final String ACTION_PAIRING_CANCEL =
"android.bluetooth.device.action.PAIRING_CANCEL";
其实上面广播看起来好像不难,开发过蓝牙具体功能的估计是大部分用到,只是有些细节可能没注意而已。
从上面代码看,常用的广播除了开关状态在 BluetoothAdapter 里面定义,其他的广播都是在 BluetoothDevice 里面定义的。
(5)从源码看Android系统有哪些广播
其实除了常用广播,看看源码定义其他也有些有用的广播比如下面的:
BluetoothAdapter.java 相关广播:
//蓝牙开关,上面已经介绍过了
public static final String ACTION_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
//扫描状态改变广播
public static final String ACTION_SCAN_MODE_CHANGED = "android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
//是否可被其他设备发现广播
public static final String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
//蓝牙名称修改后的广播
public static final String ACTION_LOCAL_NAME_CHANGED = "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED";
//连接状态的改变?
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
//BLE 低功耗设备连接
public static final String ACTION_BLE_ACL_CONNECTED = "android.bluetooth.adapter.action.BLE_ACL_CONNECTED";
//BLE 低功耗设备断开
public static final String ACTION_BLE_ACL_DISCONNECTED = "android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED";
//被发现开始
public static final String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
//被发现结束
public static final String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
//蓝牙MAC地址修改
public static final String ACTION_BLUETOOTH_ADDRESS_CHANGED = "android.bluetooth.adapter.action.BLUETOOTH_ADDRESS_CHANGED";
//请求被发现广播
public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
//请求开启广播
public static final String ACTION_REQUEST_ENABLE = "android.bluetooth.adapter.action.REQUEST_ENABLE";
//请求关闭广播
public static final String ACTION_REQUEST_DISABLE = "android.bluetooth.adapter.action.REQUEST_DISABLE";
//BLE设备请求扫描广播
public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
...
上面的广播都是从 Android13 BluetoothAdapter 具体源码上整理下来的。这些广播好像很少用到过!
BluetoothDevice.java 相关广播:
//新蓝牙设备被发现后,这个广播在普通应用也比较常用
public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND";
//BluetoothDevice 对象或者 BluetoothClass 对象信息变化后
public static final String ACTION_CLASS_CHANGED ="android.bluetooth.device.action.CLASS_CHANGED";
//蓝牙设备连接,上面已经有介绍
public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
//蓝牙设备请求关闭,这个场景没怎么用过
public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
//蓝牙设备关闭,上面已经有介绍
public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED";
//扫描到的蓝牙设备(非自身)的名称修改
public static final String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
//扫描到的蓝牙设备(非自身)的别称修改,alias一般情况和name一致
public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.device.action.ALIAS_CHANGED";
//绑定状态改变,上面已经有介绍
public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED";
//蓝牙电量改变
public static final String ACTION_BATTERY_LEVEL_CHANGED = "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED";
2、广播接收代码示例
这里一段代码,接收上面大部分广播
package com.liwenzhi.broadcastdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DebugLog.debug("");
registerBroadcast(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
DebugLog.debug("");
unRegisterBroadcast(this);
}
public void registerBroadcast(Context context) {
DebugLog.debug("");
String a = Intent.ACTION_SCREEN_OFF;
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
intentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(mEthernetReceiver, intentFilter);
}
public void unRegisterBroadcast(Context context) {
context.unregisterReceiver(mEthernetReceiver);
}
private final BroadcastReceiver mEthernetReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
DebugLog.info("action = " + action);
if (action == null) {
DebugLog.error("action == null!");
return;
}
//常用的信息写在前面
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device != null) {
DebugLog.info("BluetoothDevice = " + device + ",name = " + device.getAlias());
} else {
DebugLog.info("BluetoothDevice is null!");
}
switch (action) {
case Intent.ACTION_BOOT_COMPLETED: //开机
//判断蓝牙是否连接
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
int blueConnectState = bluetoothAdapter.getConnectionState();
DebugLog.info("bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3");
DebugLog.info("blueConnectState = " + blueConnectState);
break;
//BluetoothAdapter 相关广播
case BluetoothAdapter.ACTION_STATE_CHANGED: //蓝牙开关
DebugLog.info("Bluetooth Switch state :STATE_OFF --> 10, STATE_TURNING_ON --> 11, STATE_ON --> 12 ,STATE_TURNING_OFF --> 13 ");
int switchState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
DebugLog.info("Bluetooth Switch change to= " + switchState);
break;
case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED: //蓝牙扫描状态修改
DebugLog.info("Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23");
int scanMode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, -1);
DebugLog.info("Bluetooth scanMode change to = " + scanMode);
break;
case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED: //蓝牙连接,和ACL连接的区别 ?
DebugLog.info("bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3");
int connectPreviousState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, -1);
DebugLog.info("Bluetooth connectPreviousState = " + connectPreviousState);
int connectState = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, -1);
DebugLog.info("Bluetooth state = " + connectState);
break;
//BluetoothDevice 相关广播
case BluetoothDevice.ACTION_ACL_CONNECTED: //蓝牙连接
//判断当前连接的蓝牙数量
DebugLog.debug("ACTION_ACL_CONNECTED() !");
break;
case BluetoothDevice.ACTION_ACL_DISCONNECTED: //蓝牙断开
DebugLog.debug("ACTION_ACL_DISCONNECTED() !");
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED: //蓝牙绑定状态改变,绑定前后蓝牙变化广播
DebugLog.info("Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12 ");
int bondPreviousState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
DebugLog.info("Bluetooth bondPreviousState = " + bondPreviousState);
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
DebugLog.info("Bluetooth bondState = " + bondState);
break;
case BluetoothDevice.ACTION_PAIRING_REQUEST: //蓝牙配对
DebugLog.debug("ACTION_PAIRING_REQUEST !");
int pinNumber = intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY", 1234);
DebugLog.debug("ACTION_PAIRING_REQUEST pinNumber = " + pinNumber);
break;
case BluetoothDevice.ACTION_PAIRING_CANCEL: //蓝牙取消配对
DebugLog.debug("ACTION_PAIRING_CANCEL !");
break;
}
}
};
}
上面的代码是在Activity 界面动态注册蓝牙主要广播代码,为啥不用静态,可以看看后面蓝牙广播注册时机说明。
3、广播接收代码示例日志
紧接着上面示例代码,下面是Android13 上mtk方案的日志情况。
(1)蓝牙打开、关闭日志
蓝牙打开:
//1、蓝牙打开,获取到的BluetoothDevice对象为 null
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.STATE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
//2、蓝牙进入正在开启状态
MainActivity.java(81)::onReceive - Bluetooth Switch state :STATE_OFF --> 10, STATE_TURNING_ON --> 11, STATE_ON --> 12 ,STATE_TURNING_OFF --> 13
MainActivity.java(83)::onReceive - Bluetooth Switch change to= 11
//3、这里是系统设置本设备可被其他设备发现后(应用一般开启蓝牙会控制)
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.SCAN_MODE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(86)::onReceive - Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23
MainActivity.java(88)::onReceive - Bluetooth scanMode change to = 23
//4、蓝牙进入开启状态,获取到的BluetoothDevice对象为 null
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.STATE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(81)::onReceive - Bluetooth Switch state :STATE_OFF --> 10, STATE_TURNING_ON --> 11, STATE_ON --> 12 ,STATE_TURNING_OFF --> 13
MainActivity.java(83)::onReceive - Bluetooth Switch change to= 12
蓝牙关闭:
//1、蓝牙状态改变,进入正在关闭蓝牙状态
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.STATE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(81)::onReceive - Bluetooth Switch state :STATE_OFF --> 10, STATE_TURNING_ON --> 11, STATE_ON --> 12 ,STATE_TURNING_OFF --> 13
MainActivity.java(83)::onReceive - Bluetooth Switch change to= 13
//2、可被发现状态为NONE, 这个是系统原生流程设置的
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.SCAN_MODE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(86)::onReceive - Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23
MainActivity.java(88)::onReceive - Bluetooth scanMode change to = 20
//3、蓝牙状态改变,蓝牙关闭状态
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.STATE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(81)::onReceive - Bluetooth Switch state :STATE_OFF --> 10, STATE_TURNING_ON --> 11, STATE_ON --> 12 ,STATE_TURNING_OFF --> 13
MainActivity.java(83)::onReceive - Bluetooth Switch change to= 10
//4、可被发现状态为NONE, 这个是系统原生流程设置的
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.SCAN_MODE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(86)::onReceive - Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23
MainActivity.java(88)::onReceive - Bluetooth scanMode change to = 20
关闭流程里面有两次设置了蓝牙设备不可发现,这个是原生代码流程处理的,不用管的,影响不大。
(2)蓝牙请求连接其他蓝牙设备日志
点击配对蓝牙到自动连接的过程
//1、绑定状态的改变,从 普通状态10 到 正在绑定状态11
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 10
MainActivity.java(112)::onReceive - Bluetooth bondState = 11
//2、这时就有连接成功的简单日志?!
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.ACL_CONNECTED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(102)::onReceive - ACTION_ACL_CONNECTED() !
//3、请求配对,配对码没有,因为我是连接的蓝牙耳机,所以是没有配对码的!
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.PAIRING_REQUEST
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(115)::onReceive - ACTION_PAIRING_REQUEST !
MainActivity.java(117)::onReceive - ACTION_PAIRING_REQUEST pinNumber = 1234
//上面是进入配对确认状态,确认后会自动进入后续状态。
//4、绑定状态的改变,从正在绑定状态11 到 绑定完成状态12
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 11
MainActivity.java(112)::onReceive - Bluetooth bondState = 12
//5、连接成功详细信息,从断开连接状态0 到连接中状态1
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 0
MainActivity.java(95)::onReceive - Bluetooth state = 1
//6、连接成功详细信息,从连接中状态1 到连接成功状态2
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 1
MainActivity.java(95)::onReceive - Bluetooth state = 2
//7、扫描状态,进入可被连接状态
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.SCAN_MODE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(86)::onReceive - Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23
MainActivity.java(88)::onReceive - Bluetooth scanMode change to = 21
//8、扫描状态,进入可被外部设备发现和连接状态
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.SCAN_MODE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(86)::onReceive - Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23
MainActivity.java(88)::onReceive - Bluetooth scanMode change to = 23
(3)其他Android设备请求连接配对设备日志
其他Android手机设备配对自己的设备,未确认配对前
//1、连接成功简单信息
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.ACL_CONNECTED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(102)::onReceive - ACTION_ACL_CONNECTED() !
//2、绑定状态改变,从普通状态10 进入到 配对状态 11
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 10
MainActivity.java(112)::onReceive - Bluetooth bondState = 11
//3、进入配对过程,手机配对,有请求码。
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.PAIRING_REQUEST
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(115)::onReceive - ACTION_PAIRING_REQUEST !
MainActivity.java(117)::onReceive - ACTION_PAIRING_REQUEST pinNumber = 984754
配对又分为确认配对或者不配对
点击取消配对/不点击处理导致配对超时的情况
//1、绑定状态,从正在绑定11 到 普通状态10
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 11
MainActivity.java(112)::onReceive - Bluetooth bondState = 10
//2、断开连接简单信息
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.ACL_DISCONNECTED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(105)::onReceive - ACTION_ACL_DISCONNECTED() !
点击确认配对的情况
正常点击配对的情况
//1、绑定状态发生改变,从绑定中11 变成 绑定完成状态12
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 11
MainActivity.java(112)::onReceive - Bluetooth bondState = 12
//2、绑定状态发生改变,从绑定中11 变成 绑定完成状态12
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 12
MainActivity.java(112)::onReceive - Bluetooth bondState = 11
//3、连接成功详细状态,从断开连接状态0 到 连接中1
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 0
MainActivity.java(95)::onReceive - Bluetooth state = 1
//4、连接成功详细状态,从连接中1 到 连接成功2
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 1
MainActivity.java(95)::onReceive - Bluetooth state = 2
//5、绑定状态发生改变,从绑定中11 变成 绑定完成状态12
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 18:87:40:11:16:0E,name = Redmi 10X
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 11
MainActivity.java(112)::onReceive - Bluetooth bondState = 12
注意,我这里是mtk平台的方案,和普通系统方案有点不一样的。
普通Android系统方案是无法正常连接手机的,mtk平台是可以的,普通平台估计就是从普通状态进入到绑定状态。
(4)蓝牙连接、断开日志
从保存状态到连接蓝牙设备
//1、蓝牙具体连接状态广播,从 断开 0 到 连接中 1
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 0
MainActivity.java(95)::onReceive - Bluetooth state = 1
//2、另外一个简单蓝牙连接状态广播,没有之前的状态的
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.ACL_CONNECTED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(102)::onReceive - ACTION_ACL_CONNECTED() !
//其他的蓝牙相关TAG打印
BluetoothDatabase: updateDatabase XX:XX:XX:11:AC:7C
//3、蓝牙具体连接状态广播,从 连接中 1 到 连接成功 2
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 1
MainActivity.java(95)::onReceive - Bluetooth state = 2
断开蓝牙设备,从连接状进入保存状态
//1、连接状态详细信息,从连接状态2 进入正在断开连接状态 3
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 2
MainActivity.java(95)::onReceive - Bluetooth state = 3
//2、连接状态详细信息,从正在断开连接状态 3 进入已断开连接状态0
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 3
MainActivity.java(95)::onReceive - Bluetooth state = 0
//3、断开连接简易信息
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.ACL_DISCONNECTED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(105)::onReceive - ACTION_ACL_DISCONNECTED() !
(5)蓝牙忘记设备日志
从保存状态忘记设备
//1、绑定状态改变,从之前的绑定状态12 进入 普遍状态 10
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 12
MainActivity.java(112)::onReceive - Bluetooth bondState = 10
//2、可被发现状态改变,可连接和发现,这可能是原生流程
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.SCAN_MODE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(86)::onReceive - Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23
MainActivity.java(88)::onReceive - Bluetooth scanMode change to = 23
从连接状态忘记设备
//1、断开设备简单状态
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.ACL_DISCONNECTED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(105)::onReceive - ACTION_ACL_DISCONNECTED() !
//2、绑定设备状态改变,冲绑定12 到 普通状态10
MainActivity.java(58)::onReceive - action = android.bluetooth.device.action.BOND_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(108)::onReceive - Bluetooth bond state :BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
MainActivity.java(110)::onReceive - Bluetooth bondPreviousState = 12
MainActivity.java(112)::onReceive - Bluetooth bondState = 10
//3、断开设备详细状态,从连接2 到断开0
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED
MainActivity.java(66)::onReceive - BluetoothDevice = 11:75:58:11:AC:7C,name = A19
MainActivity.java(91)::onReceive - bluetooth ConnectState :STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
MainActivity.java(93)::onReceive - Bluetooth connectPreviousState = 2
MainActivity.java(95)::onReceive - Bluetooth state = 0
//4、可被发现状态改变,可连接和发现,这可能是原生流程
MainActivity.java(58)::onReceive - action = android.bluetooth.adapter.action.SCAN_MODE_CHANGED
MainActivity.java(68)::onReceive - BluetoothDevice is null!
MainActivity.java(86)::onReceive - Bluetooth scan mode :SCAN_MODE_NONE --> 20, SCAN_MODE_CONNECTABLE --> 21, SCAN_MODE_CONNECTABLE_DISCOVERABLE --> 23
MainActivity.java(88)::onReceive - Bluetooth scanMode change to = 23
从这里看从连接状态直接忘记设备是会先断开设备,在忘记设备的。
上面日志有点多,其实固定的状态,无非就几种状态:普通,保存,连接。
日志比较多,不一定要全部看一遍,看一两个后有大概了解就可以了,并且实际情况还会有一定变化,跟自己的开发应用处理过程调用的api有相关。
(6)日志总结
如果上面日志过程没怎么看的,那么日志总结可以看看。
重要过程,日志里面主要包含connection状态,acl_connected,bond等信息
1、开关状态,数值:STATE_OFF=10, STATE_TURNING_ON=11, STATE_ON=12 ,STATE_TURNING_OFF=13
2、绑定状态,数值::BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
3、连接状态,数值:STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
4、可被连接和发现状态,数值:SCAN_MODE_NONE=20, SCAN_MODE_CONNECTABLE=21, SCAN_MODE_CONNECTABLE_DISCOVERABLE=23
5、蓝牙从保存到连接会有 ACL_CONNECTED 和 CONNECTION_STATE_CHANGED 广播
CONNECTION_STATE_CHANGED 广播信息更加全面可靠,通过额外数据可以获取具体状态
6、从配对设备日志可以看到,未点击确认配对前就有 ACL_CONNECTED 和 BOND_STATE_CHANGED 广播
但是从 BOND_STATE_CHANGED 额外信息获取可以知道当前是绑定中的状态
确认配对后,才会进入BOND_STATE_CHANGED绑定成功和连接成功CONNECTION_STATE_CHANGED状态广播,
后续没有再收到 ACL_CONNECTED 广播,所以从配对过程也可以看到 ACL_CONNECTED 连接的广播是不准确的
7、断开连接使用 ACL_DISCONNECTED 广播判断一般是没问题的,其实也是不太准确的,因为这时候是正在断开的状态,通过广播 CONNECTION_STATE_CHANGED 额外信息获取到的断开状态才是比较准确的断开。
蓝牙各种情况状态真的是多,很容易忘记;
强烈建议像上面示例代码一样,先打印不同状态值对应的关系,再打印具体的状态值,这样就一下子知道获取到的状态值的含义了。
三、蓝牙状态判断
1、蓝牙开关状态
(1)蓝牙开关状态在 BluetoothAdapter.java 中的定义
?
public static final int STATE_OFF = 10;
public static final int STATE_TURNING_ON = 11;
public static final int STATE_ON = 12;
public static final int STATE_TURNING_OFF = 13;
public static final int STATE_BLE_TURNING_ON = 14; //这个应该没啥用。
(2)蓝牙开启状态判断
系统应用代码中对开关状态的判断处理:
LocalBluetoothManager mBluetoothManager = LocalBluetoothManager.getInstance(context, null);
LocalBluetoothAdapter mLocalAdapter = mBluetoothManager.getBluetoothAdapter();
//判断蓝牙是否打开,如果刚点击开关也会为true,蓝牙关闭肯定为false
boolean isEnabled = mLocalAdapter.isEnabled()
//界面显示的时候,可以再判断一下蓝牙具体状态,因为有可能是打开中的状态
if (isEnabled) {
updateContent(mLocalAdapter.getBluetoothState());//判断蓝牙状态
} else { //蓝牙关闭的情况
。。。
}
//蓝牙具体开关状态,处理示例
void updateContent(int bluetoothState) {
//蓝牙开关状态记得打印一下,有些问题是在打开中和关闭中处理导致异常的,是可以规避的。
LogUtil.debug("bluetoothState = " + bluetoothState);
switch (bluetoothState) { //一般只判断蓝牙是否进入开启和关闭
case BluetoothAdapter.STATE_ON: //蓝牙开启状态
enableScanning(); //开始扫描设备和接收设备列表
addCachedDevices();
break;
case BluetoothAdapter.STATE_OFF: //蓝牙已关闭成功状态
//更新UI
removeAllDevices();
break;
}
}
上面是一般系统应用的处理,LocalBluetoothManager 等一系列Local相关类都是在系统SettingsLib里面的。
普通应用也可以调用原生接口的类处理:
public final class BluetoothAdapter {
//静态获取 BluetoothAdapter 对象方法
public static synchronized BluetoothAdapter getDefaultAdapter() {
if (sAdapter == null) {
IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
if (b != null) {
IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
sAdapter = new BluetoothAdapter(managerService);
} else {
Log.e(TAG, "Bluetooth binder is null");
}
}
return sAdapter;
}
//判断蓝牙是否开启
public boolean isEnabled() {
return getState() == BluetoothAdapter.STATE_ON;
}
}
2、蓝牙连接状态数值
BluetoothAdapter.java
/** The profile is in disconnected state */
public static final int STATE_DISCONNECTED = 0; //BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED;
/** The profile is in connecting state */
public static final int STATE_CONNECTING = 1; //BluetoothProtoEnums.CONNECTION_STATE_CONNECTING;
/** The profile is in connected state */
public static final int STATE_CONNECTED = 2; //BluetoothProtoEnums.CONNECTION_STATE_CONNECTED;
/** The profile is in disconnecting state */
public static final int STATE_DISCONNECTING = 3; //BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING;
3、蓝牙某个设备绑定/连接状态
绑定其实就是已保存的设备,连接的设备是当前使用中的设备。
LocalBluetoothManager mBluetoothManager = LocalBluetoothManager.getInstance(context, null);
//已连接+绑定设备列表
Set<BluetoothDevice> bondedDevices = mBluetoothManager.getBluetoothAdapter().getBondedDevices();
for (CachedBluetoothDevice cachedDevice : cachedDevices) {
//蓝牙 BluetoothDevice 对象
BluetoothDevice deviceDevice = cachedDevice.getDevice();
//蓝牙名称
String name = deviceDevice.getName();
//蓝牙类型
int majorDeviceClass = cachedDevice.getBtClass().getMajorDeviceClass();
//蓝牙是否连接状态,不是连接状态的都是保存状态的
boolean isConnected = cachedDevice.isConnected();
//处理!
。。。
}
上面是系统应用写法,如果是普通应用,可以使用 BluetoothDevice 对象判断连接状态。
4、蓝牙关键对象 BluetoothDevice
BluetoothDevice 对象是操作蓝牙非常关键的对象,
里面包含了蓝牙基本信息:蓝牙名称,别名,MAC地址,蓝牙Class类型,电量,绑定状态,是否连接等状态
还包含了一些重要操作:配对,取消配对,连接,断开,忘记等重要操作过程。
(1)获取 BluetoothDevice 对象
普通应用如果没有SettingsLib,只能通过FOUND广播,获取扫描的蓝牙列表
系统应用写法:
//获取扫描列表
Collection<CachedBluetoothDevice> cachedDevices = mBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy();
//已连接/绑定设备列表
Set<BluetoothDevice> bondedDevices = mBluetoothManager.getBluetoothAdapter().getBondedDevices();
其实SettingsLib里面实现也是根据 FOUND广播,不断添加扫描到的蓝牙对象BluetoothDevice ,合成CachedBluetoothDevice 对象。
普通应用就要通过广播接收 BluetoothDevice.ACTION_FOUND ,获取到 BluetoothDevice 对象并收集起来显示在界面。
本文的示例代码里面只监听了广播,扫描和其他所有操作都是其他应用里面的,
获取不到 ACTION_FOUND 广播,应该是有地方收到后,进行了拦截,
自己写的demo应用,自己扫描是可以收到 ACTION_FOUND 广播信息的。
当然其他广播也有 BluetoothDevice 对象,比如蓝牙连接,断开,绑定状态改变,
但是这个广播里面的 BluetoothDevice 回调只是为了更新列表信息的数据。
蓝牙开关开关变化以及扫描状态改变等广播,是没有 BluetoothDevice 对象回调的,
所以获取BluetoothDevice 的时候要进行一下判空处理。
(2)BluetoothDevice 关键信息
public final class BluetoothDevice implements Parcelable, Attributable {
private static final String TAG = "BluetoothDevice";
private static final boolean DBG = false;
//1、基本信息
//对象 toString 只打印MAC 地址
public String toString() {
return mAddress;
}
//2、获取MAC地址
public String getAddress() {
if (DBG) Log.d(TAG, "mAddress: " + mAddress);
return mAddress;
}
//3、获取蓝牙设备名称
public String getName() {}
//4、设备蓝牙设备别名,如果未设置别名,最后也是获取的名称 Name
public String getAlias() {}
//5、设置其他蓝牙设备别名名称
public int setAlias(@Nullable String alias) {}
//6、获取电池电量,充电状态可能不准确
public @IntRange(from = -100, to = 100) int getBatteryLevel() {}
//7、获取绑定状态
public int getBondState() {}
//8、判断设备是否是连接状态
public boolean isConnected() {}
//常用操作
//1、从普通状态进入配对,执行确认配对就会进入连接状态
public boolean createBond() {}
//2、取消配对
public boolean cancelBondProcess() { }
//3、连接,可以从保存状态进入连接状态
public int connect() { }
//4、断开连接,可以用连接状态进入保存状态
public int disconnect() { }
//5、忘记设备
public boolean removeBond() {
//6、自动确认连接,前提是对方设备确认了配对,蓝牙设备不用对方确认,手机、蓝牙键盘一般要对方确认
public boolean setPairingConfirmation(boolean confirm) {
}
BluetoothDevice 对象大致就上面的内容了,有兴趣可以再看看源码。
其中蓝牙类型还是比较多知识的,可以看看之前那个博客:
https://blog.csdn.net/wenzhi20102321/article/details/133777224
四、其他
1、蓝牙配对广播ACTION_PAIRING_REQUEST的说明
这个配对是别的设备向你配对,还是你的设备向其他的设备配对?
其实不管是你配对其他设备,还是其他设备向你配对都是有这个广播,
系统的弹框提示(有的有配对码),就是用接收这个广播,然后弹框提示。
这个广播是有序广播,如果要自定义弹框就可以自己接收这个广播弹框,并进行拦截
abortBroadcast(); //onReceive 方法内,拦截广播可以拦截掉系统那个,让系统的配对框不显示。
如果要默认就是支持配对,就在收到 ACTION_PAIRING_REQUEST 广播里面,设置默认同意即可。
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
device.setPairingConfirmation(true);
在广播请求广播内设置了上述代码,本机设备相当于默认支持别的设备配对的。
至于是否需要弹框提示,可以根据实际情况处理。
2、蓝牙广播注册时机说明
理论上,除了几个特殊广播,比如息屏广播和时间变化广播等,
蓝牙上面的所有广播,无论是静态还是动态都是可以注册的,但是实际上却不是这样的。
我这个是通过Android13 实际代码验证的情况:
只能动态注册的蓝牙广播:
BluetoothAdapter.ACTION_STATE_CHANGED: //蓝牙开关
BluetoothAdapter.ACTION_SCAN_MODE_CHANGED: //蓝牙扫描状态修改
BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED: //蓝牙连接详细情况
BluetoothDevice.ACTION_BOND_STATE_CHANGED: //蓝牙绑定状态改变,绑定前后蓝牙变化广播
动态和静态注册都ok 的蓝牙广播:
BluetoothDevice.ACTION_ACL_CONNECTED: //蓝牙连接
BluetoothDevice.ACTION_ACL_DISCONNECTED: //蓝牙断开
这里看静态注册没几个广播信息的!
这里不做具体原因分析,如果要研究可以看看AMS加载 apk 信息的过程,应该有对某些广播的限制代码(静态注册相当于没注册)。
所以说蓝牙的广播动态注册是最保险的,可以在自己的某个服务启动后进行动态监听注册即可。
插一句,所有的广播都是可以动态注册并且能正常监听,
即使是开机广播 Intent.ACTION_BOOT_COMPLETED 只要你在系统服务刚起来的时候注册这个广播,
开机完成后也是可以收到广播信息的,并且还会比静态注册的方式收到得快一些。
3、各种状态总结
蓝牙状态感觉很多的样子,但是其实就三个,开关状态,绑定状态,连接状态。
写完这个后,我可能也会不记得了,所以最的方法是,打印状态前,打印一下所有状态的含义。
但是还是要总结一下,大概知道有这些属性值就行:
1、开关状态,数值:
STATE_OFF=10, STATE_TURNING_ON=11, STATE_ON=12 ,STATE_TURNING_OFF=13
2、绑定状态,数值::
BOND_NONE = 10, BOND_BONDING = 11, BOND_BONDED = 12
3、连接状态,数值:
STATE_DISCONNECTED=0, STATE_CONNECTING=1, STATE_CONNECTED=2, STATE_DISCONNECTING=3
除了上面三个,还有个是否可以连接和被发现状态
4、可被发现和连接状态:
SCAN_MODE_NONE=20, SCAN_MODE_CONNECTABLE=21, SCAN_MODE_CONNECTABLE_DISCOVERABLE=23
是否可被发现是有api可以控制的
蓝牙关闭是会进入不可发现和连接的 SCAN_MODE_NONE 状态。
// 设置蓝牙可见性
public void requestDiscoverable() {
LocalBluetoothAdapter mLocalAdapter = mBluetoothManager.getBluetoothAdapter();
mLocalAdapter.setDiscoverableTimeout(300); //注意单位是秒哦
//可发现和可连接状态
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
}
4、其他开发组对于这部分知识的总结
(1)Android 蓝牙基本开发知识介绍,包含一些常用的api和广播
地址:https://www.jianshu.com/p/b15314d91df0
(3)Android 蓝牙驱动开发
地址: https://www.voycn.com/index.php/article/androidzhilanyaqudongkaifazongjie
(4)蓝牙通讯框架
https://zhuanlan.zhihu.com/p/500092347
(5)蓝牙广播-硬件信号相关的介绍
https://blog.51cto.com/u_12959/7464069
(6)之前写的蓝牙总结文章,有兴趣可以看看
Android无线蓝牙开发总结:
https://blog.csdn.net/wenzhi20102321/article/details/53870789
Android蓝牙4.0开发:
https://blog.csdn.net/wenzhi20102321/article/details/53893511
Android 蓝牙协议配置讲解:
https://blog.csdn.net/wenzhi20102321/article/details/125826972
Android13 原生设置应用蓝牙配对代码分析研究:
https://blog.csdn.net/wenzhi20102321/article/details/131648367
Android 实现蓝牙录音:
https://blog.csdn.net/wenzhi20102321/article/details/89714569
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!