下面列出了android.bluetooth.BluetoothAdapter#isOffloadedScanBatchingSupported ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@NonNull
@Override
/* package */ android.bluetooth.le.ScanSettings toNativeScanSettings(@NonNull final BluetoothAdapter adapter,
@NonNull final ScanSettings settings,
final boolean exactCopy) {
final android.bluetooth.le.ScanSettings.Builder builder =
new android.bluetooth.le.ScanSettings.Builder();
if (exactCopy || adapter.isOffloadedScanBatchingSupported() && settings.getUseHardwareBatchingIfSupported())
builder.setReportDelay(settings.getReportDelayMillis());
if (exactCopy || settings.getUseHardwareCallbackTypesIfSupported())
builder.setCallbackType(settings.getCallbackType())
.setMatchMode(settings.getMatchMode())
.setNumOfMatches(settings.getNumOfMatches());
builder.setScanMode(settings.getScanMode())
.setLegacy(settings.getLegacy())
.setPhy(settings.getPhy());
return builder.build();
}
@NonNull
@Override
/* package */ android.bluetooth.le.ScanSettings toNativeScanSettings(@NonNull final BluetoothAdapter adapter,
@NonNull final ScanSettings settings,
final boolean exactCopy) {
final android.bluetooth.le.ScanSettings.Builder builder =
new android.bluetooth.le.ScanSettings.Builder();
if (exactCopy || adapter.isOffloadedScanBatchingSupported() && settings.getUseHardwareBatchingIfSupported())
builder.setReportDelay(settings.getReportDelayMillis());
if (exactCopy || settings.getUseHardwareCallbackTypesIfSupported())
builder.setCallbackType(settings.getCallbackType())
.setMatchMode(settings.getMatchMode())
.setNumOfMatches(settings.getNumOfMatches());
builder.setScanMode(settings.getScanMode());
return builder.build();
}
@NonNull
/* package */ android.bluetooth.le.ScanSettings toNativeScanSettings(@NonNull final BluetoothAdapter adapter,
@NonNull final ScanSettings settings,
final boolean exactCopy) {
final android.bluetooth.le.ScanSettings.Builder builder =
new android.bluetooth.le.ScanSettings.Builder();
if (exactCopy || adapter.isOffloadedScanBatchingSupported() && settings.getUseHardwareBatchingIfSupported())
builder.setReportDelay(settings.getReportDelayMillis());
if (settings.getScanMode() != ScanSettings.SCAN_MODE_OPPORTUNISTIC) {
builder.setScanMode(settings.getScanMode());
} else {
// SCAN MORE OPPORTUNISTIC is not supported on Lollipop.
// Instead, SCAN_MODE_LOW_POWER will be used.
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
}
settings.disableUseHardwareCallbackTypes(); // callback types other then CALLBACK_TYPE_ALL_MATCHES are not supported on Lollipop
return builder.build();
}
static ScanSettings.Builder buildSettings(BluetoothAdapter adapter, int scanMode, Interval scanReportDelay) {
final ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setScanMode(scanMode);
if( adapter.isOffloadedScanBatchingSupported() )
{
final long scanReportDelay_millis = false == Interval.isDisabled(scanReportDelay) ? scanReportDelay.millis() : 0;
builder.setReportDelay(scanReportDelay_millis);
}
else
{
builder.setReportDelay(0);
}
return builder;
}
@Override
@RequiresPermission(allOf = {Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH})
/* package */ void startScanInternal(@NonNull final List<ScanFilter> filters,
@NonNull final ScanSettings settings,
@NonNull final ScanCallback callback,
@NonNull final Handler handler) {
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
final BluetoothLeScanner scanner = adapter.getBluetoothLeScanner();
if (scanner == null)
throw new IllegalStateException("BT le scanner not available");
final boolean offloadedBatchingSupported = adapter.isOffloadedScanBatchingSupported();
final boolean offloadedFilteringSupported = adapter.isOffloadedFilteringSupported();
ScanCallbackWrapperLollipop wrapper;
synchronized (wrappers) {
if (wrappers.containsKey(callback)) {
throw new IllegalArgumentException("scanner already started with given callback");
}
wrapper = new ScanCallbackWrapperLollipop(offloadedBatchingSupported,
offloadedFilteringSupported, filters, settings, callback, handler);
wrappers.put(callback, wrapper);
}
final android.bluetooth.le.ScanSettings nativeScanSettings = toNativeScanSettings(adapter, settings, false);
List<android.bluetooth.le.ScanFilter> nativeScanFilters = null;
if (!filters.isEmpty() && offloadedFilteringSupported && settings.getUseHardwareFilteringIfSupported())
nativeScanFilters = toNativeScanFilters(filters);
scanner.startScan(nativeScanFilters, nativeScanSettings, wrapper.nativeCallback);
}
@Override
@RequiresPermission(Manifest.permission.BLUETOOTH)
public void flushPendingScanResults(@NonNull final ScanCallback callback) {
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
//noinspection ConstantConditions
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null!");
}
ScanCallbackWrapperLollipop wrapper;
synchronized (wrappers) {
wrapper = wrappers.get(callback);
}
if (wrapper == null) {
throw new IllegalArgumentException("callback not registered!");
}
final ScanSettings settings = wrapper.scanSettings;
if (adapter.isOffloadedScanBatchingSupported() && settings.getUseHardwareBatchingIfSupported()) {
final BluetoothLeScanner scanner = adapter.getBluetoothLeScanner();
if (scanner == null)
return;
scanner.flushPendingScanResults(wrapper.nativeCallback);
} else {
wrapper.flushPendingScanResults();
}
}
static ScanSettings.Builder buildSettings(BluetoothAdapter adapter, int scanMode, Interval scanReportDelay) {
final ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setScanMode(scanMode);
if( adapter.isOffloadedScanBatchingSupported() )
{
final long scanReportDelay_millis = false == Interval.isDisabled(scanReportDelay) ? scanReportDelay.millis() : 0;
builder.setReportDelay(scanReportDelay_millis);
}
else
{
builder.setReportDelay(0);
}
return builder;
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(final Context context, final Intent intent) {
// Ensure we are ok.
if (context == null || intent == null)
return;
// Find the target pending intent.
final PendingIntent callbackIntent = intent.getParcelableExtra(EXTRA_PENDING_INTENT);
if (callbackIntent == null)
return;
// Filters and settings have been set as native objects, otherwise they could not be
// serialized by the system scanner.
final ArrayList<android.bluetooth.le.ScanFilter> nativeScanFilters =
intent.getParcelableArrayListExtra(EXTRA_FILTERS);
final android.bluetooth.le.ScanSettings nativeScanSettings = intent.getParcelableExtra(EXTRA_SETTINGS);
if (nativeScanFilters == null || nativeScanSettings == null)
return;
// Some ScanSettings parameters are only on compat version and need to be sent separately.
final boolean useHardwareBatchingIfSupported = intent.getBooleanExtra(EXTRA_USE_HARDWARE_BATCHING, true);
final boolean useHardwareFilteringIfSupported = intent.getBooleanExtra(EXTRA_USE_HARDWARE_FILTERING, true);
final boolean useHardwareCallbackTypesIfSupported = intent.getBooleanExtra(EXTRA_USE_HARDWARE_CALLBACK_TYPES, true);
final long matchLostDeviceTimeout = intent.getLongExtra(EXTRA_MATCH_LOST_TIMEOUT, ScanSettings.MATCH_LOST_DEVICE_TIMEOUT_DEFAULT);
final long matchLostTaskInterval = intent.getLongExtra(EXTRA_MATCH_LOST_INTERVAL, ScanSettings.MATCH_LOST_TASK_INTERVAL_DEFAULT);
final int matchMode = intent.getIntExtra(EXTRA_MATCH_MODE, ScanSettings.MATCH_MODE_AGGRESSIVE);
final int numOfMatches = intent.getIntExtra(EXTRA_NUM_OF_MATCHES, ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT);
// Convert native objects to compat versions.
final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
final BluetoothLeScannerImplOreo scannerImpl = (BluetoothLeScannerImplOreo) scanner;
final ArrayList<ScanFilter> filters = scannerImpl.fromNativeScanFilters(nativeScanFilters);
final ScanSettings settings = scannerImpl.fromNativeScanSettings(nativeScanSettings,
useHardwareBatchingIfSupported,
useHardwareFilteringIfSupported,
useHardwareCallbackTypesIfSupported,
matchLostDeviceTimeout, matchLostTaskInterval,
matchMode, numOfMatches);
// Check device capabilities and create a wrapper that will send a PendingIntent.
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
final boolean offloadedBatchingSupported = adapter.isOffloadedScanBatchingSupported();
final boolean offloadedFilteringSupported = adapter.isOffloadedFilteringSupported();
// Obtain or create a PendingIntentExecutorWrapper. A static instance (obtained from a
// static BluetoothLeScannerCompat singleton) is necessary as it allows to keeps
// track of found devices and emulate batching and callback types if those are not
// supported or a compat version was forced.
BluetoothLeScannerImplOreo.PendingIntentExecutorWrapper wrapper;
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (scanner) {
try {
wrapper = scannerImpl.getWrapper(callbackIntent);
} catch (final IllegalStateException e) {
// Scanning has been stopped.
return;
}
if (wrapper == null) {
// Wrapper has not been created, or was created, but the app was then killed
// and must be created again. Some information will be lost (batched devices).
wrapper = new BluetoothLeScannerImplOreo.PendingIntentExecutorWrapper(offloadedBatchingSupported,
offloadedFilteringSupported, filters, settings, callbackIntent);
scannerImpl.addWrapper(callbackIntent, wrapper);
}
}
// The context may change each time. Set the one time temporary context that will be used
// to send PendingIntent. It will be released after the results were handled.
wrapper.executor.setTemporaryContext(context);
// Check what results were received and send them to PendingIntent.
final List<android.bluetooth.le.ScanResult> nativeScanResults =
intent.getParcelableArrayListExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT);
if (nativeScanResults != null) {
final ArrayList<ScanResult> results = scannerImpl.fromNativeScanResults(nativeScanResults);
if (settings.getReportDelayMillis() > 0) {
wrapper.handleScanResults(results);
} else if (!results.isEmpty()) {
final int callbackType = intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE,
ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
wrapper.handleScanResult(callbackType, results.get(0));
}
} else {
final int errorCode = intent.getIntExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, 0);
if (errorCode != 0) {
wrapper.handleScanError(errorCode);
}
}
// Release the temporary context reference, so that static executor does not hold a
// reference to a context.
wrapper.executor.setTemporaryContext(null);
}