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的过程中可能会出现一些问题,比如读取服务出现读取失败,读取时间长,在代码中需要个人根据逻辑添加一些延时的处理,基本上以上的代码就可以完成蓝牙的基本使用了,复杂的还是在于逻辑上