作為菜鳥,記錄下今年藍(lán)牙入坑1年的一些問題,方便回顧;
藍(lán)牙的相應(yīng)api就不貼了;
要實現(xiàn)自動配對先注冊廣播:
/**
* 搜索BroadcastReceiver
*/
private final BroadcastReceiver searchDevices = new BroadcastReceiver() {
@SuppressLint("NewApi")
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = null;
// 搜索設(shè)備時,取得設(shè)備的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.確認(rèn)配對
device.setPin(strPsw.getBytes());
//如果沒有將廣播終止,則會出現(xiàn)一個一閃而過的配對框。
abortBroadcast();
}
}
}
};
配對:之前沒接觸藍(lán)牙相關(guān)api的時候,也是學(xué)網(wǎng)上的api用反射區(qū)實現(xiàn);后來谷歌爸爸在9.0限制了不能使用反射獲取隱藏api(親測,兩部p20,8.0可以配對,9.0無法配對),這個反射實現(xiàn)的自動陪對也就尷尬了。后面看api,發(fā)現(xiàn)可以直接使用;
在掃描到設(shè)備后連接,根據(jù) BluetoothDevice.getBondState() == BluetoothDevice.BOND_NONE
判斷是否已經(jīng)配對,沒有配對調(diào)用BluetoothDevice.createBond()之后在廣播中監(jiān)聽,在監(jiān)聽到BluetoothDevice.ACTION_PAIRING_REQUEST后調(diào)用 device.setPin(strPsw.getBytes());將PIN碼設(shè)置進(jìn)去,好了就是這么簡單,目前我在華為p20、榮耀8等幾部手機(jī)上都測試沒問題。后續(xù)再多試幾部手機(jī)。
發(fā)現(xiàn)服務(wù):藍(lán)牙連接后在BluetoothGattCallback接口回調(diào)方法onConnectionStateChange(BluetoothGatt gatt, int status, int newState)中調(diào)用gatt.discoverServices()發(fā)現(xiàn)服務(wù),這個地方有坑。有時候發(fā)現(xiàn)服務(wù)不了(個人認(rèn)為因為這些回調(diào)都是在異步線程,異步嘛就是得看看什么時候有空了就執(zhí)行)。換了個辦法就是gatt不拿onConnectionStateChange回調(diào)回來的,直接用BluetoothGatt mBluetoothGatt=BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)連接時候的mBluetoothGatt.discoverServices()發(fā)現(xiàn)服務(wù),在onConnectionStateChange回調(diào)后在主線程中調(diào)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;
}
}
}
以上記錄,有錯誤還請原諒。
有問題可以一起交流~