Scanning for Bluetooth LE devices when the phone is in doze mode, don't work. CallBack method dosn't called when doze mode

Viewed 492

I am developing an Android app (the app runs on Android 6): I want the app to send a notification to the user when it is near a BLE device (a device that I have at home). So I continuously scan, I scan through a service (which is running in the background). It works well when the phone screen is on; but, when the screen turns off, a few seconds later the application can no longer find the BLE (the scan is still running, but there is no callback.

if (enable) {
            if (mScanning) return;
            // Stops scanning after a pre-defined scan period.
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (!mScanning) return;
                    try {
                        mScanning = false;
                        mBluetoothLeScanner.stopScan(mScanCallback);
                        Log.i(TAG_LOG, "Stop scanning after pre-defined scan periode");

                    } catch (Exception e){Log.e(TAG_LOG,"mBluetoothLeScanner.stopScan Exception:=>"+e.getMessage());}
                }
            }, SCAN_PERIOD);

            mScanning = true;
            mBluetoothLeScanner.startScan(filters, settings, mScanCallback);
            Log.i(TAG_LOG, "Start scanning ....");
        }



 private ScanCallback mScanCallback = new ScanCallback() {
    //When a BLE advertisement has been found
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        Log.i(TAG_LOG, "Name: "+result.getDevice().getName()+". Adresse: "+result.getDevice().getAddress()+". Rssi: "+result.getRssi());
        //scanDevices(false);
        if(result.getDevice().getName() != null && result.getDevice().getName().toString().equals(deviceName)){
            mDeviceAdress = result.getDevice().getAddress();
            mDevice = mBluetoothAdapter.getRemoteDevice(mDeviceAdress);
            Log.i(TAG_LOG, "Device found");
            scanDevices(false);
        }
    }
1 Answers

You can't make this work. Scanning is a very expensive operation that Android won't allow in the background. Instead, make an attempt to connect to the device. I had success doing this in a WorkManager job, running every 15 minutes. Battery drain was negligible and it was pretty reliable. Note that a connection state 0x85 usually represents the device being out of range, and 0x80 means a different device is already connected to it (or the phone is already connected to too many different devices). Full error list is at https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/stack/include/gatt_api.h#27

Related