Android 藍牙 BLE 開發筆記


最近公司頭戴換了一塊藍牙4.0 BLE模塊,所以我們Android組要適配 BLE。
Android BLE 需要 4.3 以上系統,api 還是非常簡單的, 第一步就是掃描, 掃描到設備后就可以連接了,
連接成功后在 onServicesDiscovered 中拿到 Service Characteristic Descriptor 就可以了。
不過還是遇到了幾個小坑
第一: setCharacteristicNotification 時 onCharacteristicChanged 中收不到回調 原因是 BLE 不能連續執行寫操作,必須等前一個
寫完了再寫一下個, 所以應該維護一個隊列等前一個寫完了再寫下一個。

啟用通知

BluetoothGattCharacteristic rxCharacteristic = uartService
        .getCharacteristic(UUID.fromString(BleConst.UUID_RX_CHARACTERISTIC));
if (rxCharacteristic != null) {
    BluetoothGattDescriptor rxCharacteristicDescriptor = rxCharacteristic
            .getDescriptor(UUID.fromString(BleConst.UUID_RX_CHARACTERISTIC_DESCRIPTOR));
    // 設置 Characteristic 可以接收通知
    gatt.setCharacteristicNotification(rxCharacteristic, true);
    if (rxCharacteristicDescriptor != null) {
        // enable descriptor notification
        rxCharacteristicDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        mBluetoothGatt.writeDescriptor(rxCharacteristicDescriptor);
    }
}

第二:藍牙自動配對
自動配對就是通過反射去調用 BluetoothDevice 的 createBond 方法

Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
createBondMethod.invoke(btDevice);

第三:藍牙自動連接
配對和連接是不一樣的,自動配對后還要連接上藍牙, stackoverflow 查了一些下面的方法可以自動連接 A2DP 和 HFP 兩個 profile
監聽 BluetoothDevice.ACTION_BOND_STATE_CHANGED 廣播,藍牙配對成功后調用下面的方法連接上兩個 profile 就行了。

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    adapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            try {
                Log.d(TAG, "a2dp onServiceConnected");
                Method connect = BluetoothA2dp.class.getDeclaredMethod("connect", BluetoothDevice.class);
                connect.invoke(proxy, device);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(int profile) {
            Log.d(TAG, "a2dp onServiceDisconnected");
        }
    }, BluetoothProfile.A2DP);

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        adapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
            @Override
            public void onServiceConnected(int profile, BluetoothProfile proxy) {
                try {
                    Log.d(TAG, "hfp onServiceConnected");
                    Method connect = BluetoothHeadset.class.getDeclaredMethod("connect", BluetoothDevice.class);
                    connect.invoke(proxy, device);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(int profile) {
                Log.d(TAG, "hfp onServiceDisconnected");
            }
        }, BluetoothProfile.HEADSET);

目前頭戴所有按鍵走的都是藍牙自定義協議,本來Android是可以用 HID 標准鍵值的, 但由於 IOS 不支持 HID 所已也走自定義協議。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM