BLE使用笔记
来源:互联网 发布:怎么卸载mac软件 编辑:程序博客网 时间:2024/06/05 16:42
一、BLE概述
Android4.3以上加入了BLE——低功耗蓝牙。
使用低功耗蓝牙可以包括多个Profile,一个Profile中有多个Service,一个Service中有多个Characteristic,一个Characteristic中包括一个value和多个Descriptor。
二、BLE的使用
1.权限
和经典蓝牙一样,应用使用蓝牙,需要声明BLUETOOTH权限,如果需要扫描设备或者操作蓝牙设置,则还需要BLUETOOTH_ADMIN权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
required为true时,则应用只能在支持BLE的Android设备上安装运行;required为false时,Android设备均可正常安装运行,需要在代码运行时判断设备是否支持BLE:
// 判断当前手机是否支持BLE
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); finish();}
2.使用步骤
2.1 初始化 BluetoothAdapter,用来判断设备是否支持蓝牙并打开蓝牙
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
finalBluetoothManager bluetoothManager =
(BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter= bluetoothManager.getAdapter();
// 判断是否支持蓝牙
if(mBluetoothAdapter==null) {
return false;
}
//打开蓝牙
if(!mBluetoothAdapter.isEnabled()) {
ILog.e("蓝牙未打开");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);}
2.2 扫描蓝牙设备
扫描指定UUID的设备,mLeScanCallback为扫描的回调接口
mBluetoothAdapter.startLeScan(UUID[],mLeScanCallback);
//回调接口
BluetoothAdapter.LeScanCallbackmLeScanCallback=newBluetoothAdapter.LeScanCallback() {
// 开始扫描和停止扫描都会调用此方法
@Override
public voidonLeScan(finalBluetoothDevice device,intrssi,byte[] scanRecord) {
//可通过对比当前扫描到的device的name与自己想查找到的设备name对比,来获取想连接的device信息
}
2.3 停止扫描
可以在扫描到自己需要的蓝牙后,停止扫描,注意:停止扫描和开始扫描的回调接口是同一个
mBluetoothAdapter.stopLeScan(mLeScanCallback);
2.4 连接设备
if(mBluetoothAdapter!=null) {
// 获取BluetoothGatt,连接设备,设为自动连接(即第二个参数为true),可能会存在问题,
mBluetoothGatt= device.connectGatt(context,false,BluetoothGattCallback callback);
//连接后的回调接口
BluetoothGattCallback callback=new BluetoothGattCallback() {
// 若连接状态发生改变
@Override
public void onConnectionStateChange(BluetoothGatt gatt,intstatus,intnewState) {
// status 表示相应的连接或断开操作是否完成,而不是指连接状态
if(newState == BluetoothProfile.STATE_CONNECTED) {
ILog.e("Connected to GATT server.");
}else if(newState == BluetoothProfile.STATE_DISCONNECTED) {
ILog.e("Disconnected from GATT server.");
}
@Override
public voidonServicesDiscovered(BluetoothGatt gatt,intstatus) {
Message msg = Message.obtain();
if(status == BluetoothGatt.GATT_SUCCESS) {
ILog.e("扫描到服务");
// 获取我们需要的服务
BluetoothGattService service =mBluetoothGatt.getService(SERVICE_UUID);
// 我需要得到的应该是一个特定的BluetoothGattCharacteristic,根据uuid获取
BluetoothGattCharacteristic mCharacteristic = service.getCharacteristic(CHARAC_READ_UUID);
}
// 接收到信息
@Override
public voidonCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
readInfo(characteristic);
}
//信息写入成功回调
@Override
public voidonCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,intstatus) {
if(status == BluetoothGatt.GATT_SUCCESS) {
ILog.e("回调:信息写入成功");
}else{
ILog.e("回调:信息写入失败");
}
2.5 连接到设备后的处理
1.获取指定服务及特征值:在连接设备的回调接口中有扫描到服务的方法,可以在此方法中获取指定的BluetoothGattService,并且可以在该服务中获取指定的BluetoothGattCharacteristic,如果需要开启notify功能(此功能可以不用主动轮询消息,而是被动接收设备发来消息)
// 给设备设置notifity功能
// 如果设备主动给手机发信息,则可以通过notification的方式,这种方式不用手机去轮询地读设备上的数据
mBluetoothGatt.setCharacteristicNotification(mCharacteristic,true);
BluetoothGattDescriptor descripter = mCharacteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
if(descripter !=null) {
descripter.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descripter);
}
2.读取消息:由于BLE是低功耗的,每次可传输的字节数为20,所以读取消息需要进行拼接,这就需要发送的内容加前后缀,来判断是否拼接成了完整的数据
3.发送消息:确定扫描到服务之后才能进行数据发送,并且需要分包发送,我是开启线程,在线程中进行数据的分包,将分包的数据加入队列中,并轮询队列,有数据就发送
/**
* BLE数据发送对象
*/
public class BleSenderextendsThread {
public static final intMAX_LENGTH=18;
private BlockingQueuedatas;
private BluetoothGattmBluetoothGatt;
private booleanisRunning;
private booleanisExit;
publicBleSender() {
isRunning=false;
}
public void init(BluetoothGatt mBluetoothGatt) {
clearAllData();
datas=new ArrayBlockingQueue(100);
this.mBluetoothGatt= mBluetoothGatt;
isExit=false;
if(!isRunning) {
start();
}
}
public void addData(BluetoothGattCharacteristic characteristic, String data) {
if(TextUtils.isEmpty(data))
return;
//分包
byte[] bytes = data.getBytes();
intlength = bytes.length;
intnumber = length %MAX_LENGTH==0? length /MAX_LENGTH: length /MAX_LENGTH+1;
for(inti =0; i < number; i++) {
byte[] range = Arrays.copyOfRange(bytes, i *18, i == number -1? length : (i +1) *MAX_LENGTH);
try{
// 将分包后的每个包的信息都填加到队列中
datas.put(newBLEData(characteristic, range));
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
private void sendData(BLEData data) {
BluetoothGattCharacteristic characteristic = data.characteristic;
byte[] bytes = data.data;
if(characteristic ==null|| bytes ==null)
return;
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
characteristic.setValue(bytes);
mBluetoothGatt.writeCharacteristic(characteristic);
}
public void clearAllData() {
if(datas!=null)
datas.clear();
}
@Override
public void run() {
super.run();
isRunning=true;
while(!isExit) {
try{
BLEData data =datas.take();
Thread.sleep(20);
sendData(data);
}catch(Exception e) {
e.printStackTrace();
}
public void stopSend() {
isExit=true;
}
- BLE使用笔记
- BLE学习笔记
- CC2540 BLE开发笔记
- Android BLE开发笔记
- android ble 开发笔记
- Android BLE学习笔记
- Android BLE学习笔记
- Android BLE学习笔记
- Android BLE学习笔记
- BLE:CC2540学习笔记
- ble连接参数笔记
- Android BLE学习笔记
- Android BLE学习笔记
- Android:使用BLE蓝牙
- Android 蓝牙BLE初学笔记
- 【笔记】蓝牙BLE开发记录
- BLE Link Layer学习笔记
- ble学习笔记八---------ble协议栈之简介
- 蓝桥杯2017模拟赛-排列序列
- selenium使用python的csv进行参数化时,中文乱码解决方案
- 基于静态分析的Android恶意软件检测
- 滚动选页+on事件触发
- 赚钱是给学习知识最好的回报
- BLE使用笔记
- Xcode创建framework工程
- Chrome Devtools之工作区
- 【RxJava】RxJava响应式带来的好处
- java 的耦合度,要高内聚,低耦合
- SQL DEFAULT 约束
- maven 多模块多Web应用合并War包
- Java 定时任务 与 Spring定时任务
- Vue。js学习系列(二十四)--条件语句(二)