Ble

本文围绕Android BLE蓝牙开发展开,详细讲解原生API,包括蓝牙开发流程、主要类的理解及方法对应关系,还推荐了github上的蓝牙优秀库,最后提及ble开发注意事项,如处理粘包丢包、更改mtu大小等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

官方手册:翻墙查看,点击直达

传统蓝牙(对比):https://www.yiibai.com/android/android_bluetooth.html

GATT协议参考:https://blog.youkuaiyun.com/weixin_37730482/article/details/77187866

一、原生API的详细讲解

在BLE协议中,有两个角色,周边(Periphery)和中央(Central);周边是数据提供者,中央是数据使用/处理者,一个中央可以同时连接多个周边,但是一个周边某一时刻只能连接一个中央。
首先使用蓝牙就不得不说BluetoothGatt和BluetoothGattCallback这两个类,该类继承自BluetoothProfile,BluetoothGatt作为中央来使用和处理数据,通过BluetoothGatt可以连接设备(connect),发现服务(discoverServices),并把相应地属性返回到BluetoothGattCallback,BluetoothGattCallback返回中央的状态和周边提供的数据。

1. 蓝牙开发流程:

我们蓝牙操作的主要目的就是为了拿到中央BluetoothGatt这个对象,进而进行接下来的所有一系列操作,如下:

1.先拿到BluetoothManager bluetoothManager 
        = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

2.再拿到BluetoothAdapt btAdapter = bluetoothManager.getAdapter();

3.开始扫描:btAdapter.startLeScan( BluetoothAdapter.LeScanCallback);

4.从LeScanCallback中得到BluetoothDevice 
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {…..}

5.用BluetoothDevice得到BluetoothGatt:gatt = device.connectGatt(this, true, gattCallback);

这时总算拿到中央BluetoothGatt了,它有很多的方法,调用这些方法,你就可以通过BluetoothGattCallback和周边BluetoothGattServer交互了。

2. 主要类的大致理解:

  • BluetoothProfile: 一个通用的规范,按照这个规范来收发数据。

  • BluetoothManager:通过BluetoothManager来获取BluetoothAdapter

    如:BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    
  • BluetoothAdapter:一个Android系统只有一个BluetoothAdapter ,通过BluetoothManager 获取

    BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
    
  • BluetoothGattDescriptor:可以看成是描述符,对Characteristic的描述,包括范围、计量单位等。

  • BluetoothGattService:服务,Characteristic的集合。

  • BluetoothGattCallback:已经连接上设备,对设备的某些操作后返回的结果。这里必须提醒下,已经连接上设备后的才可以返回,没有返回的认真看看有没有连接上设备。

    private BluetoothGattCallback GattCallback = new BluetoothGattCallback() {
    
      // 这里有9个要实现的方法,看情况要实现那些,用到那些就实现那些
    
      public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState){};
    
      public void onCharacteristicWrite(BluetoothGatt gatt, 
                          BluetoothGattCharacteristic characteristic, int status){
    
                          };            
    
              };
     BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    
     BluetoothGatt gatt = device.connectGatt(this, false, mGattCallback);
    

3. 上面所说的9个要实现的方法,所对应蓝牙交互的主要对应关系:

(1) notification对应onCharacteristicChanged;

gatt.setCharacteristicNotification(characteristic, true);

该方法一般是在发现服务后,进行设置的,设置该方法的目的是让硬件在数据改变的时候,发送数据给app,app则通过onCharacteristicChanged方法回调给用户,从参数中可获取到回调回来的数据。

(2) readCharacteristic对应onCharacteristicRead;

gatt.readCharacteristic(characteristic);

(3) writeCharacteristic对应onCharacteristicWrite;

gatt.wirteCharacteristic(mCurrentcharacteristic);

(4) 连接蓝牙或者断开蓝牙 对应 onConnectionStateChange;

bluetoothDevice.connectGatt(this, false, mGattCallback);
或
gatt.disconnect();(断开连接后务必记得gatt.close();)

(5) readDescriptor对应onDescriptorRead;

gatt.readDescriptor(descriptor);

(6) writeDescriptor对应onDescriptorWrite;

gatt.writeDescriptor(descriptor);

(7) readRemoteRssi对应onReadRemoteRssi;

gatt.readRemoteRssi();

(8) executeReliableWrite对应onReliableWriteCompleted;

 gatt.executeReliableWrite();

(9) discoverServices对应onServicesDiscovered

gatt.discoverServices();

开启蓝牙所具备的权限:

 <uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

如果 android.hardware.bluetooth_le设置为false,可以安装在不支持的设备上使用,判断是否支持蓝牙4.0用以下代码就可以了,如:

  if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
          Toast.makeText(this, “设备不支持蓝牙4.0”, Toast.LENGTH_SHORT).show();
          finish();
    }

对蓝牙的启动关闭操作:

1、利用系统默认开启蓝牙对话框

if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
  }

2、后台打开蓝牙,不做任何提示,这个也可以用来自定义打开蓝牙对话框啦

mBluetoothAdapter.enable();

3、后台关闭蓝牙

mBluetoothAdapter.disable();

二、github蓝牙优秀库推荐

1.github: https://github.com/xiaoyaoyou1212/BLE

2.github:https://github.com/dingjikerbo/BluetoothKit

(可以加上这个项目下的qq群,里面有大神,可以请教探讨)

三、ble开发注意事项

在android中,BLE的特征一次读写最大长度20字节。对于长时间连续发送的大于20字节的帧结构,如果安卓终端进行接收的话,就需要我们进行重新组帧(即如何处理粘包和丢包问题)。

请参考该文 https://blog.youkuaiyun.com/andyzhu_2005/article/details/78816142

实际项目中,由于蓝牙模块需要手机传输升级文件,文件被分成若干包发送,比如以64字节为一段,再加上杂七杂八的一些校验位、结束符等等,包长已经远大于默认mtu所规定的20字节,就需要再分成若干份20字节段发送,由于每段数据有没有序号位,导致在传输过程中出现客户端(蓝牙模块)丢包现象,为了避免这种情况的发生,我们应该更改mtu大小,使mtu大于协议中规定的单帧数据的长度,可参考下文更改mtu大小https://blog.youkuaiyun.com/huariylee/article/details/52758254?locationNum=8

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值