蓝牙4.0——Ble 开发要点

来源:互联网 发布:js时间戳转时间对象 编辑:程序博客网 时间:2024/05/15 17:40

                             

Android 4.3才开始支持BLE API,所以保证在蓝牙4.0在Android 4.3及其以上的系统使用

首先要确定他所需要的权限,2个权限如下:

<uses-permission android:name="android.permission.BLUETOOTH"/>

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

BLE分为三部分Service、Characteristic、Descriptor,这三部分都由UUID作为唯一标示符。一个蓝牙4.0的终端可以包含多个Service,一个Service可以包含多个Characteristic,一个Characteristic包含一个Value和多个Descriptor,一个Descriptor包含一个Value。

蓝牙使用第一步:

判断手机是否支持蓝牙4.0   方法如下

if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {

// 满足条件,表示手机支持

}

初始化 Bluetooth adapter, 通过蓝牙管理器得到一个参考蓝牙适配器(API必须在以上android4.3或以上和版本)

BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

mBluetoothAdapter = bluetoothManager.getAdapter();

蓝牙使用第二步:搜索蓝牙设备

//开始搜索

mBluetoothAdapter.startLeScan(mLeScanCallback);

//停止搜索

mBluetoothAdapter.stopLeScan(mLeScanCallback);

搜索蓝牙的回调方法:

// Device scan callback.

private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

@Override

public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {

runOnUiThread(new Runnable() {

@Override

public void run() {

// 可以获取搜索到的蓝牙的一些信息 ,包括名称,mark地址等等

name = device.getName();

address = device.getAddress();

});

}

};

第三步:蓝牙连接

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

此方法会根据连接的结果给予回调方法;

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

@Override

public void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {

String intentAction;

System.out.println("=======status:" + status+",newState="+newState);

// 蓝牙连接成功

if (newState == BluetoothProfile.STATE_CONNECTED) {  

intentAction = ACTION_GATT_CONNECTED;

mConnectionState = STATE_CONNECTED;

broadcastUpdate(intentAction);

Log.i(TAG, "Connected to GATT server.");

// Attempts to discover services after successful connection.

Log.i(TAG, "Attempting to start service discovery:"

+ mBluetoothGatt.discoverServices());

// 蓝牙连接成功之后,必须调用此方法来发现蓝牙的服务

mBluetoothGatt.discoverServices()

// 蓝牙连接失败

else if (newState == BluetoothProfile.STATE_DISCONNECTED) {

intentAction = ACTION_GATT_DISCONNECTED;

mConnectionState = STATE_DISCONNECTED;

Log.i(TAG, "Disconnected from GATT server.");

broadcastUpdate(intentAction);

}

}

// 发现服务

@Override

public void onServicesDiscovered(BluetoothGatt gatt, int status) {

if (status == BluetoothGatt.GATT_SUCCESS) {

// 发现服务

} else {

 

}

}

// 读取蓝牙数据

@Override

public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {

System.out.println("onCharacteristicRead");

if (status == BluetoothGatt.GATT_SUCCESS) {

broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

}

}

@Override

public void onDescriptorWrite(BluetoothGatt gatt,BluetoothGattDescriptor descriptor, int status) {

System.out.println("onDescriptorWriteonDescriptorWrite = " + status

+ ", descriptor =" + descriptor.getUuid().toString());

}

// 服务状态发生变化

@Override

public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {

broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

if (characteristic.getValue() != null) {

System.out.println(characteristic.getStringValue(0));

}

System.out.println("--------onCharacteristicChanged-----");

}

 

// 获取蓝牙信号强度

@Override

public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {

System.out.println("rssi = " + rssi);

}

// 写入数据

public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {

System.out.println("--------write success----- status:" + status);

System.out.println("--------write success----- WriteType:" + characteristic.getWriteType());

}

};

第四步:蓝牙服务读取 

读取蓝牙服务,遍历服务,获取到自己需要的服务uuid

遍历次服务下的特征值,判断读,写,通知属性,设置通知属性发送数据到蓝牙设备打开通知

某些函数之间存在先后关系,首先connect——>discoverService

 

一些函数是异步的

(1)discoverService()----->回调OnServiceDiscovered()

(2)readCharacteristic()----->回调OnCharacteristicRead()

(3)SetCharacteristicNotification()----->回调OnCharacteristicChanged()

 

 

for (BluetoothGattService gattService : gattServices) {

uuid_1 = gattService.getUuid().toString();

Log.e("info1","<<<<<<<<<<<<<<<<uuid_1="+uuid_1);

List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();

Map<String, BluetoothGattCharacteristic> charas = new HashMap<String, BluetoothGattCharacteristic>();

if(Config.uuid.equals(uuid_1)){

String uuid=null;

// Loops through available Characteristics.

for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {

uuid = gattCharacteristic.getUuid().toString();

Log.e("info1",">>>>>>>>>>>>>>>>>>>>>>>>>>>>uuid="+uuid);

if(Config.uuid_write.equals(uuid)){

final int prop = gattCharacteristic.getProperties();

// 具有可写属性 

if ((prop & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {

Log.e("info","uuid_write 可读");

}

//  具有通知属性 

if ((prop & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {

Log.e("info","uuid_write 通知属性");

}

 

if ((prop & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {

Log.e("info","uuid_write 可写");

}

charas.put(uuid, gattCharacteristic);

}

if(Config.uuid_read.equals(uuid)){

final int prop = gattCharacteristic.getProperties();

//  具有可写属性 

if ((prop & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {

Log.e("info","uuid_read 可写");

}

//  具有可读属性 

if ((prop & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {

Log.e("info","uuid_read 可读");

}

//  具有通知属性 

if ((prop & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {

Log.e("info","uuid_read 通知属性");

}

MyApplication.getInstance().bindService.setCharacteristicNotification(gattCharacteristic, true);

charas.put(uuid, gattCharacteristic);

}

if(Config.uuid.equals(uuid_1)){  // 判断是需要的 uudi 才搜集

MyApplication.getInstance().mGattCharacteristics.put(uuid_1, charas);

}

}

}

}

}

 

 

 

注释:

在找到Service后,不能同时监听两个或两个以上的Service只能先监听一个再去监听另一个(串行监听),把一个服务里面的所有特征监听完(特征也是串行监听)再去监听另一个服务的所有特征。。。

 

 

 

做完以上4步蓝牙基本可以正常使用了,但是在代码调试过程中,需要注意的是安卓设备在使用蓝牙4.0的过程中可能会出现一些问题,比如读取服务出现读取失败,读取时间长,在代码中需要个人根据逻辑添加一些延时的处理,基本上以上的代码就可以完成蓝牙的基本使用了,复杂的还是在于逻辑上

 

1 0