Android BLE虚拟设备端
来源:互联网 发布:药智网数据库 编辑:程序博客网 时间:2024/06/17 17:19
简介
Android5.0以上的系统可以作为在BLE通信中的设备端,能够开启服务接收其他手机发送来的数据。
大致的通信过程如下:
打开蓝牙–添加服务和特征值–发送广播数据。
其他手机接收到广播数据之后,便可以从中读取出服务和特征值,如果特征值可写,那么便可以往特征值里面写数据,设备端便可以接收到数据。
以下是我自己写的一个demo,增加了服务CONFIG_SERVICE和特征值CONFIG_CHARACTER,其他设备搜寻到CONFIG_CHARACTER特征值,便可以往里面写数据。
源码地址:http://download.csdn.net/detail/hbdatouerzi/9894632
开发步骤
1.初始化
这一步主要是初始化mBluetoothManager、mBluetoothAdapter和mBluetoothAdvertiser,其中mBluetoothManager和mBluetoothAdapter获取蓝牙服务,打开和关闭蓝牙等;mBluetoothAdvertiser用于发送广播。
//初始化 public boolean init(){ String str = "设备不支持蓝牙低功耗通讯"; if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { LogUtil.getInstance().ilog(tag,str); return false; } mBluetoothManager = (BluetoothManager) context.getSystemService(BLUETOOTH_SERVICE); if (mBluetoothManager == null) { LogUtil.getInstance().ilog(tag,str); return false; } mBluetoothAdapter = mBluetoothManager.getAdapter(); if(mBluetoothAdapter == null){ LogUtil.getInstance().ilog(tag,str); return false; } mBluetoothAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser(); if (mBluetoothAdvertiser == null) { LogUtil.getInstance().ilog(tag,str); return false; } //打开蓝牙的套路 if ((mBluetoothAdapter == null) || (!mBluetoothAdapter.isEnabled())) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); context.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } return true; }
2.设置特征值读写的回调
//连接、读写的回调public class BluetoothCallBack extends BluetoothGattServerCallback{ private String TAG = "BluetoothCallBack"; private WifiviewI wifiview; private ResponseI response; private StringBuilder reciveStr;//收到的数据 private int byteCount;//收到信息的条数 public BluetoothCallBack(WifiviewI wifiview){ this.wifiview = wifiview; reciveStr = new StringBuilder(); } public void setResponse(ResponseI response){ this.response = response; } //添加一个服务之后的回调 public void onServiceAdded(int status, BluetoothGattService service) { if (status == BluetoothGatt.GATT_SUCCESS) { LogUtil.getInstance().ilog(TAG,"添加服务成功!服务的uuid为"+service.getUuid().toString()); } else { LogUtil.getInstance().ilog(TAG, "添加服务失败!"); } } //连接状态改变之后的回调 public void onConnectionStateChange(android.bluetooth.BluetoothDevice device, int status, int newState) { LogUtil.getInstance().ilog(TAG, "连接状态为" + newState); } //当客户端来读数据时的回调 public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) { LogUtil.getInstance().ilog(TAG, "客户端来读取数据"); } //当有客户端来写数据时回调的回调 @Override public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { final String str = new String(value); LogUtil.getInstance().ilog(TAG, "客户端来写数据,写的数据为"+str); if(response != null){ response.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, null); } }}
3.添加服务和特征值
构造CONFIG_SERVICE和CONFIG_CHARACTER,并设置CONFIG_CHARACTER为可读可写,其中UUID应当事先约定好,这样手机端便可以知道哪个UUID是CONFIG_CHARACTER。
if(mGattServer == null) { mGattServer = mBluetoothManager.openGattServer(context, callBack);//callback对特征值进行数据读写时的回调 } //构造服务和特征值BluetoothGattService testService = new BluetoothGattService(UUID.fromString(Attributes.CONFIG_SERVICE_UUID), BluetoothGattService.SERVICE_TYPE_PRIMARY);//设置特征值可读可写BluetoothGattCharacteristic fcharacter = new BluetoothGattCharacteristic(UUID.fromString(Attributes.CONFIG_CHARACTER_UUID), BluetoothGattCharacteristic.PROPERTY_READ |BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_NOTIFY , BluetoothGattCharacteristic.PERMISSION_READ |BluetoothGattCharacteristic.PERMISSION_WRITE); fcharacter.setValue("first");testService.addCharacteristic(fcharacter);//添加服务if(mGattServer!=null && testService!=null) mGattServer.addService(testService);
4.设定发送广播的回调
发送广播的回调有两个函数,发送成功和发送失败
private AdvertiseCallback adCallBack = new AdvertiseCallback() { @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) { super.onStartSuccess(settingsInEffect); LogUtil.getInstance().ilog(tag,"广告回调 onStartSuccess"); } @Override public void onStartFailure(int errorCode) { super.onStartFailure(errorCode); LogUtil.getInstance().ilog(tag,"广告回调 onStartFailure"); } };
5.发送广播
adCallBack是发送广播的回调。
try{ mBluetoothAdvertiser.startAdvertising(createAdvSettings(true, 0), createFMPAdvertiseData(),adCallBack); }catch(Exception e){ e.printStackTrace(); LogUtil.getInstance().ilog(tag,"发送广告出现异常"+e); }
createAdvSettings为广告设置,createFMPAdvertiseData为广告数据
public AdvertiseSettings createAdvSettings(boolean connectable, int timeoutMillis) { AdvertiseSettings.Builder builder = new AdvertiseSettings.Builder(); //设置广播的模式,应该是跟功耗相关 builder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED); builder.setConnectable(connectable); builder.setTimeout(timeoutMillis); builder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH); return builder.build(); } //设置一下FMP广播数据 public AdvertiseData createFMPAdvertiseData() { AdvertiseData.Builder builder = new AdvertiseData.Builder(); builder.setIncludeDeviceName(true); AdvertiseData adv = builder.build(); return adv; }
这样手机端便可以扫描到设备,连接设备并发现设备的服务和特征值,如果特征值可写,便可以写数据,设备通过回调函数可以收取到写来的数据。
6.停止发送
停止发送广播,关闭服务
if (mBluetoothAdvertiser != null) { mBluetoothAdvertiser.stopAdvertising(adCallBack); mBluetoothAdvertiser = null; } if(mBluetoothAdapter != null){ mBluetoothAdapter = null; } if (mGattServer != null) { mGattServer.clearServices(); mGattServer.close(); mGattServer = null; } LogUtil.getInstance().ilog(tag,"结束服务成功");
总结
BLE连接方式相对于经典蓝牙的连接方式来说,BLE不需要配对,直接通过服务特征值的方式,便可以进行数据的传输,弄明白了它的连接流程和工作方式之后,其实编程也是很简单的。另外设备端需要获取以下权限,不要忘了添加。
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
- Android BLE虚拟设备端
- Android BLE设备扫描
- android 蓝牙ble设备开发
- Android BLE学习(一): Android搜索BLE设备
- Android BLE学习(一): Android搜索BLE设备
- android 6.0 不能搜索Ble设备
- Android智能设备蓝牙连接(BLE)
- Android BLE设备蓝牙通信框架BluetoothKit
- android 6.0 不能搜索Ble设备
- 关于android读取BLE设备信息
- Android BLE控制端
- android 虚拟设备的用法
- android蓝牙--不支持ble设备的旧api
- android蓝牙--不支持ble设备的旧api
- Android手机与多个BLE设备通信
- 关于Android蓝牙4.0Ble设备开发技术点
- Android手机与多个BLE设备通信
- Android 6.0 扫描不到 Ble 设备需开启位置权限
- jzoj 3928_射击_堆
- web配置文件属性metadata-complete讲解
- 欢迎使用CSDN-markdown编辑器
- Android Library工程switch case中使用 R.id.x报错
- 百度APi
- Android BLE虚拟设备端
- light oj 1341 Aladdin and the Flying Carpet
- 2017西安交大ACM小学期 美妙音乐[差分KMP匹配]
- 布谷鸟算法(cuckoo_search)可能会遇到的问题
- 为什么要使用CMake+VS编译OpenCV的源码
- Qt 常用类 —— QFont
- POJ1724
- JZOJ 3929. 【NOIP2014模拟11.6】创世纪
- 排序算法——直接选择排序