安卓低功耗蓝牙BLE开发--客户端
低功耗蓝牙 BLE 客户端篇
最近忙着折腾智能手表Android Wear2.0的开发,由于国内用不了play服务,所以谷歌为wear提供的一套和手机通信的API都不能用。为了在手机和手表之间传递数据,我不得不考虑使用蓝牙来建立手机和手表之间的通讯。在这个过程中被坑了许多次,所以记录下来方便自己查阅。
(PS: 国内有的教程使用的API以被弃用,许多东西是我自己看着官方文档总结出来的,如有不对的地方请帮我指出来。)
1.准备工作
工欲善其事,必先利其器。Android Wear2.0时的目标SDK版本已经在23以上了,安卓在6.0的时候加入了运行时权限系统,所以想开发蓝牙客户端的第一步,就是拿到应用所需要的必要权限。
需要的权限如下:
- android.permission.BLUETOOTH
- android.permission.BLUETOOTH_ADMIN
- android.permission.ACCESS_COARSE_LOCATION
对于前两个权限,比较好理解,一个用于连接蓝牙设备,一个用于搜索蓝牙设备。可是这最后一个模糊地理位置权限是什么鬼?原来谷歌认为扫描周围蓝牙4.0设备可以获取用户的大概位置,所以要求开发者申请模糊位置权限。没有这个权限的话虽然能正常开始扫描蓝牙BLE设备,但是一个结果都不会返回,一点儿用都没有。
首先在AndroidManifest.xml之中声明权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
接着,需要在运行时申请权限:
//首先判断是否是安卓6.0以上,然后申请权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
this.requestPermissions(new String[]{
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH,
Manifest.permission.ACCESS_COARSE_LOCATION
},0);
}
之后在onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults) 回调方法中确认用户是否同意了权限。
2.查找蓝牙BLE设备
查找蓝牙设备要用到这样几个类:
- BluetoothManager 蓝牙管理器
- BluetoothAdapter 这个是我们本机的蓝牙设备
- BluetoothLeScanner 低功耗蓝牙BLE扫描器
- ScanCallback 扫描器需要使用的回调
基本过程就是,首先获取BluetoothManager,然后通过BluetoothManager获取到BluetoothAdapter,BluetoothAdapter获取到BluetoothLeScanner,用BluetoothLeScanner来注册回调并扫描蓝牙BLE设备。
BluetoothManager bm = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
BluetoothAdapter adapter = bm.getAdapter();
BluetoothLeScanner scanner = adapter.getBluetoothLeScanner();
scanner.startScan(scanCallback); //scanCallback是回调
如此便开始了扫描进程。接下来扫描的结果,会通过ScanCallback里面的
onScanResult(int callbackType, ScanResult result)方法返回,
result.getDevice()方法可以返回扫描到的蓝牙设备BluetoothDevice对象,这个就是我们下一步连接用的必要对象。
3.连接蓝牙BLE设备
连接蓝牙设备要用到这样几个类:
- BluetoothDevice 蓝牙设备
- BluetoothGatt 手机和蓝牙设备连接的“通道”
- BluetoothGattCallback 和蓝牙设备通讯的回调,收发数据相关的代码都在这里实现
连接蓝牙BLE设备就比较容易了:
bluetoothDevice.connectGatt(this,false,gattCallback);
接着在gattCallback里面重写
onConnectionStateChange(BluetoothGatt gatt, int status, int newState)方法
判断当连接成功时,就可以保存gatt引用,使用方法传入的gatt对象和蓝牙BLE设备通讯了。
不过这里有个坑,gattCallback里面的回调并不是运行在主线程上面的,也就是说在回调之中不能直接操作UI对象,需要通知主线程来更改UI。
评论已关闭