赞
踩
Android 4.3(API Level 18)开始引入Bluetooth Low Energy(BLE,低功耗蓝牙)的核心功能并提供了相应的 API, 应用程序通过这些 API 扫描蓝牙设备、查询 services、读写设备的 characteristics(属性特征)等操作。
Android BLE 使用的蓝牙协议是 GATT 协议,有关该协议的详细内容可以参见蓝牙官方文档。以下我引用一张官网的图来大概说明 Android 开发中我们需要了解的一些 Bluetooth Low Energy 的专业术语。
一个低功耗蓝牙设备可以定义许多 Service, Service 可以理解为一个功能的集合。设备中每一个不同的 Service 都有一个 128 bit 的 UUID 作为这个 Service 的独立标志。蓝牙核心规范制定了两种不同的UUID,一种是基本的UUID,一种是代替基本UUID的16位UUID。所有的蓝牙技术联盟定义UUID共用了一个基本的UUID:
0x0000xxxx-0000-1000-8000-00805F9B34FB
为了进一步简化基本UUID,每一个蓝牙技术联盟定义的属性有一个唯一的16位UUID,以代替上面的基本UUID的‘x’部分。例如,心率测量特性使用0X2A37作为它的16位UUID,因此它完整的128位UUID为:
0x00002A37-0000-1000-8000-00805F9B34FB
在 Service 下面,又包括了许多的独立数据项,我们把这些独立的数据项称作 Characteristic。同样的,每一个 Characteristic 也有一个唯一的 UUID 作为标识符。在 Android 开发中,建立蓝牙连接后,我们说的通过蓝牙发送数据给外围设备就是往这些 Characteristic 中的 Value 字段写入数据;外围设备发送数据给手机就是监听这些 Charateristic 中的 Value 字段有没有变化,如果发生了变化,手机的 BLE API 就会收到一个监听的回调。
更详细的内容可以参见:
BluetoothAdapter
BluetoothAdapter 拥有基本的蓝牙操作,例如开启蓝牙扫描,使用已知的 MAC 地址 (BluetoothAdapter#getRemoteDevice)实例化一个 BluetoothDevice 用于连接蓝牙设备的操作等等。
BluetoothDevice
代表一个远程蓝牙设备。这个类可以让你连接所代表的蓝牙设备或者获取一些有关它的信息,例如它的名字,地址和绑定状态等等。
BluetoothGatt
这个类提供了 Bluetooth GATT 的基本功能。例如重新连接蓝牙设备,发现蓝牙设备的 Service 等等。
BluetoothGattService
这一个类通过 BluetoothGatt#getService 获得,如果当前服务不可见那么将返回一个 null。这一个类对应上面说过的 Service。我们可以通过这个类的 getCharacteristic(UUID uuid) 进一步获取 Characteristic 实现蓝牙数据的双向传输。
BluetoothGattCharacteristic
这个类对应上面提到的 Characteristic。通过这个类定义需要往外围设备写入的数据和读取外围设备发送过来的数据。
<!-- 蓝牙所需权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
BluetoothManager mBluetoothManager =(BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
mBluetoothAdapter.isEnabled()
如果返回true,这个时候就可以扫描了
如果返回false,这时候需要打开手机蓝牙。 可以调用系统方法让用户打开蓝牙。
Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivity(enable);
//10s后停止搜索
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, 1000 * 10);
UUID[] serviceUuids = {UUID.fromString(service_uuid)};
mBluetoothAdapter.startLeScan(serviceUuids, mLeScanCallback);
//蓝牙扫描回调接口
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback(){
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device.getName() == null) {
return;
}
Log.e("--->搜索到的蓝牙名字:", device.getName());
//可以将扫描的设备弄成列表,点击设备连接,也可以根据每个设备不同标识,自动连接。
}
};
//获取所需地址
String mDeviceAddress = device.getAddress();
BluetoothGatt mBluetoothGatt = device.connectGatt(context, false, mGattCallback);
onConnectionStateChange()被调用
连接状态改变时,mGattCallback中onConnectionStateChange()方法会被调用,当连接成功时,需要调用
mBluetoothGatt.discoverServices();去获取服务。
onServicesDiscovered()被调用
调用mBluetoothGatt.discoverServices();方法后,onServicesDiscovered()这个方法会被调用,说明发现当前设备了。然后我们就可以在里面去获取BluetoothGattService和BluetoothGattCharacteristic。
// BLE回调操作
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,int newState){
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
// 连接成功
mBluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
// 连接断开
Log.d("TAG","onConnectionStateChange fail-->" + status);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
//发现设备,遍历服务,初始化特征
initBLE(gatt);
} else {
Log.d("TAG","onServicesDiscovered fail-->" + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status){
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
// 收到的数据
byte[] receiveByte = characteristic.getValue();
}else{
Log.d("TAG","onCharacteristicRead fail-->" + status);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic){
super.onCharacteristicChanged(gatt, characteristic);
//当特征中value值发生改变
}
/**
* 收到BLE终端写入数据回调
* @param gatt
* @param characteristic
* @param status
*/
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
// 发送成功
} else {
// 发送失败
}
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
}
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
}
}
@Override
public void onDescriptorRead(BluetoothGatt gatt,BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
}
}
};
//写通道uuid
private static final UUID writeCharactUuid = UUID.fromString("0000fff6-0000-1000-8000-00805f9b34fb");
//通知通道 uuid
private static final UUID notifyCharactUuid =UUID.fromString( "0000fff7-0000-1000-8000-00805f9b34fb");
//初始化特征
public void initBLE(BluetoothGatt gatt) {
if (gatt == null) {
return;
}
//遍历所有服务
for (BluetoothGattService BluetoothGattService : gatt.getServices()) {
Log.e(TAG, "--->BluetoothGattService" + BluetoothGattService.getUuid().toString());
//遍历所有特征
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : BluetoothGattService.getCharacteristics()) {
Log.e("---->gattCharacteristic", bluetoothGattCharacteristic.getUuid().toString());
String str = bluetoothGattCharacteristic.getUuid().toString();
if (str.equals(writeCharactUuid)) {
//根据写UUID找到写特征
mBluetoothGattCharacteristic = bluetoothGattCharacteristic;
} else if (str.equals(notifyCharactUuid)) {
//根据通知UUID找到通知特征
mBluetoothGattCharacteristicNotify = bluetoothGattCharacteristic;
}
}
}
}
mBluetoothGatt.setCharacteristicNotification(mGattCharacteristicNotify, true);
mGattCharacteristicWrite .setValue(sData);
if (mBluetoothGatt != null) {
mBluetoothGatt.setCharacteristicNotification(notifyCharactUuid , true);
mBluetoothGatt.writeCharacteristic(mGattCharacteristicWrite );
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status){
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
// 收到的数据
byte[] receiveByte = characteristic.getValue();
}else{
Log.d("TAG","onCharacteristicRead fail-->" + status);
}
}
public boolean disConnect() {
if (mBluetoothGatt != null) {
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
mBluetoothGatt = null;
return true;
}
return false;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。