简体   繁体   中英

How do I run a BLE scan in the background only if my application is alive and in the background as well and not destroyed?

My application scans for BLE devices while it is in the background so that notifications can be sent to the user if the devices stop advertising or their RSSI drops below a set limit.

However, what I've noticed is that even though my app is closed and no longer in the background, my application will sometimes still scan for BLE Devices. How can I make it so that these background BLE scans occur in the background only when my app is alive and in the background?

I'm currently disabling scans in the onDestroy callback but I've read that its not recommended since the code in there isn't always executed. This is also why my application will still scan in the background sometimes.

Below is the onDestroy callback and the code I use to start or stop scans.

@Override
public void onDestroy() {
    super.onDestroy();
    scanLeDevice(false); //stop scanning and stop notification from showing when app closed
    try {
        unregisterReceiver(mReceiverOn);
        unregisterReceiver(mReceiverOff);
        //Register or UnRegister your broadcast receiver here

    } catch(IllegalArgumentException e) {

        e.printStackTrace();
    }
    stopService();
    Log.d("lifecycle", "onDestroy: isAppRunning in on destroy");
}

 private void scanLeDevice(final boolean enable) { //need to update to non deprecated code
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && PackageManager.PERMISSION_GRANTED != getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION))
    {
        Toast.makeText(DeviceScanActivity.this, R.string.location_permission_needed, Toast.LENGTH_SHORT).show();
        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 9); //get fine location, needed for android 10
    }
    else if (enable && !scanRunning) { //starting a scan that is currently not running
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() { //Stops scanning after a pre-defined scan period. This is required if you are to scan indefinitely
                mBluetoothAdapter.stopLeScan(mLeScanCallback );
                scanRunning = false;
                if(mScanning)
                    mHandler2.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            scanLeDevice(true);
                        }
                    }, 650);
                invalidateOptionsMenu();
            }
        }, 8000);
        mScanning = true;
        scanRunning = true;
        boolean onScanner = mBluetoothAdapter.startLeScan(uuid, mLeScanCallback);
        Log.d(TAG, "scanLeDevice: onScanner " + onScanner + " isDiscovering " + mBluetoothAdapter.isDiscovering());
    } else if (enable && appNotDestroyed){ //scanRunning is true
        mScanning = true;
        mBluetoothAdapter.startLeScan(uuid, mLeScanCallback);
        Log.d(TAG, "scanLeDevice: mScanning " + mScanning + " isDiscovering " + mBluetoothAdapter.isDiscovering());
    } else { //enable is false
        mScanning = false;
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
        if(!clearHandlerHasRunnable) {
            clearHandlerHasRunnable = true;
            clearHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (!mScanning)
                        clearUnsavedDevices(mLeDevices);
                    clearHandlerHasRunnable = false;
                }
            }, 3000);
        }
    }
    invalidateOptionsMenu();
    if(!mScanning){ //clear indicators for all cells so that user isn't confused by certain indicators being on/off
        for (int i = 0; i < mLeDevices.size(); i++){
            updateViewScanFor(i);
        }
    }
}

I am no longer starting a background scan in my onPause() and then stopping it in onDestroy() in my main activity.

Instead, I am starting a foreground service in which my scanning takes place. This allows my app to stop the service, and therefore the scanning, when my app is destroyed since nothing is happening in the background.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM