作为菜鸟,记录下今年蓝牙入坑1年的一些问题,方便回顾;
蓝牙的相应api就不贴了;
要实现自动配对先注册广播:
/**
* 搜索BroadcastReceiver
*/
private final BroadcastReceiver searchDevices = new BroadcastReceiver() {
@SuppressLint("NewApi")
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = null;
// 搜索设备时,取得设备的MAC地址
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
String str = " 未配对|" + device.getName() + "|"
+ device.getAddress();
LogUtils.e(str);
}
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
LogUtils.e("action:" + action);
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING:
LogUtils.e(TAG, "正在配对......");
break;
case BluetoothDevice.BOND_BONDED:
LogUtils.e(TAG, "配对成功!");
break;
case BluetoothDevice.BOND_NONE:
LogUtils.e(TAG, "取消配对");
default:
break;
}
} else if (intent.getAction().equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
LogUtils.e("action:" + action);
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//1.确认配对
device.setPin(strPsw.getBytes());
//如果没有将广播终止,则会出现一个一闪而过的配对框。
abortBroadcast();
}
}
}
};
配对:之前没接触蓝牙相关api的时候,也是学网上的api用反射区实现;后来谷歌爸爸在9.0限制了不能使用反射获取隐藏api(亲测,两部p20,8.0可以配对,9.0无法配对),这个反射实现的自动陪对也就尴尬了。后面看api,发现可以直接使用;
在扫描到设备后连接,根据 BluetoothDevice.getBondState() == BluetoothDevice.BOND_NONE
判断是否已经配对,没有配对调用BluetoothDevice.createBond()之后在广播中监听,在监听到BluetoothDevice.ACTION_PAIRING_REQUEST后调用 device.setPin(strPsw.getBytes());将PIN码设置进去,好了就是这么简单,目前我在华为p20、荣耀8等几部手机上都测试没问题。后续再多试几部手机。
发现服务:蓝牙连接后在BluetoothGattCallback接口回调方法onConnectionStateChange(BluetoothGatt gatt, int status, int newState)中调用gatt.discoverServices()发现服务,这个地方有坑。有时候发现服务不了(个人认为因为这些回调都是在异步线程,异步嘛就是得看看什么时候有空了就执行)。换了个办法就是gatt不拿onConnectionStateChange回调回来的,直接用BluetoothGatt mBluetoothGatt=BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)连接时候的mBluetoothGatt.discoverServices()发现服务,在onConnectionStateChange回调后在主线程中调mBluetoothGatt.discoverServices();我目前试的基本都能成功。
切到主线程我是用的 handler。
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
Message message = mainHandler.obtainMessage();
message.what = BleMsg.MSG_DISCOVER_SERVICES;
mainHandler.sendMessage(message);
}
}
private MainHandler mainHandler = new MainHandler(Looper.getMainLooper());
private final class MainHandler extends Handler {
MainHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BleMsg.MSG_DISCOVER_SERVICES: {
if (bluetoothGatt != null) {
mBluetoothGatt.discoverServices()
}
}
default:
super.handleMessage(msg);
break;
}
}
}
以上记录,有错误还请原谅。
有问题可以一起交流~