2
votes

I want to develop an android app that is always listening ble advertisements, useful for beacons. The app has an activity and a background service. All BLE operations are done in service and this service executes a REST post when it finds a specific mac:

... mBluetoothAdapter.startLeScan(this); ...

public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) ...

If I run app and let smart phone apart, the screen turns off but app continues to work because I can see in REST service log that there was a call. However, more or less 3 hours later the android app stops call the rest service.

As the android service is Sticky, a stared again the app and close the app. 3 seconds later the service is started and I see rest calls beeing done. However, 15 minutes later the service stops calling rest server.

All logic is inside onLeScan() callback. So I can infer that this callback stops beeing called even though there are lots of BLE devices arround constantly advertising...

Please, any tips on this?

Thanks a lot

2

2 Answers

0
votes

First, don't use the old scan API. Use the new introduced in Lollipop. The reason for that is that you need to perform a filtered scan to make it continue forever. The filter needs to be set according to something what the advertisement data contains.

Second, use a Foreground Service to make sure your app process is not killed after a while. OR use the new API where you set a PendingIntent that is executed when a match occurs.

0
votes

In my understanding, the scanning process has no time frame. The developers need to call stopScan() to stop the scanning process. Some BLE devices need the scan() process background to get the device notifications. I think, your beacons are in that category. Three common suggestion I can share with you

  1. If you required a continues scanning process, it's better to do the scanning process in a worker thread.

  2. In Android 6 onwards, the services having drastic changes. So instead of using the service, use Job Service or WorkManager.

  3. The BLE scan method is a deprecated one. You can use this method only in Android OS 4.8. In Android OS 5 onwards, you need to use startScan() method instead.

My Scanning implementation is given below(Kotlin Version)

     /**
         * Scan The BLE Device
         * Check the available BLE devices in the Surrounding
         * If the device is Already scanning then stop Scanning
         * Else start Scanning and check 10 seconds
         * Send the available devices as a callback to the system
         * Finish Scanning after 10 Seconds
         */
        fun scanBLEDevice(isContinuesScan: Boolean) {
            try {
                mIsContinuesScan = isContinuesScan

                if (mScanThread != null) {
                    /**
                     * Already Running - No need to rescan
                     */
                    return
                }

                mScanThread = Thread(mScanRunnable)
                mScanThread.start()

                /**
                 * Stop Scanning after a Period of Time
                 * Set a 10 Sec delay time and Stop Scanning
                 * collect all the available devices in the 10 Second
                 */
                if (!isContinuesScan) {
                    mHandler?.postDelayed({
                        // Set a delay time to Scanning
                        stopScan(mDeviceObject)
                    }, BLEConstants.SCAN_PERIOD) // Delay Period
                }
            } catch (e: Exception) {
                Log.e(TAG, e.message)
            }

        }

   private val mScanRunnable = Runnable {
        if (mBluetoothAdapter != null && mBluetoothAdapter!!.isEnabled) {
            scan()
        }
    }

    private fun scan() {
        if (isLollyPopOrAbove()) {// Start Scanning For Lollipop devices
            mBluetoothAdapter?.bluetoothLeScanner?.startScan(/*scanFilters(),
            scanSettings(),*/scanCallback) // Start BLE device Scanning in a separate thread
        } else {
            mBluetoothAdapter?.startLeScan(mLeScanCallback) // Start Scanning for Below Lollipop device
        }
    }

If you need more information you can visit my blog

https://medium.com/@nithinjith.p/ble-in-android-kotlin-c485f0e83c16