概述
经典蓝牙与低功耗(BLE)蓝牙的区别
①经典蓝牙:发现/搜索设备-->配对/绑定设备-->建立连接-->数据通信
②BLE蓝牙:中央 VS 外围设备,中央设备扫描,寻找广播;外围设备发出广播。二者通过GATT协议进行数据通信交互
③只要有蓝牙功能基本都支持经典蓝牙,那么BLE蓝牙Google在Android 4.3才开始支持BLE API
④BLE有设备角色的概念以及基于GATT协议来达到交互,至于经典蓝牙的数据通信,查看android.bluetooth包下发现BluetoothServerSocket与BluetoothSocket你就大致知道了
⑤BLE与传统的蓝牙相比最大的优势是功耗降低90%,同时传输距离增大(超过100米)、安全和稳定性提高(支持AES加密和CRC验证)
iBeacon与BLE的区别
虽然iBeacon技术基于BLE,但是iBeacon的UUID和BLE的Service、Characteristic、Descriptor的UUID是没关系,iBeacon的UUID是广播的时候发出,是由Apple自己定义的标准,而Service、Characteristic、Descriptor必须是连上BLE终端后才得到,是BLE标准。
运行效果
权限
<uses-feature Android:name="android.hardware.bluetooth_le" android:required="true"/>
这里的true标示手机如果不支持低功耗蓝牙就直接不让安装,但是如果想让你的app提供给那些不支持BLE的设备,需要在manifest中包括上面代码并设置required="false",然后在运行时可以通过使用getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)确定BLE的可用性。
打开蓝牙
打开方法与经典蓝牙打开方式相同,区别在于BLE通过getSystemService(Context.BLUETOOTH_SERVICE)得到BluetoothManager(API level 18),BluetoothManager.getAdapter()得到BluetoothAdapter。
发现/搜索BLE设备
通过调用BluetoothAdapter的startLeScan(BluetoothAdapter.LeScanCallback)搜索BLE设备。调用此方法时需要传入 BluetoothAdapter.LeScanCallback参数。因此你需要实现 BluetoothAdapter.LeScanCallback接口,BLE设备的搜索结果将通过这个callback返回。如果你只需要搜索指定UUID的外设,你可以调用 startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法。其中UUID数组指定你的应用程序所支持的GATT Services的UUID。stopLeScan(BluetoothAdapter.LeScanCallback)停止搜索BLE设备,由于搜索需要尽量减少功耗,因此在实际使用时需要注意。
onLeScan 方法在Android 5.0以下及Android 5.0及以上所运行的线程不同。
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
if (Looper.myLooper() == Looper.getMainLooper()) {// Android 5.0 及以上
addData(device, rssi, scanRecord);
} else {
runOnUiThread(new Runnable() {// Android 5.0 以下
@Override
public void run() {
addData(device, rssi, scanRecord);
}
});
}
}
处理发现的BLE设备,并展示在UI上
public void addData(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device != null) {
/**
* 这里调用ibeacon工具类封装bieacon并转换距离
* 非ibeacon设备可替换自己的业务
*/
BleBuletoothDeviceBean mdb = IbeaconUtils.fromScanData(new BleBuletoothDeviceBean(), device, rssi, scanRecord);
if (mainList.size() < 1) {
mainList.add(mdb);
lvAdapter.notifyDataSetChanged();
return;
}
for (int i = 0; i < mainList.size(); i++) {
BleBuletoothDeviceBean bbdb = mainList.get(i);
if (bbdb.getType() == 1) {
if (bbdb.getDevice().getAddress().equals(device.getAddress())) {
bbdb.setDistance(mdb.getDistance());
bbdb.setRssi(mdb.getRssi());
bbdb.setTxPower(mdb.getTxPower());
}
} else {
if (!bbdb.getDevice().getAddress().equals(mdb.getDevice().getAddress())) {
mainList.add(mdb);
}
}
}