Android开发——低功耗蓝牙通信BLE
1.前言
接着上一章传统蓝牙通信,现开发低功耗蓝牙通信,低功耗蓝牙相比于传统蓝牙有以下区别
1.传统蓝牙用于传输数据量大的(音乐),低功耗蓝牙用于传输量小的(手环)
2.低功耗蓝牙功耗低
。。。。。
多了Service还有Characteristic等
可以查看博客:https://blog.csdn.net/zqf_888/article/details/80982337
2.开发环境
华为p20 AndroidStudio 3.2 + 低功耗蓝牙设备
经过测试发现有的手机搜索蓝牙设备需要开启location权限,在华为上我的手机没有开启也可以进行搜索,另外还需要动态的允许权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.ACCESS_COARSE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},1);
}
3.搜索设备
和传统蓝牙一样,在搜寻设备的时候需要先查看自己的设备是否支持蓝牙,同时检测是否打开蓝牙,当二者都满足的时候再通过不同的方式搜索ble设备
adapter=BluetoothAdapter.getDefaultAdapter();//获取本地蓝牙设备
if(adapter!=null){
if(!adapter.isEnabled()){ //判断是否开启了蓝牙,如何未开启执行开启操作
Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(intent);
}
}else{
//不支持蓝牙
}
获取本地的蓝牙适配器有二种方法,我以上是使用BluetoothAdapter获取默认Adapter获取到的,下面这个使用BluetoothManager再获取到,二者是一样的,当我获取到adapter之后用她获取到BluetoothLeScanner对象,将会用她来对ble设备进行扫描(这是新的扫描方式,之前通过startLeScan()方法 已被弃用)
BluetoothManager bluetoothManager=(BluetoothManager)getSystemService(BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter=bluetoothManager.getAdapter();
BluetoothLeScanner bluetoothLeScanner=bluetoothAdapter.getBluetoothLeScanner();
扫描将调用BluetoothLeScanner对象的startScan()方法,但是此对象需要传入一个回调对象————ScanCallback,创建此回调对她进行改写,当扫描到设备时就会调用此回调函数种的OnScanResult函数,从而获取到Device
ScanCallback leCallback=new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device=result.getDevice();
//此处可以对device进行操作,如加入List中 用于显示再ListView中
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
Log.d(TAG, "搜索失败");
}
};
开始搜索
bluetoothLeScanner.startScan(leCallback);
4.连接设备
当搜索完设备后可显示在Listview中,通过点击相应的设备进行连接,同样首先要获取到此BluetoothDevice对象,调用其方法connectGatt(Context,autoConnect,BluetoothGattCallback) 参数一:Context 参数二: 是否自动连接 参数三:回调函数(用于返回连接状态,还有character等的变化) 回调函数改写里有数据的收发,因此写在发送和接收数据这一块
bluetoothGatt=bluetoothDevice.connectGatt(this,false,bluetoothGattCallback);
5.发现服务
连接上之后返回bluetoothGatt对象 可以通过此查看设备的所有服务,也可以根据指定ServiceUUID获取指定的服务
bluetoothGatt.getService(SERVICE_UUID);
bluetoothGatt.discoverServices();
6.发现Characteristic
通过获取到的BluetoothGattService对象就可以查看此服务下的所有Characteristic,也可以根据指定CharacteristicUUID获取指定的
BluetoothGattCharacteristic bluetoothGattCharacteristic=bluetoothGattService.getCharacteristic(CHARACTERISRIC_UUID);
以下UUID是我的设备的串口通信ServiceUUID还有CharacteristicUUID,如果只开发通信的话,只需连接之后返回Gatt,直接查询此Service下的Characteristic即可
private static final UUID SERVICE_UUID=UUID.fromString("0000FFE0-0000-1000-8000-00805F9B34FB");
private static final UUID CHARACTERISRIC_UUID=UUID.fromString("0000FFE1-0000-1000-8000-00805F9B34FB");
7.发送数据
发送数据其实就相当于找到此Characteristic 然后对她进行写的操作
bluetoothGattCharacteristic.setValue(message);
bluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic);
8.接收数据
记得刚才上面定义的bluetoothGattCallback 回调函数吗,现在对她进行改写,其中改写的函数就有一个是当串口发送数据过来时会调用的函数,在此函数中就可以获取到串口中发送过来的数据了
BluetoothGattCallback bluetoothGattCallback=new BluetoothGattCallback() {
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if(status==BluetoothGatt.GATT_SUCCESS){
//此处会在我们发送成功后调用,可以在此显示发送成功之类的操作
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
byte[] arrayOfByte = characteristic.getValue();
//此处就是当串口发送数据过来时会调用的函数,arragyOfbyte就是数据,对其进行转成String就可以显示
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if(status==BluetoothGatt.GATT_SUCCESS && (bluetoothGatt.getService(SERVICE_UUID)!=null)){
//此处就是我们指定的串口通信的服务被发现的时候,
}else {
//没有发现此服务
}
}
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if(status==BluetoothGatt.GATT_SUCCESS){
if(newState==BluetoothProfile.STATE_CONNECTED){
//此处用于写连接成功之后的操作
}else if(newState==BluetoothProfile.STATE_DISCONNECTED){
//连接失败后的操作
}
}
}
};
上一篇: 对 onreadystatechange 属性的理解
下一篇: CSS3的动画效果