BLE

安卓BLE蓝牙

2020-04-24  本文已影响0人  仕明同学

1、简介

image.png image.png

2、连接流程

蓝牙是夸进程通信的,所以源码使用了aidl来解决跨进程通信
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;
}

adapter.startLeScan(mScanCallback)
  private final BluetoothAdapter.LeScanCallback mScanCallback = new BluetoothAdapter.LeScanCallback() {
        /**
         * ui线程,不要做耗时操作
         * @param device
         * @param rssi 信号强度
         * @param scanRecord 广播数据,解析广播
         */
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            ScanResult result = new ScanResult(device, rssi, scanRecord);
            if (TextUtils.isEmpty(device.getName())){

            }else if (!mScanResults.containsKey(device.getAddress())) {
                mScanResults.put(device.getAddress(), result);
                Log.v(TAG, String.format("onLeScan: mac = %s, name = %s, record = (%s)%d",
                        device.getAddress(), device.getName(), byteToString(scanRecord), scanRecord.length));
                mAdapter.refresh(mScanResults);
            }
        }
    };

2、通过BluetoothLeScanner,目前项目使用这个


   BluetoothAdapter adapter = getBluetoothManager().getAdapter();
        BluetoothLeScanner bluetoothLeScanner = adapter.getBluetoothLeScanner();
        bluetoothLeScanner.startScan(new ScanCallback() {
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                super.onScanResult(callbackType, result);
            }

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

            @Override
            public void onScanFailed(int errorCode) {
                super.onScanFailed(errorCode);
            }
        });
        
  mBluetoothGatt = mDevice.connectGatt(this, false, new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                Log.v(TAG, String.format("onConnectionStateChange: status = %d, newState = %d", status, newState));

                if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothGatt.STATE_CONNECTED) {
                    onConnected();

                    if (!mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)) {
                        disconnect();
                    }

                    if (!mBluetoothGatt.discoverServices()) {
                        disconnect();
                    }
                } else {
                    disconnect();
                }
            }

            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                Log.v(TAG, String.format("onServicesDiscovered: status = %d", status));

                if (status == BluetoothGatt.GATT_SUCCESS) {
                    refreshProfile();

                    startChannel();

                    BluetoothUtils.setCharacteristicNotification(gatt, UUID_MYSERVICE, UUID_PACKET, true);
                    mBtnPacket.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mBtnPacket.setEnabled(true);
                        }
                    }, 1000);
                } else {
                    disconnect();
                }
            }

            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                Log.v(TAG, String.format("onCharacteristicRead: service = %s, character = %s, value = %s, status = %d",
                        characteristic.getService().getUuid(),
                        characteristic.getUuid(),
                        ByteUtils.byteToString(characteristic.getValue()),
                        status));
            }

            @Override
            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                Log.v(TAG, String.format("onCharacteristicWrite service = %s, character = %s, status = %d",
                        characteristic.getService().getUuid(),
                        characteristic.getUuid(),
                        status));
                if (mChannelCallback != null) {
                    mChannelCallback.onCallback(status == BluetoothGatt.GATT_SUCCESS ? Code.SUCCESS : Code.FAIL);
                    mChannelCallback = null;
                }
            }

            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                Log.v(TAG, String.format("onCharacteristicChanged service = %s, character = %s, value = %s",
                        characteristic.getService().getUuid(),
                        characteristic.getUuid(),
                        ByteUtils.byteToString(characteristic.getValue())));

                mChannel.onRead(characteristic.getValue());
            }

            @Override
            public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
                Log.v(TAG, String.format("onReadRemoteRssi rssi = %d, status = %d", rssi, status));
            }

            @Override
            public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                Log.v(TAG, String.format("onDescriptorWrite service = %s, character = %s, descriptor = %s, status = %d",
                        descriptor.getCharacteristic().getService().getUuid(),
                        descriptor.getCharacteristic().getUuid(),
                        descriptor.getUuid(), status));
            }
        });
image.png

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    Log.v(TAG, String.format("onCharacteristicChanged service = %s, character = %s, value = %s",
            characteristic.getService().getUuid(),
            characteristic.getUuid(),
            ByteUtils.byteToString(characteristic.getValue())));

    mChannel.onRead(characteristic.getValue());
}

private BluetoothGattCharacteristic getNotifyCharacteristic() {
    if (mBluetoothGatt != null) {
        BluetoothGattService service = mBluetoothGatt.getService(UUID_MYSERVICE);
        return service != null ? service.getCharacteristic(UUID_PACKET) : null;
    }
    return null;
}
BluetoothGattCharacteristic characteristic = getNotifyCharacteristic();
characteristic.setValue(bytes);
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
mBluetoothGatt.writeCharacteristic(characteristic);
mChannelCallback = callback;

3、什么是GATT

2、service可以理解为一个服务,在ble从机中,通过有多个服务,例如电量信息服务、系统信息服务等,每个service中又包含多个characteristic特征值。每个具体的characteristic特征值才是ble通信的主题。比如当前的电量是80%,所以会通过电量的characteristic特征值存在从机的profile里,这样主机就可以通过这个characteristic来读取80%这个数据
3、characteristic特征值,ble主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容。

把Profile 当做是国家,Service 就是中国足球。Characteristic就是国足的某一个人,我需要找到这个人告诉他,明天不要提假球(类似对ble设备设置信息),所以需要uuid,uuid一般是问询问硬件工程师,问他要这个设备的UUID

4、UUID到底是个啥?

5、BLE一些问题的总结,刚入坑不久,持续记录

安卓BLE蓝牙.png
上一篇 下一篇

猜你喜欢

热点阅读