对 Android 中的 BLE 定向广告 (ADV_DIRECT_IND) 做出反应
Reacting to BLE directed advertising (ADV_DIRECT_IND) in Android
如何对Android中的定向广告 (ADV_DIRECT_IND == 0001
)做出反应?
有一个 BLE 小工具可以将定向广告发送到 Android phone(目前使用 phone 的硬编码 MAC 地址)并且在我的 Android app 我想做出反应并启动与小工具的连接并从小工具读取 org.bluetooth.characteristic.location_and_speed 值:
请告知是否可以通过Android 5 API。
直接广告 确实有效 - 至少在 HTC M8 phone 和 Android 5.0 (API 21 级及以上)。
解决方案是将设备地址添加到 ScanFilter。
如果将过滤器留空,将不会调用扫描回调。
这是我的工作代码:
public static final String TAG = "My_BLE_app";
public static final String DEVICE_1 = "D4:BE:84:72:5B:8E";
public static final String DEVICE_2 = "C4:39:07:19:60:E2";
private Context mContext;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mScanner;
private ScanSettings mSettings;
private List<ScanFilter> mFilters = new ArrayList<ScanFilter>();
首先是初始化BLE的方法:
public boolean init() {
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null)
return false;
mScanner = mBluetoothAdapter.getBluetoothLeScanner();
mSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
mFilters.add(new ScanFilter.Builder().setDeviceAddress(DEVICE_1).build());
mFilters.add(new ScanFilter.Builder().setDeviceAddress(DEVICE_2).build());
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
然后是扫描回调:
private ScanCallback mDirectedScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
processResult(result);
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult result: results) {
processResult(result);
}
}
private void processResult(ScanResult result) {
BluetoothDevice device = result.getDevice();
if (device == null)
return;
String address = device.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address))
return;
int rssi = result.getRssi();
Log.d(TAG, "address=" + address + ", rssi=" + rssi);
// TODO connect to the device in under 1 second
}
};
最后是开始扫描的代码:
mScanner.startScan(mFilters, mSettings, mDirectedScanCallback);
一个问题仍然悬而未决:
我不知道如何在Android端检测扫描类型——也就是说扫描是否是定向的。
部分回答开放式问题:
我注意到 ScanRecord.getBytes()
是空的——全是“\0”——用于定向扫描 (ADV_DIRECT_IND
)——但否则会包含广告数据 (ADV_IND
)。
如何对Android中的定向广告 (ADV_DIRECT_IND == 0001
)做出反应?
有一个 BLE 小工具可以将定向广告发送到 Android phone(目前使用 phone 的硬编码 MAC 地址)并且在我的 Android app 我想做出反应并启动与小工具的连接并从小工具读取 org.bluetooth.characteristic.location_and_speed 值:
请告知是否可以通过Android 5 API。
直接广告 确实有效 - 至少在 HTC M8 phone 和 Android 5.0 (API 21 级及以上)。
解决方案是将设备地址添加到 ScanFilter。
如果将过滤器留空,将不会调用扫描回调。
这是我的工作代码:
public static final String TAG = "My_BLE_app";
public static final String DEVICE_1 = "D4:BE:84:72:5B:8E";
public static final String DEVICE_2 = "C4:39:07:19:60:E2";
private Context mContext;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mScanner;
private ScanSettings mSettings;
private List<ScanFilter> mFilters = new ArrayList<ScanFilter>();
首先是初始化BLE的方法:
public boolean init() {
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null)
return false;
mScanner = mBluetoothAdapter.getBluetoothLeScanner();
mSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
mFilters.add(new ScanFilter.Builder().setDeviceAddress(DEVICE_1).build());
mFilters.add(new ScanFilter.Builder().setDeviceAddress(DEVICE_2).build());
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
然后是扫描回调:
private ScanCallback mDirectedScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
processResult(result);
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult result: results) {
processResult(result);
}
}
private void processResult(ScanResult result) {
BluetoothDevice device = result.getDevice();
if (device == null)
return;
String address = device.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address))
return;
int rssi = result.getRssi();
Log.d(TAG, "address=" + address + ", rssi=" + rssi);
// TODO connect to the device in under 1 second
}
};
最后是开始扫描的代码:
mScanner.startScan(mFilters, mSettings, mDirectedScanCallback);
一个问题仍然悬而未决:
我不知道如何在Android端检测扫描类型——也就是说扫描是否是定向的。
部分回答开放式问题:
我注意到 ScanRecord.getBytes()
是空的——全是“\0”——用于定向扫描 (ADV_DIRECT_IND
)——但否则会包含广告数据 (ADV_IND
)。