Yes. On Android 8+ you can use an Intent-based scan tied to a BroadcastReceiver to wake up an app based on a BLE advertisement detection. The BroadcastReceiver will only be allowed to run for a few seconds, but you can use this time to start an immediate JobService that can run for up to 10 minutes. This is exactly what the Android Beacon Library does out-of-the-box to allow background detections. You may also be able to use a foreground service to run longer than 10 minutes in the background. Read more about the options here.
ScanSettings settings = (new ScanSettings.Builder().setScanMode(
ScanSettings.SCAN_MODE_LOW_POWER)).build();
// Make a scan filter matching the beacons I care about
List<ScanFilter> filters = getScanFilters();
BluetoothManager bluetoothManager =
(BluetoothManager) mContext.getApplicationContext()
.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
Intent intent = new Intent(mContext, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
bluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, pendingIntent);
The above code will set an Intent to fire that will trigger a call to a class called MyBroadcastReceiver when a matching bluetooth device is detected. You can then fetch the scan data like this:
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int bleCallbackType = intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, -1);
if (bleCallbackType != -1) {
Log.d(TAG, "Passive background scan callback type: "+bleCallbackType);
ArrayList<ScanResult> scanResults = intent.getParcelableArrayListExtra(
BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT);
// Do something with your ScanResult list here.
// These contain the data of your matching BLE advertising packets
}
}
}