本次测试 主要是用两个 基于Android5.0系统以上的手机,一个负责蓝牙广播,一个负责搜索蓝牙广播。
其中发送广播的规则为:
设置不同频率的广播 ,广播内容为三个 byte 数据。
系统要求:Android 5.0以上
需要的权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
广播频率的相关设置:
/**
* 设置频率:
* ADVERTISE_MODE_LOW_LATENCY 100ms
* ADVERTISE_MODE_LOW_POWER 1s
* ADVERTISE_MODE_BALANCED 250ms
*/
private AdvertiseSettings buildAdvertiseSettings() {
AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY);
settingsBuilder.setTimeout(0);
return settingsBuilder.build();
}
添加广播数据内容
/**
* 设置 serviceUuid
*/
private AdvertiseData buildAdvertiseData() {
byte[] sendDatas = new Byte[]{0x01,0x02,0x03};
AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
dataBuilder.addServiceUuid(Constants.Service_UUID);
dataBuilder.setIncludeDeviceName(true); // 是否包含设备名称
dataBuilder.addServiceData(Constants.Service_UUID, sendDatas);
return dataBuilder.build();
}
/**
* 开始蓝牙广播
*/
private void startAdvertising() {
if (mAdvertiseCallback == null) {
AdvertiseSettings settings = buildAdvertiseSettings();
AdvertiseData data = buildAdvertiseData();
mAdvertiseCallback = new SampleAdvertiseCallback();
if (mBluetoothLeAdvertiser != null) {
mBluetoothLeAdvertiser.startAdvertising(settings, data, mAdvertiseCallback);
}
}
}
蓝牙广播成功的回调:
private class SampleAdvertiseCallback extends AdvertiseCallback {
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
Log.e(TAG, "Advertising failed ");
}
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
Log.e(TAG, "Advertising successfully started");
}
}
设置搜索的频率,同样也有三种可以选择,这里选择:
SCAN_MODE_LOW_LATENCY
private ScanSettings buildScanSettings() {
ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
return builder.build();
}
设置过滤uuid
private List buildScanFilters() {
List scanFilters = new ArrayList<>();
ScanFilter.Builder builder = new ScanFilter.Builder();
// Comment out the below line to see all BLE devices around you
builder.setServiceUuid(Constants.Service_UUID);
scanFilters.add(builder.build());
return scanFilters;
}
设置搜索的回调:
private class SampleScanCallback extends ScanCallback {
@Override
public void onBatchScanResults(List results) {
super.onBatchScanResults(results);
}
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
ScanRecord record = result.getScanRecord();
Log.e(TAG, "data = " +LogTool.LogBytes2Hex(parseAdverData(record.getBytes())));
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
Log.e(TAG, "Scan failed with error: " + errorCode);
}
}
解析广播的数据,因为广播的是三个字节的内容,所以解析如下:
public static byte[] parseAdverData(byte[] scanRecord) {
int len = scanRecord.length;
int start = 0;
for (int i = 0; i < len - 1; i++) {
if ((scanRecord[i] & 0xff) == 0xb8
&& (scanRecord[i + 1] & 0xff) == 0x06) {
start = i + 5;
break;
}
}
byte[] data = new byte[3];
data[0] = scanRecord[start];
data[1] = scanRecord[start + 1];
data[2] = scanRecord[start + 2];
return data;
}
开始搜索:
public void startScanning() {
if (mScanCallback == null) {
Log.d(TAG, "Starting Scanning");
// Kick off a new scan.
mScanCallback = new SampleScanCallback();
mBluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), mScanCallback);
}
}