手机锁屏状态下,后台服务无法扫描蓝牙设备
2019-05-07 本文已影响0人
冰珊孤雪
搜索蓝牙接口:
/**
* Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
* For unfiltered scans, scanning is stopped on screen off to save power. Scanning is
* resumed when screen is turned on again. To avoid this, do filetered scanning by
* using proper {@link ScanFilter}.
* <p>
* An app must hold
* {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
* in order to get results.
*
* @param filters {@link ScanFilter}s for finding exact BLE devices.
* @param settings Settings for the scan.
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback) {
startScan(filters, settings, null, callback, /*callbackIntent=*/ null, null);
}
注释上写的非常清楚:
For unfiltered scans, scanning is stopped on screen off to save power. Scanning is
* resumed when screen is turned on again. To avoid this, do filetered scanning by
* using proper {@link ScanFilter}.
没有添加过滤的情况下锁屏状态会停止扫描,所以我们只需要加上过滤条件ScanFilter
即可,示例代码如下:
List<ScanFilter> scanFilters = new ArrayList<>();
scanFilters.add(
new ScanFilter.Builder().setDeviceName("INPUT_YOUR_FILTER_NAME").build()
);
ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
scanSettingsBuilder.setPhy(scannerParams.getPhy())
.setLegacy(false);
}
ScanSettings scanSettings = scanSettingsBuilder.build();
try {
// Cannot start unfiltered scan in location-off. This scan will be resumed when location is on: 6
mBluetoothLeScanner.startScan(scanFilters, scanSettings, mScanCallback);
return true;
} catch (Exception e) {
ZLogger.e(e.toString());
return false;
}
GattService.java
// Check if a scan record matches a specific filters.
private boolean matchesFilters(ScanClient client, ScanResult scanResult) {
if (client.filters == null || client.filters.isEmpty()) {
return true;
}
for (ScanFilter filter : client.filters) {
if (filter.matches(scanResult)) {
return true;
}
}
return false;
}
ScanFilter.java
// Manufacturer data match.
if (mManufacturerId >= 0) {
if (!matchesPartialData(mManufacturerData, mManufacturerDataMask,
scanRecord.getManufacturerSpecificData(mManufacturerId))) {
return false;
}
}