美文网首页
关于蓝牙ble开发相关知识

关于蓝牙ble开发相关知识

作者: 林下人水边兵 | 来源:发表于2019-11-19 11:21 被阅读0次

    蓝牙的基础知识

    1. 相关权限申请

    权限

    android:name="android.permission.BLUETOOTH"/>

    android:name="android.permission.BLUETOOTH_ADMIN"/>

    注意:android6.0后 需要再添加如下权限定位权限 (如下一个就可以了 也可以多个申请)

    android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    android:name="android.permission.ACCESS_FINE_LOCATION"/>

    2. 搜索蓝牙流程

    2.1 打开蓝牙(需要在此之前获取蓝牙适配器BluetoothAdapter 才可以 调起打开蓝牙)

     2.1.1 获取蓝牙适配器BluetoothAdapter

    BluetoothManager bluetoothManager =

    (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

    mBluetoothAdapter = bluetoothManager.getAdapter();

      2.1.2 权限申请成功后 就可以 打开蓝牙 ,如下是蓝牙是

    if(mBluetoothAdapter ==null|| !mBluetoothAdapter.isEnabled()) {

    Intent enableBtIntent =newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

    startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);

    }

    2.2 扫描蓝牙设备

    mBluetoothAdapter.startLeScan(mLeScanCallback)

    需要注意:搜索是一个不间断的搜索过程,需要我们手动 停止搜索

    所以需要 调用mBluetoothAdapter. mBluetoothAdapter.stopLeScan(mLeScanCallback);

    具体代码 定时搜索 如下

    private voidscanLeDevice(final booleanenable) {

    if(enable) {

    // Stops scanning after a pre-defined scan period.

    mHandler.postDelayed(newRunnable() {

    @Override

    public voidrun() {

    mScanning =false;

    mBluetoothAdapter.stopLeScan(mLeScanCallback);

    }

    },SCAN_PERIOD);

    mScanning =true;

    mBluetoothAdapter.startLeScan(mLeScanCallback);

    }else{

    mScanning =false;

    mBluetoothAdapter.stopLeScan(mLeScanCallback);

    }

    关于mLeScanCallback的具体实现

    privateBluetoothAdapter.LeScanCallback mLeScanCallback =

    newBluetoothAdapter.LeScanCallback() {

    @Override

    public voidonLeScan(finalBluetoothDevice device, intrssi,

    byte[] scanRecord) {

    //搜索到蓝牙 将会在该方法回调 , device就是搜索到的蓝牙

    }

    };

    注意:蓝牙搜索过程 是没有帮我们过来重复搜索到蓝牙 ,如果想要把搜索结果放在集合返回,有可能一个设备会重复给搜索到,这个时候需要自己做个过滤,可通过bleDevice 的mac 地址不同进行过滤

    2. 连接蓝牙流程

    2.1 先理清 将会常操作的几个 类的概念 如下是它们的关系流程图

    BluetoothGatt:手机与BLE终端设备建立通信的一个管道,只有有了这个管道,之后的所有读写通知操作都是通过这个来操作

    BluetoothGattService:蓝牙设备的服务,每个BluetoothGatt有多个BluetoothGattService,在这里我们把BluetoothGattService比喻成班级。而Bluetoothdevice我们把它比喻成学校,一个学校里面可以有很多班级,也就是说我们每台BLE终端设备拥有多个服务,班级(各个服务)之间通过UUID(唯一标识符)区别

    BluetoothGattCharacteristic:蓝牙所拥有的特征 。每个BluetoothGattService有多个BluetoothGattCharacteristic。它是手机与BLE终端设备交换数据的关键,我们做的所有事情,目的就是为了得到它。在这里我们把它比喻成学生,一个班级里面有很多个学生,也就是说我们每个服务下拥有多个特征,学生(各个特征)之间通过UUID(唯一标识符)区别。

    理清了我们开始连接蓝牙

    2.2连接蓝牙

    搜索到蓝牙后 拿到蓝牙对象 BluetoothDevice device 调用如下方法

    参数:第一个参数是上下文对象,第二个参数是是否自动连接,这里设置为false,第三个参数就是上面的回调方法

    mBluetoothGatt = device.connectGatt(this, false,mGattCallback);

    mGattCallback的具体实现

    privateBluetoothGattCallbackmGattCallback=newBluetoothGattCallback() {

    //连接状态改变的回调

    @Override

    public voidonConnectionStateChange(BluetoothGatt gatt, intstatus,

    intnewState) {

    if(newState == BluetoothProfile.STATE_CONNECTED) {

    // 连接成功后 必须启调用 服务发现 (discoverServices)

    //调用后 当回调 onServicesDiscovered(BluetoothGatt gatt, int status)方法

    //才属于真正的成功连接

    mBluetoothGatt.discoverServices();

    }

    }

    //发现服务的回调

    public voidonServicesDiscovered(BluetoothGatt gatt, intstatus) {

    if(status == BluetoothGatt.GATT_SUCCESS) {

    Log.e(TAG,"成功发现服务");

    }else{

    Log.e(TAG,"服务发现失败,错误码为:"+ status);

    }

    if(status == BluetoothGatt.GATT_SUCCESS) {

    if(mBluetoothGatt !=null&& isServiceConnected) {

    BluetoothGattService gattService = mBluetoothGatt.getService(UUID_SERVICE);

    BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(UUID_NOTIFICATION);

    booleanb = mBluetoothGatt.setCharacteristicNotification(characteristic, true);

    if(b) {

    List descriptors = characteristic.getDescriptors();

    for(BluetoothGattDescriptor descriptor : descriptors) {

    booleanb1 = descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);

    if(b1) {

    mBluetoothGatt.writeDescriptor(descriptor);

    Log.d(TAG,"startRead: "+"监听收数据");

    }

    }

    }

    }

    }

    //写操作的回调

    public voidonCharacteristicWrite (BluetoothGatt gatt,BluetoothGattCharacteristic

    characteristic,intstatus){

    if(status == BluetoothGatt.GATT_SUCCESS) {

    Log.e(TAG,"写入成功"+ characteristic.getValue());

    }

    }

    //读操作的回调

    public voidonCharacteristicRead (BluetoothGatt gatt,BluetoothGattCharacteristic

    characteristic,intstatus){

    if(status == BluetoothGatt.GATT_SUCCESS) {

    Log.e(TAG,"读取成功"+ characteristic.getValue());

    }

    }

    //数据返回的回调(此处接收BLE设备返回数据)

    public voidonCharacteristicChanged (BluetoothGatt gatt,BluetoothGattCharacteristic

    characteristic){

    }

    }

    }

    当 回调  onServicesDiscovered(BluetoothGatt gatt, int status) 方法 后  就可以拿着    gatt(上文有解释概念) 进行 读写通知 操作了

    3 关于 读,写,通知,操作

     写数据

    public void startSend(View view) {

    if (mBluetoothGatt != null && isServiceConnected) {

    BluetoothGattService gattService = mBluetoothGatt.getService(UUID_SERVICE);

    BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(UUID_WRITE);

    byte[] bytes = new byte[2];

    bytes[0] = 04;

    bytes[1] = 01;

    characteristic.setValue(bytes);

    characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);

    mBluetoothGatt.writeCharacteristic(characteristic);

    }}

    写入成功会回调

    public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {

    if (status == BluetoothGatt.GATT_SUCCESS) {

    Log.e(TAG, "写入成功" +characteristic.getValue());

    }

    }

    读数据

    public void startSend(View view) {

    if (mBluetoothGatt != null && isServiceConnected) {

    BluetoothGattService gattService = mBluetoothGatt.getService(UUID_SERVICE);

    BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(UUID_WRITE);

    byte[] bytes = new byte[2];

    bytes[0] = 04;

    bytes[1] = 01;

    characteristic.setValue(bytes);

    mBluetoothGatt.readCharacteristic(characteristic);

    }

    }

    读取成功会回调

    //读操作的回调

    public voidonCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, intstatus) {

    if(status == BluetoothGatt.GATT_SUCCESS) {

    Log.e(TAG,"读取成功"+characteristic.getValue());

    }

    }

    注意: 在 读写操作过程  不可以 用for 一次性进行操作  会出现阻塞  需要 将读写操作 写入 队列中  一个一个写入  才是比较好的操作  也不会出现堵塞问题

      蓝牙的操作流程  就此结束    在此基础上  可以再次封装一层  代码就不出来了,一下是流程图

    相关文章

      网友评论

          本文标题:关于蓝牙ble开发相关知识

          本文链接:https://www.haomeiwen.com/subject/zcdwictx.html