基础准备
蓝牙通信概念
通常意义的蓝牙通信的含义就是Client通过蓝牙对接后进行数据通信,这里面需要注意的是蓝牙通信是点对点的,所以是1对1关系,所以就有了Central vs. peripheral (中心设备vs外围设备)的概念,接下来我们将以Client角度阐述
蓝牙通信首先要了解几个重要的类
BluetoothAdapter
蓝牙通信的核心类,单例模式,通过BluetoothAdapter.getDefaultAdapter()获得或者通过蓝牙服务获取
BluetoothDevice
对应可搜索到的蓝牙设备,可使用这个类进行连接
BluetoothGatt
连接成功后的返回,可用来关闭连接,发现服务等等
具体开发流程(代码)
1.首先需要检查权限
<uses-featureandroid:name="android.hardware.bluetooth_le"android:required="true"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
2.检查ble支持
f(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this,R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
3.获取蓝牙代理
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
或者
BluetoothManager bm = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bm.getAdapter();
4.检查蓝牙是否开启
if(!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()){
Intent enableBtIntent = newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
5.搜索蓝牙设备
mHandler.postDelayed(newRunnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
这里需要注意的是因为蓝牙搜索比较费电,所以我们过一个时间间隔就关闭它,
startLeScan(UUID[], BluetoothAdapter.LeScanCallback)有个重载可通过uuid搜索指定的设备
privateBluetoothAdapter.LeScanCallback mLeScanCallback =
newBluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(finalBluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
一旦搜索到设备就加到显示列表
6.获取到需要连接的device后连接
BluetoothGatt mBluetoothGatt = device.connectGatt(this, false,BluetoothGattCallback);
这个GattCallback有9个回调,主要提供状态变换后的数据通信,BluetoothGatt 用来可用来写数据
可以看源码大致了解函数功能
7.连接后,就可以通讯了
BLE的三部分Service,Characteristic,Descriptor,所以大致讲下这几个概念
Service
Characteristic的集合。比如心率可以分成好几个Characteristic来秒速他
Characteristic
一个数据类型,包含一个value和0-n个对value的Descriptor
Descriptor
对Characteristic的描述,比如返回,单位
这三者的查找都是通过uuid,然后通过获取相应的类进行操作
写数据
首先需要一个Characteristic对象,然后往里面放数据,这里我们放入byte[]
Characteristic characteristic=new Characteristic();
characteristic.setValue(byte[] mByte);
bluetoothGatt.writeCharacteristic(characteristic);
这时候就会收到GattCallback里的onCharacteristicWrite回调
读数据
bluetoothGatt.readCharacteristic(characteristic);
调用此方法后会收到GattCallback的onCharacteristicRead回调,或者数据正常传过来的情况下此方法也会被回调,通过Characteristic.getValue方法即可收到相应数值
Summarize
流程大概就如上所示,有几个点需要注意
比如connect需要先discoverServices
还有一些数据转换的问题,16进制,byte[],十进制,字符串...
本文参考woshasanguo蓝牙开发