Android Bluetooth Low Energy学习笔记.docx
- 文档编号:23368993
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:14
- 大小:20.25KB
Android Bluetooth Low Energy学习笔记.docx
《Android Bluetooth Low Energy学习笔记.docx》由会员分享,可在线阅读,更多相关《Android Bluetooth Low Energy学习笔记.docx(14页珍藏版)》请在冰豆网上搜索。
AndroidBluetoothLowEnergy学习笔记
BluetoothLowEnergy(Android)
Android4.3(APILevel18)平台支持蓝牙低功耗,并提供了APIs,apps可以使用这些函数发现设备,服务,读写特征值。
对比经典蓝牙,蓝牙低功耗的设计显著降低了功耗。
平台允许Androidapps与一些有低功耗需求的BLE设备实现通讯,比如防丢器传感器,心率监测仪,健身设备等等。
1、角色和职责(RolesandResponsibilities)
以下是Android设备与BLE设备通讯时的角色和职责:
1.Central和Peripheral。
举例BLE连接,中心设备扫描,发现广播,周边设备发射广播。
2.GATTserver和GATTclient。
这决定了两个设备建立连接后怎样进行通讯。
本文以HeartRateProfile举例说明。
2、BT声明
1.在APP源程序manifest 文件中,进行Bluetoothpermissions:
(manifest.xml文件的Permissions标签页添加usespermission)
name="android.permission.BLUETOOTH"/> name="android.permission.BLUETOOTH_ADMIN"/> 2.如果想让APP只有BLE-capabledevices可用,在manifest中加入: (manifest.xml文件的mainifest标签页添加usesfeature) name="android.hardware.bluetooth_le"android: required="true"/> 3.如果想让APP不支持BLE,也可以包含这个feature,但是required=false,在运行时想用BLE,则使用 PackageManager.hasSystemFeature() 3、建立BLE连接 如果设备支持BLE,但是处于disable状态,可以通过以下两个步骤在不离开应用的情况下,请求用户enableBluetooth: 1.Getthe BluetoothAdapter BluetoothAdapter对于所有蓝牙活动都是必须的。 它是针对整个系统的,整个系统有一个BluetoothAdapte,应用程序可以使用这个对象进行交互。 //InitializesBluetoothadapter. finalBluetoothManagerbluetoothManager= (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter=bluetoothManager.getAdapter(); 2.EnableBluetooth 下一步需要确保蓝牙enable,通过调用isEnabled()检查当前蓝牙是否enabled。 返回false,蓝牙disabled。 下面的代码是check蓝牙是否enabled,如果没有,则通过显示错误提示,让用户去设置启用蓝牙: privateBluetoothAdaptermBluetoothAdapter; ... //EnsuresBluetoothisavailableonthedeviceanditisenabled.Ifnot, //displaysadialogrequestinguserpermissiontoenableBluetooth. if(mBluetoothAdapter==null||! mBluetoothAdapter.isEnabled()){ IntentenableBtIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT); } 4、发现BLE设备 发现BLE设备,可以使用startLeScan()方法,这个方法有一个参数: BluetoothAdapter.LeScanCallback,必须实现这个回调,这个方法会返回扫描结果。 另外,由于扫描会耗电,所以必须遵循以下两条原则: (1)一旦找到需要的设备,马上停止扫描; (2)不要在循环中设置扫描,在扫描中设置一个时间限制 举例扫描和停止扫描: /** *ActivityforscanninganddisplayingavailableBLEdevices. */ publicclassDeviceScanActivityextendsListActivity{ privateBluetoothAdaptermBluetoothAdapter; privatebooleanmScanning; privateHandlermHandler; //Stopsscanningafter10seconds. privatestaticfinallongSCAN_PERIOD=10000; ... privatevoidscanLeDevice(finalbooleanenable){ if(enable){ //Stopsscanningafterapre-definedscanperiod. mHandler.postDelayed(newRunnable(){ @Override publicvoidrun(){ mScanning=false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } },SCAN_PERIOD); mScanning=true; mBluetoothAdapter.startLeScan(mLeScanCallback); }else{ mScanning=false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } ... } ... } 如果想扫描仅针对特定类型的外围设备,可以改为调用startLeScan(UUID[],BluetoothAdapter.LeScanCallback),提供指定的UUID对象数组,服务应用程序。 以下是BluetoothAdapter.LeScanCallback,用来提供BLE扫描结果的接口的实现: privateLeDeviceListAdaptermLeDeviceListAdapter; ... //Devicescancallback. privateBluetoothAdapter.LeScanCallbackmLeScanCallback= newBluetoothAdapter.LeScanCallback(){ @Override publicvoidonLeScan(finalBluetoothDevicedevice,intrssi, byte[]scanRecord){ runOnUiThread(newRunnable(){ @Override publicvoidrun(){ mLeDeviceListAdapter.addDevice(device); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } }; 注意: 只能扫描BLE设备或只扫描经典蓝牙设备。 不能同一时间既扫描BLE又扫描经典设备。 5、连接到GATTServer 第一步与BLEdevice互动就是与它建立连接,更具体的说,就是连接到设备的GATTServer。 去连接一个在BLEdevice上的GATTServer,需要使用connectGatt()方法,这个方法包含三个参数: (1)一个Context对象, (2)autoConnect(boolean,表示当蓝牙可用时是否自动连接BLE设备),(3)一个BluetoothGattCallback mBluetoothGatt=device.connectGatt(this,false,mGattCallback); 连接到BLEdevice的GATTserver后,会返回一个BluetoothGatt实例,你可以通过这个实例执行GATTclient操作。 安卓APP就是GATTclient。 BluetoothGattCallback用于传递结果到client,比如连接状态等其他GATTclient操作。 下面这个例子中,BLEApp举例连接,显示数据,显示设备支持的GATTservices和characteristics。 基于用户输入,通过调用BluetoothLeService与一个Service进行通讯,这也是通过AndroidBLEAPI与BLEdevice进行互动: //AservicethatinteractswiththeBLEdeviceviatheAndroidBLEAPI. publicclassBluetoothLeServiceextendsService{ privatefinalstaticStringTAG=BluetoothLeService.class.getSimpleName(); privateBluetoothManagermBluetoothManager; privateBluetoothAdaptermBluetoothAdapter; privateStringmBluetoothDeviceAddress; privateBluetoothGattmBluetoothGatt; privateintmConnectionState=STATE_DISCONNECTED; privatestaticfinalintSTATE_DISCONNECTED=0; privatestaticfinalintSTATE_CONNECTING=1; privatestaticfinalintSTATE_CONNECTED=2; publicfinalstaticStringACTION_GATT_CONNECTED= "com.example.bluetooth.le.ACTION_GATT_CONNECTED"; publicfinalstaticStringACTION_GATT_DISCONNECTED= "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED"; publicfinalstaticStringACTION_GATT_SERVICES_DISCOVERED= "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED"; publicfinalstaticStringACTION_DATA_AVAILABLE= "com.example.bluetooth.le.ACTION_DATA_AVAILABLE"; publicfinalstaticStringEXTRA_DATA= "com.example.bluetooth.le.EXTRA_DATA"; publicfinalstaticUUIDUUID_HEART_RATE_MEASUREMENT= UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT); //VariouscallbackmethodsdefinedbytheBLEAPI. privatefinalBluetoothGattCallbackmGattCallback= newBluetoothGattCallback(){ @Override publicvoidonConnectionStateChange(BluetoothGattgatt,intstatus, intnewState){ StringintentAction; if(newState==BluetoothProfile.STATE_CONNECTED){ intentAction=ACTION_GATT_CONNECTED; mConnectionState=STATE_CONNECTED; broadcastUpdate(intentAction); Log.i(TAG,"ConnectedtoGATTserver."); Log.i(TAG,"Attemptingtostartservicediscovery: "+ mBluetoothGatt.discoverServices()); }elseif(newState==BluetoothProfile.STATE_DISCONNECTED){ intentAction=ACTION_GATT_DISCONNECTED; mConnectionState=STATE_DISCONNECTED; Log.i(TAG,"DisconnectedfromGATTserver."); broadcastUpdate(intentAction); } } @Override //Newservicesdiscovered publicvoidonServicesDiscovered(BluetoothGattgatt,intstatus){ if(status==BluetoothGatt.GATT_SUCCESS){ broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); }else{ Log.w(TAG,"onServicesDiscoveredreceived: "+status); } } @Override //Resultofacharacteristicreadoperation publicvoidonCharacteristicRead(BluetoothGattgatt, BluetoothGattCharacteristiccharacteristic, intstatus){ if(status==BluetoothGatt.GATT_SUCCESS){ broadcastUpdate(ACTION_DATA_AVAILABLE,characteristic); } } ... }; ... } 当一个特定的回调函数被触发,它要调用合适的辅助方法broadcastUpdate()。 注意,这部分的数据解析按照蓝牙心率测量ProfileSpec执行: privatevoidbroadcastUpdate(finalStringaction){ finalIntentintent=newIntent(action); sendBroadcast(intent); } privatevoidbroadcastUpdate(finalStringaction, finalBluetoothGattCharacteristiccharacteristic){ finalIntentintent=newIntent(action); //ThisisspecialhandlingfortheHeartRateMeasurementprofile.Data //parsingiscarriedoutasperprofilespecifications. if(UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())){ intflag=characteristic.getProperties(); intformat=-1; if((flag&0x01)! =0){ format=BluetoothGattCharacteristic.FORMAT_UINT16; Log.d(TAG,"HeartrateformatUINT16."); }else{ format=BluetoothGattCharacteristic.FORMAT_UINT8; Log.d(TAG,"HeartrateformatUINT8."); } finalintheartRate=characteristic.getIntValue(format,1); Log.d(TAG,String.format("Receivedheartrate: %d",heartRate)); intent.putExtra(EXTRA_DATA,String.valueOf(heartRate)); }else{ //Forallotherprofiles,writesthedataformattedinHEX. finalbyte[]data=characteristic.getValue(); if(data! =null&&data.length>0){ finalStringBuilderstringBuilder=newStringBuilder(data.length); for(bytebyteChar: data) stringBuilder.append(String.format("%02X",byteChar)); intent.putExtra(EXTRA_DATA,newString(data)+"\n"+ stringBuilder.toString()); } } sendBroadcast(intent); } 回到DeviceControlActivity,这些事件是由一个BroadcastReceiver处理: //HandlesvariouseventsfiredbytheService. //ACTION_GATT_CONNECTED: connectedtoaGATTserver. //ACTION_GATT_DISCONNECTED: disconnectedfromaGATTserver. //ACTION_GATT_SERVICES_DISCOVERED: discoveredGATTservices. //ACTION_DATA_AVAILABLE: receiveddatafromthedevice.Thiscanbea //resultofreadornotificationoperations. privatefinalBroadcastReceivermGattUpdateReceiver=newBroadcastReceiver(){ @Override publicvoidonReceive(Contextcontext,Intentintent){ finalStringaction=intent.getAction(); if(BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)){ mConnected=true; updateConnectionState(R.string.connected); invalidateOptionsMenu(); }elseif(BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)){ mConnected=false; updateConnectionState(R.string.disconnected); invalidateOptionsMenu(); clearUI(); }elseif(BluetoothLeService. ACTION_GATT_SERVICES_DISCOVERED.equals(action)){ //Showallthesupportedservicesandcharacteristicsonthe //userinterface. displayGattServices(mBluetoothLeService.getSupportedGattServices()); }elseif(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)){ displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA)); } } }; 6、读取BLE属性 一旦AndroidApp连接到了一个GATTserver,同时发现的了services,它可以读取和写入支持的属性。 例如,这段代码循环访问server的services和characteristics,并将它们显示在UI上: publicclassDev
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Bluetooth Low Energy学习笔记 Energy 学习 笔记