Android BLE 蓝牙学习总结(一):手机作为周边BluetoothGattServer的实现
来源:互联网 发布:知错改错不认错的人 编辑:程序博客网 时间:2024/04/30 15:48
低功耗蓝牙的基本概念:
在BLE协议中,有两个角色,周边(Periphery)和中央(Central)。周边是数据的提供者,中央是数据的使用和处理者。在Android SDK里面,Android4.3以后手机可以作为中央使用;Android5.0以后手机才可以作为周边使用,即此时的手机可以作为BLE设备(如可穿戴设备、手环、智能锁、心率测量仪等)来为中央提供数据。
一个中央可以同时连接多个周边,但一个周边某一时刻只能连接一个中央。
Android BLE SDK的四个关键类如下:
1、BluetoothGattServer作为周边来提供数据,BluetoothGattServerCallback返回周边的状态,更通俗的说,当中央有请求时,系统调用该抽象类的相应方法传递数据给周边。
2、BluetoothGatt作为中央来使用和处理数据,BluetoohGattCallback返回中央的状态和周边提供数据,即周边反馈的数据通过该抽象类的相应方法传递到中央。
该篇文章主要总结手机作为周边的实现
一、创建一个周边所需的类,如下图
说明:每个周边BluetoothGattServer包含多个服务,每个服务包含多个特征,每个特征又可以包含多个描述
1、new一个描述:descriptor=new BluetoothGattDescriptor(UUID_DESCRIPTOR,
BluetoothGattCharacteristic.PERMISSION_WRITE);
2、new 一个特征:characteristicRead=new BluetoothGattCharacteristic(
UUID_CHARREAD,
BluetoothGattCharacteristic.PROPERTY_READ,
3、把描述添加到特征:characteristicRead.addDescriptor(descriptor);
4、new 一个服务: service=new BluetoothGattService(UUID_SERVER,
BluetoothGattService.SERVICE_TYPE_PRIMARY);
5、把特征添加到服务:service.addCharacteristic(characteristicWrite);
6、获取BluetoothManager:mBluetoothManager=(BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
7、获取周边:mBluetoothGattServer=mBluetoothManager.openGattServer(
context,bluetoothGattServerCallback);
8、把服务添加到周边: mBluetoothGattServer.addService(service);
9、将添加的服务广播出去,在本人实现的案例中,将initServices()在广播的回调方法中调用。
二、实现的程序讲解
手机作为外设:设置广播与服务主要涉及的类BluetoothLeAdvertiser与BluetoothGattServer
1、设置广播,主要操作是BluetoothLeAdvertiser
1.1、获取BluetoothLeAdvertiser实例:
private void initialize(){ if(mBluetoothLeAdvertiser==null){ mBluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE); if(mBluetoothManager!=null){ BluetoothAdapter bluetoothAdapter=mBluetoothManager.getAdapter(); if(bluetoothAdapter!=null){ mBluetoothLeAdvertiser=bluetoothAdapter.getBluetoothLeAdvertiser(); }else{ Toast.makeText(this,"设备不支持蓝牙广播",Toast.LENGTH_SHORT).show(); } }else{ Toast.makeText(this,"不支持蓝牙",Toast.LENGTH_SHORT).show(); } } }
1.2、开始广播,BluetoothLeAdvertiser.startAdvertising(settings,data,mAdvertiseCallback),开始广播之前需要准备三个参数
1) AdvertiseSettings:
private AdvertiseSettings buildAdvertiseSettings(){ AdvertiseSettings.Builder settingsBuilder=new AdvertiseSettings.Builder(); settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER); settingsBuilder.setTimeout(0); return settingsBuilder.build(); }
2)AdvertiseData
private AdvertiseData buildAdvertiseData(){ AdvertiseData.Builder dataBuilder=new AdvertiseData.Builder(); dataBuilder.setIncludeDeviceName(true); return dataBuilder.build(); }
3)mAdvertiseCallback=new SampleAdvertiseCallback,即广播成功或者失败的系统回调
private class SampleAdvertiseCallback extends AdvertiseCallback{ @Override public void onStartFailure(int errorCode){ super.onStartFailure(errorCode); Log.d(TAG,"广播失败"); sendFailureIntent(errorCode); stopSelf(); } @Override public void onStartSuccess(AdvertiseSettings settingsInEffect){ super.onStartSuccess(settingsInEffect); Log.d(TAG,"服务端的广播成功开启"); Log.d(TAG,"BLE服务的广播启动成功后:TxPowerLv="+settingsInEffect.getTxPowerLevel()+";mode="+settingsInEffect.getMode()+";timeout="+settingsInEffect.getTimeout()); initServices(getContext());//该方法是添加一个服务 }}
1.3、关闭广播
private void stopAdvertising(){ Log.d(TAG,"服务停止广播"); if(mBluetoothLeAdvertiser!=null){ mBluetoothLeAdvertiser.stopAdvertising(mAdertiseCallback); mAdertiseCallback=null; } }
2、设置服务,
2.1、首先先实现服务的回调:bluetoohtGattServerCallback,该实例将作为参数
//服务事件的回调private BluetoothGattServerCallback bluetoothGattServerCallback=new BluetoothGattServerCallback() { //1、首先是连接状态的回调 @Override public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { super.onConnectionStateChange(device, status, newState); Log.e(TAG,"连接状态发生改变,安卓系统回调onConnectionStateChange:device name="+device.getName()+"address="+device.getAddress()+"status="+status+"newstate="+newState); } @Override public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) { super.onCharacteristicReadRequest(device, requestId, offset, characteristic); Log.e(TAG,"客户端有读的请求,安卓系统回调该onCharacteristicReadRequest()方法"); mBluetoothGattServer.sendResponse(device,requestId, BluetoothGatt.GATT_SUCCESS,offset,characteristic.getValue()); } //接受具体字节,当有特征被写入时,回调该方法,写入的数据为参数中的value @Override public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value); Log.e(TAG,"客户端有写的请求,安卓系统回调该onCharacteristicWriteRequest()方法"); //特征被读取,在该回调方法中回复客户端响应成功 mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value); //处理响应内容 //value:客户端发送过来的数据 onResponseToClient(value,device,requestId,characteristic); } //特征被读取。当回复相应成功后,客户端胡读取然后触发本方法 @Override public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) { super.onDescriptorReadRequest(device, requestId, offset, descriptor); mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,null); } //2、其次,当有描述请求被写入时,回调该方法, @Override public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value); mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value); // onResponseToClient(value,device,requestId,descriptor.getCharacteristic()); } @Override public void onServiceAdded(int status,BluetoothGattService service){ super.onServiceAdded(status,service); Log.e(TAG,"添加服务成功,安卓系统回调该onServiceAdded()方法"); }};
2.2、获取BluetoothGattServer的实例
mBluetoothGattServer=mBluetoothManager.openGattServer(context,bluetoothGattServerCallback);
2.3、为设备添加服务:
//添加一个服务,该服务有一个读特征、该特征有一个描述;一个写特征。//用BluetoothGattServer添加服务,并实现该类的回调接口private void initServices(Context context){ mBluetoothGattServer=mBluetoothManager.openGattServer(context,bluetoothGattServerCallback); BluetoothGattService service=new BluetoothGattService(UUID_SERVER,BluetoothGattService.SERVICE_TYPE_PRIMARY); characteristicRead=new BluetoothGattCharacteristic(UUID_CHARREAD,BluetoothGattCharacteristic.PROPERTY_READ,BluetoothGattCharacteristic.PERMISSION_READ); BluetoothGattDescriptor descriptor=new BluetoothGattDescriptor(UUID_DESCRIPTOR,BluetoothGattCharacteristic.PERMISSION_WRITE); characteristicRead.addDescriptor(descriptor); service.addCharacteristic(characteristicRead); BluetoothGattCharacteristic characteristicWrite=new BluetoothGattCharacteristic(UUID_CHARWRITE, BluetoothGattCharacteristic.PROPERTY_WRITE |BluetoothGattCharacteristic.PROPERTY_READ|BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_WRITE); service.addCharacteristic(characteristicWrite); mBluetoothGattServer.addService(service); Log.d(TAG,"初始化服务成功:initServices ok");}
案例代码地址:https://github.com/lihongandroid/BleServer
- Android BLE 蓝牙学习总结(一):手机作为周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙学习总结(二):手机作为中央BluetoothGatt的实现
- Android BluetoothGatt和周边BluetoothGattServer的实现
- Android蓝牙开发教程:中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央和周边的实现
- Android BLE 蓝牙低功耗教程,中央和周边的实现
- Android BLE 蓝牙低功耗教程,中央和周边的实现
- Android BLE学习(二): Android与51822蓝牙模块通信流程的实现与分析
- Android BLE学习(二): Android与51822蓝牙模块通信流程的实现与分析
- org.apache.zookeeper.KeeperException$InvalidACLException: KeeperErrorCode = InvalidACL for /f
- 【Android】AndroidStudio2.2.3 切换到AndroidStudio3.0之后问题处理记录
- 对一致性hash算法的理解
- 数据库设计 Step by Step (3)——基本ER模型构件
- vi的命令
- Android BLE 蓝牙学习总结(一):手机作为周边BluetoothGattServer的实现
- 02_RxJava转换操作符代码示例
- 手把手交大家在mac上用VMWare虚拟机装win7
- os.x浏览器常用快捷键
- js-先判断是否是内网IP
- 移植u-boot-2012.04----支持nand启动
- 查找算法之哈希查找
- Android studio3.0 com.android.tools.aapt2.Aapt2Exception: AAPT2 error
- iptables导致linux关机错误的解决方法