Merge "BLE scan API using PendingIntent" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
7859022e8e
@@ -8078,7 +8078,12 @@ package android.bluetooth.le {
|
||||
method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
|
||||
method public void startScan(android.bluetooth.le.ScanCallback);
|
||||
method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
|
||||
method public int startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.app.PendingIntent);
|
||||
method public void stopScan(android.bluetooth.le.ScanCallback);
|
||||
method public void stopScan(android.app.PendingIntent);
|
||||
field public static final java.lang.String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
|
||||
field public static final java.lang.String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
|
||||
field public static final java.lang.String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
|
||||
}
|
||||
|
||||
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
|
||||
|
||||
@@ -8550,10 +8550,15 @@ package android.bluetooth.le {
|
||||
method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
|
||||
method public void startScan(android.bluetooth.le.ScanCallback);
|
||||
method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
|
||||
method public int startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.app.PendingIntent);
|
||||
method public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback);
|
||||
method public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback);
|
||||
method public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
|
||||
method public void stopScan(android.bluetooth.le.ScanCallback);
|
||||
method public void stopScan(android.app.PendingIntent);
|
||||
field public static final java.lang.String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
|
||||
field public static final java.lang.String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
|
||||
field public static final java.lang.String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
|
||||
}
|
||||
|
||||
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
|
||||
|
||||
@@ -8109,7 +8109,12 @@ package android.bluetooth.le {
|
||||
method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
|
||||
method public void startScan(android.bluetooth.le.ScanCallback);
|
||||
method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
|
||||
method public int startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.app.PendingIntent);
|
||||
method public void stopScan(android.bluetooth.le.ScanCallback);
|
||||
method public void stopScan(android.app.PendingIntent);
|
||||
field public static final java.lang.String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
|
||||
field public static final java.lang.String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
|
||||
field public static final java.lang.String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
|
||||
}
|
||||
|
||||
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.bluetooth.le.AdvertiseSettings;
|
||||
@@ -47,6 +48,9 @@ interface IBluetoothGatt {
|
||||
void unregisterScanner(in int scannerId);
|
||||
void startScan(in int scannerId, in ScanSettings settings, in List<ScanFilter> filters,
|
||||
in WorkSource workSource, in List scanStorages, in String callingPackage);
|
||||
void startScanForIntent(in PendingIntent intent, in ScanSettings settings, in List<ScanFilter> filters,
|
||||
in String callingPackage);
|
||||
void stopScanForIntent(in PendingIntent intent, in String callingPackage);
|
||||
void stopScan(in int scannerId);
|
||||
void flushPendingBatchResults(in int scannerId);
|
||||
|
||||
|
||||
@@ -17,17 +17,18 @@
|
||||
package android.bluetooth.le;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.ActivityThread;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.IBluetoothGatt;
|
||||
import android.bluetooth.IBluetoothManager;
|
||||
import android.bluetooth.le.IScannerCallback;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.RemoteException;
|
||||
import android.os.WorkSource;
|
||||
import android.util.Log;
|
||||
@@ -36,7 +37,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This class provides methods to perform scan related operations for Bluetooth LE devices. An
|
||||
@@ -57,6 +57,27 @@ public final class BluetoothLeScanner {
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = false;
|
||||
|
||||
/**
|
||||
* Extra containing a list of ScanResults. It can have one or more results if there was no
|
||||
* error. In case of error, {@link #EXTRA_ERROR_CODE} will contain the error code and this
|
||||
* extra will not be available.
|
||||
*/
|
||||
public static final String EXTRA_LIST_SCAN_RESULT
|
||||
= "android.bluetooth.le.extra.LIST_SCAN_RESULT";
|
||||
|
||||
/**
|
||||
* Optional extra indicating the error code, if any. The error code will be one of the
|
||||
* SCAN_FAILED_* codes in {@link ScanCallback}.
|
||||
*/
|
||||
public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
|
||||
|
||||
/**
|
||||
* Optional extra indicating the callback type, which will be one of
|
||||
* ScanSettings.CALLBACK_TYPE_*.
|
||||
* @see ScanCallback#onScanResult(int, ScanResult)
|
||||
*/
|
||||
public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
|
||||
|
||||
private final IBluetoothManager mBluetoothManager;
|
||||
private final Handler mHandler;
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
@@ -110,7 +131,27 @@ public final class BluetoothLeScanner {
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
|
||||
public void startScan(List<ScanFilter> filters, ScanSettings settings,
|
||||
final ScanCallback callback) {
|
||||
startScan(filters, settings, null, callback, null);
|
||||
startScan(filters, settings, null, callback, /*callbackIntent=*/ null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Bluetooth LE scan using a {@link PendingIntent}. The scan results will be delivered via
|
||||
* the PendingIntent. Use this method of scanning if your process is not always running and it
|
||||
* should be started when scan results are available.
|
||||
*
|
||||
* @param filters Optional list of ScanFilters for finding exact BLE devices.
|
||||
* @param settings Optional settings for the scan.
|
||||
* @param callbackIntent The PendingIntent to deliver the result to.
|
||||
* @return Returns 0 for success or an error code from {@link ScanCallback} if the scan request
|
||||
* could not be sent.
|
||||
* @see #stopScan(PendingIntent)
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
|
||||
public int startScan(@Nullable List<ScanFilter> filters, @Nullable ScanSettings settings,
|
||||
@NonNull PendingIntent callbackIntent) {
|
||||
return startScan(filters,
|
||||
settings != null ? settings : new ScanSettings.Builder().build(),
|
||||
null, null, callbackIntent, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,23 +186,23 @@ public final class BluetoothLeScanner {
|
||||
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
|
||||
public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
|
||||
final WorkSource workSource, final ScanCallback callback) {
|
||||
startScan(filters, settings, workSource, callback, null);
|
||||
startScan(filters, settings, workSource, callback, null, null);
|
||||
}
|
||||
|
||||
private void startScan(List<ScanFilter> filters, ScanSettings settings,
|
||||
private int startScan(List<ScanFilter> filters, ScanSettings settings,
|
||||
final WorkSource workSource, final ScanCallback callback,
|
||||
final PendingIntent callbackIntent,
|
||||
List<List<ResultStorageDescriptor>> resultStorages) {
|
||||
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
|
||||
if (callback == null) {
|
||||
if (callback == null && callbackIntent == null) {
|
||||
throw new IllegalArgumentException("callback is null");
|
||||
}
|
||||
if (settings == null) {
|
||||
throw new IllegalArgumentException("settings is null");
|
||||
}
|
||||
synchronized (mLeScanClients) {
|
||||
if (mLeScanClients.containsKey(callback)) {
|
||||
if (callback != null && mLeScanClients.containsKey(callback)) {
|
||||
postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
|
||||
return;
|
||||
}
|
||||
IBluetoothGatt gatt;
|
||||
try {
|
||||
@@ -170,28 +211,34 @@ public final class BluetoothLeScanner {
|
||||
gatt = null;
|
||||
}
|
||||
if (gatt == null) {
|
||||
postCallbackError(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
|
||||
return;
|
||||
return postCallbackErrorOrReturn(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
|
||||
}
|
||||
if (!isSettingsConfigAllowedForScan(settings)) {
|
||||
postCallbackError(callback,
|
||||
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
|
||||
return;
|
||||
return postCallbackErrorOrReturn(callback,
|
||||
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
|
||||
}
|
||||
if (!isHardwareResourcesAvailableForScan(settings)) {
|
||||
postCallbackError(callback,
|
||||
ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
|
||||
return;
|
||||
return postCallbackErrorOrReturn(callback,
|
||||
ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
|
||||
}
|
||||
if (!isSettingsAndFilterComboAllowed(settings, filters)) {
|
||||
postCallbackError(callback,
|
||||
return postCallbackErrorOrReturn(callback,
|
||||
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
|
||||
settings, workSource, callback, resultStorages);
|
||||
wrapper.startRegisteration();
|
||||
if (callback != null) {
|
||||
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
|
||||
settings, workSource, callback, resultStorages);
|
||||
wrapper.startRegistration();
|
||||
} else {
|
||||
try {
|
||||
gatt.startScanForIntent(callbackIntent, settings, filters,
|
||||
ActivityThread.currentOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
return ScanCallback.SCAN_FAILED_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ScanCallback.NO_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,6 +261,25 @@ public final class BluetoothLeScanner {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops an ongoing Bluetooth LE scan started using a PendingIntent.
|
||||
* <p>
|
||||
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
|
||||
*
|
||||
* @param callbackIntent The PendingIntent that was used to start the scan.
|
||||
* @see #startScan(List, ScanSettings, PendingIntent)
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
|
||||
public void stopScan(PendingIntent callbackIntent) {
|
||||
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
|
||||
IBluetoothGatt gatt;
|
||||
try {
|
||||
gatt = mBluetoothManager.getBluetoothGatt();
|
||||
gatt.stopScanForIntent(callbackIntent, ActivityThread.currentOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush pending batch scan results stored in Bluetooth controller. This will return Bluetooth
|
||||
* LE scan results batched on bluetooth controller. Returns immediately, batch scan results data
|
||||
@@ -252,7 +318,7 @@ public final class BluetoothLeScanner {
|
||||
scanFilters.add(filter.getFilter());
|
||||
scanStorages.add(filter.getStorageDescriptors());
|
||||
}
|
||||
startScan(scanFilters, settings, null, callback, scanStorages);
|
||||
startScan(scanFilters, settings, null, callback, null, scanStorages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,7 +361,7 @@ public final class BluetoothLeScanner {
|
||||
mResultStorages = resultStorages;
|
||||
}
|
||||
|
||||
public void startRegisteration() {
|
||||
public void startRegistration() {
|
||||
synchronized (this) {
|
||||
// Scan stopped.
|
||||
if (mScannerId == -1) return;
|
||||
@@ -399,7 +465,6 @@ public final class BluetoothLeScanner {
|
||||
mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -453,6 +518,15 @@ public final class BluetoothLeScanner {
|
||||
}
|
||||
}
|
||||
|
||||
private int postCallbackErrorOrReturn(final ScanCallback callback, final int errorCode) {
|
||||
if (callback == null) {
|
||||
return errorCode;
|
||||
} else {
|
||||
postCallbackError(callback, errorCode);
|
||||
return ScanCallback.NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private void postCallbackError(final ScanCallback callback, final int errorCode) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -50,6 +50,8 @@ public abstract class ScanCallback {
|
||||
*/
|
||||
public static final int SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 5;
|
||||
|
||||
static final int NO_ERROR = 0;
|
||||
|
||||
/**
|
||||
* Callback when a BLE advertisement has been found.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user