搞定Android Bluetooth Low Energy-02

发现蓝牙设备

一般情况下,要连接蓝牙设备,先要发现蓝牙设备,也就是进行蓝牙扫描。
Peripheral devices(一直发送蓝牙广播,例如:手环)
Central devices(扫描接收Peripheral devices的广播,例如:Android手机)
advertising_and_discovery    广播示意图

这个有点类似ARP(Address Resolution Protocol,地址解析协议),不过ARP高级多了,但都是为了得到目标设备的通信信息。

Android蓝牙扫描

Android4.3/4.4存在一些bug和不稳定性,Android5.0出了新的API。

Android4.3/4.4
BluetoothAdapter.java
//开始扫描,扫描所有附近的蓝牙设备,扫描结果在回调:onLeScan
public boolean startLeScan (BluetoothAdapter.LeScanCallback callback)
//开始扫描广播中指定uuid service的设备,但是对于128位的UUID,这个方法无效。
public boolean startLeScan (UUID[] serviceUuids, BluetoothAdapter.LeScanCallback callback)
//由于扫描是耗电操作,完成后尽早结束扫描。
public void stopLeScan (BluetoothAdapter.LeScanCallback callback)

BluetoothAdapter.LeScanCallback.java
//扫描结果回调,回调是子线程。
public abstract void onLeScan (BluetoothDevice device, int rssi, byte[] scanRecord)
Android5.0及以上
BluetoothLeScanner.java
public void startScan (ScanCallback callback)
public void startScan (List<ScanFilter> filters, ScanSettings settings, ScanCallback callback)
public void stopScan (ScanCallback callback)

ScanCallback.java
public void onScanResult (int callbackType, ScanResult result)
public void onScanFailed (int errorCode)
Android扫描强烈建议:

0. 权限:BLUETOOTH and BLUETOOTH_ADMIN
1. 扫描是耗电操作,扫描完毕立马结束扫描。
2. 扫描是耗电操作,不要一直扫描,设置超时时间(当设备不在的时候,纯属浪费)。
3. 有些手机,一次扫描结果只上报一次而且device.getName()可能返回为null,如果想再次上报扫描,需要重新开始扫描。
4. 扫描结果回调是子线程。
5. startLeScan()有可能失败,需要关注return值。
6. Android6.0还需要权限:ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION

Android bug:BLE filtering in startLeScan(UUIDs, callback) doesn’t work for 128-bit UUIDs

Android蓝牙扫描实例

权限配置:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
库依赖

Add it in your root build.gradle at the end of repositories:

allprojects {
	repositories {
		...
		maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
	}
}
Add the dependency
dependencies {
    compile 'com.github.captain-miao:ble:1.0.0-SNAPSHOT'
}
几行搞定扫描
BleScanner mBleScanner = new BleScanner(getContext(), new SimpleScanCallback() {
    @Override
    public void onBleScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
        
    }

    @Override
    public void onBleScanFailed(BleScanState scanState) {

    }
});

//开始扫描 10秒超时
mBleScanner.startBleScan(10 * 1000);

//停止扫描
mBleScanner.stopBleScan();

Android6.0 权限处理参考:

Android M(6.0) 权限爬坑之旅

发表评论

电子邮件地址不会被公开。 必填项已用*标注