Android 藍牙開發


Android 藍牙開發

我們在進行藍牙開發時首先要了解低功耗藍牙、經典藍牙、單模藍牙、雙模藍牙之間的關系。
單模藍牙:支持低功耗藍牙
雙模藍牙:支持低功耗藍牙和經典藍牙
經典藍牙:支持經典藍牙
藍牙開發大致分為這幾步

前面需要定位權限和藍牙權限的支持

發現設備:

經典藍牙發現設備api
BluetoothAdapter.startDiscovery
聽說可以同時發現經典藍牙和低功耗藍牙(BLE)。但我這沒單模的藍牙,所以沒辦法測試。
因為startDiscovery返回的是一個是否開始掃描設備,我們要獲取藍牙設備的信息需要注冊一個 BroadcastReceiver 針對 ACTION_FOUND 
Intent 會攜帶額外的字段 EXTRA_DEVICE 和 EXTRA_CLASS。這兩者分別包含 BluetoothDevice 和 BluetoothClass。

var filter =IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver,filter);
    
    val mReceiver = object :BroadcastReceiver(){
        override fun onReceive(context: Context?, intent: Intent?) {
            var action = intent?.action
            if(BluetoothDevice.ACTION_FOUND == action){
                var device = intent?.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
            }
        }

    }
    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(mReceiver)
    }    

Ble發現設備api
BluetoothAdapter.getBluetoothLeScanner()
BluetoothLeScanner.startScan(ScanCallback callback)//掃描會在屏幕關閉時停止以節省電量。 再次打開屏幕時,將恢復掃描。 為避免這種情況,請使用下面兩個
BluetoothLeScanner.startScan(List<ScanFilter> filters, ScanSettings settings, ScanCallback callback)
BluetoothLeScanner.startScan(List<ScanFilter> filters, ScanSettings settings, PendingIntent callbackIntent)

BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        filters.add(new ScanFilter.Builder()
                .setServiceUuid(ParcelUuid.fromString("0000000-0000-0000-0000-000000000000"))
                .build());
        bluetoothLeScanner.startScan(filters , new ScanSettings.Builder().build(),
                new ScanCallback() {
                    @Override
                    public void onScanResult(int callbackType, ScanResult result) {
                        super.onScanResult(callbackType, result);
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            Log.d(MainActivity.ACTIVITY_SERVICE, "onScanResult:"+
                                "\n Rssi() "+result.getRssi()+
                                "\n AdvertisingSid() "+result.getAdvertisingSid()+
                                "\n DataStatus() "+result.getDataStatus()+
                                "\n ScanRecord() "+result.getScanRecord().getBytes()+
                                "\n Address() "+result.getDevice().getAddress()+
                                "\n Address() "+result.getDevice().getName()
                                );
                        }
                    }

                    @Override
                    public void onBatchScanResults(List<ScanResult> results) {
                        super.onBatchScanResults(results);
                    }

                    @Override
                    public void onScanFailed(int errorCode) {
                        super.onScanFailed(errorCode);
                    }
                }
        );

 

建立連接:

在配對之前應該先cancelDiscovery()或者stopScan(callback),
然后根據獲取到藍牙Mac地址連接即可

BluetoothDevice device = bluetoothAdapter.getRemoteDevice(result.getDevice().getAddress());
device.connectGatt(MainActivity.this, false, new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            //status 連接或斷開連接操作成功 BluetoothGatt.GATT_SUCCESS(0)
            //newState 新的連接狀態 BluetoothProfile.STATE_DISCONNECTED(0-斷開狀態) BluetoothProfile.STATE_CONNECTED(1-連接狀態)
        }
    }
);

 

數據通信:
ble寫入操作

 private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            //status 連接或斷開連接操作成功 BluetoothGatt.GATT_SUCCESS(0)
            //newState 新的連接狀態 BluetoothProfile.STATE_DISCONNECTED(0-斷開狀態) BluetoothProfile.STATE_CONNECTED(1-連接狀態)
            //獲取遠程設備提供的服務以及它們的特征和描述符。這步很重要而且是一個異步操作(這里需要時間直接接在下面寫不可取)
            bluetoothGatt.discoverServices();
            //獲取藍牙GATT服務
            BluetoothGattService gattService = bluetoothGatt.getService(UUID.fromString("00000000-0000-0000-0000-000000000000"/*藍牙協議*/));
            //GATT特性:用於構建 GATT 服務的基本數據元素
            BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(UUID.fromString("00000000-0000-0000-0000-000000000000"));
            //設置數據,這里是我加密后的數據所以看起來有點不習慣
            byte[] data = {-27, 36, 65, -70, -8, 94, 18, -12, -56, 116, -68, -124, 92, -19, 94, -91 };
            //設置此特性的本地存儲值。
            characteristic.setValue(data);
            //寫入到遠程藍牙設備
            bluetoothGatt.writeCharacteristic(characteristic);
                  
      

        }

 Ble通知讀取操作

//通知UUID
BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(UUID.fromString("00000000-0000-0000-0000-000000000000"));
enableNotification(bluetoothGatt,true,gattCharacteristic);

public void enableNotification(BluetoothGatt bluetoothGatt, boolean enable, BluetoothGattCharacteristic characteristic) {
            if (bluetoothGatt == null || characteristic == null) {
                return;
            }
            if (!bluetoothGatt.setCharacteristicNotification(characteristic, enable)) {
                return;
            }
            //獲取到Notify當中的Descriptor通道  然后再進行注冊
            List<BluetoothGattDescriptor> clientConfigs = characteristic.getDescriptors();
            if (clientConfigs == null || clientConfigs.size() ==0) {
                return;
            }
            if (enable) {
                for (BluetoothGattDescriptor clientConfig: clientConfigs) {
                    clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                    bluetoothGatt.writeDescriptor(clientConfig);
                }
            } else {
                for (BluetoothGattDescriptor clientConfig: clientConfigs) {
                    clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
                    bluetoothGatt.writeDescriptor(clientConfig);
                }
            }
        }

 


免責聲明!

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



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