question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Android O ranging in background issue

See original GitHub issue

Expected behavior

Contionusly range beacons when in proximity when app is in background / screen is off.

Actual behavior

After somewhere between 15-30 minutes of running in the background the app is killed and restarted automatically. However when restarted it does not resume ranging beacons.

Steps to reproduce this behavior

Perhaps I’ve missed something in my implementation of ranging beacons from the application class, see code below


public class ExampleApplication extends Application implements BootstrapNotifier, BeaconConsumer, RangeNotifier {


    private RegionBootstrap regionBootstrap;
    private BackgroundPowerSaver backgroundPowerSaver;
    private MainActivity mainActivity = null;
    private BeaconManager beaconManager;
    private Region r;

    @Override
    public void onCreate() {
        super.onCreate();

        createNotificationChannel(
                Constants.BACKGROUND_NOTIFICATION_CHANNEL_ID,
                R.string.beacon_scan,
                R.string.beacon_scan_desc
        );

        beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);

        beaconManager.getBeaconParsers().clear();
        beaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout(Constants.IBEACON_LAYOUT));


        // Uncomment the code below to use a foreground service to scan for beacons. This unlocks
        // the ability to continually scan for long periods of time in the background on Android 8+
        // in exchange for showing an icon at the top of the screen and a always-on notification to
        // communicate to users that your app is using resources in the background.
        //

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, Constants.BACKGROUND_NOTIFICATION_CHANNEL_ID);
        mBuilder.setSmallIcon(R.drawable.my_logo);
        mBuilder.setContentTitle("Scanning for Beacons");
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
        );

        mBuilder.setContentIntent(pendingIntent);
        beaconManager.enableForegroundServiceScanning(mBuilder.build(), 1);


        // For the above foreground scanning service to be useful, you need to disable
        // JobScheduler-based scans (used on Android 8+) and set a fast background scan
        // cycle that would otherwise be disallowed by the operating system.
        //

        beaconManager.setEnableScheduledScanJobs(false);
        beaconManager.setBackgroundBetweenScanPeriod(1L);
        beaconManager.setBackgroundScanPeriod(1100L);
        beaconManager.setForegroundBetweenScanPeriod(1100L);
        beaconManager.setForegroundScanPeriod(1L);
        this.beaconManager.setRssiFilterImplClass(RunningAverageRssiFilter.class);
        RunningAverageRssiFilter.setSampleExpirationMilliseconds(10000L);

        // wake up the app when a beacon is seen
        r = new Region("backgroundRegion",
                Identifier.parse(Constants.UUID_STRING), null, null);
        regionBootstrap = new RegionBootstrap(this, r);

        // simply constructing this class and holding a reference to it in your custom Application
        // class will automatically cause the BeaconLibrary to save battery whenever the application
        // is not visible.  This reduces bluetooth power usage by about 60%
        //backgroundPowerSaver = new BackgroundPowerSaver(this);

        beaconManager.bind(this);
        beaconManager.setDebug(true);
    }

    @Override
    public void didEnterRegion(Region region) {

        mainActivity.logToDisplay("Beacon in proximity");
    }

    @Override
    public void didExitRegion(Region region) {
        if (mainActivity != null) {

        }
    }

    @Override
    public void didDetermineStateForRegion(int state, Region region) {
        if (mainActivity != null) {
            String s = state == 0 ? "Out of distance" : "In distance";
            if(state == 1) {
                try {
                    beaconManager.startRangingBeaconsInRegion(region);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    beaconManager.stopRangingBeaconsInRegion(region);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            mainActivity.logToDisplay("Beacon switched state: " + s);

        }
    }

    public void setMainActivity(MainActivity activity) {
        this.mainActivity = activity;
    }

    private void createNotificationChannel(String notification_channel, int resIdName, int resIdDescription) {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name  = getString(resIdName);
            String description = getString(resIdDescription);
            int importance = android.app.NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(notification_channel, name, importance);
            channel.setDescription(description);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            android.app.NotificationManager notificationManager = getSystemService(android.app.NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

    @Override
    public void onBeaconServiceConnect() {
        beaconManager.addRangeNotifier(this);
    }


    @Override
    public void didRangeBeaconsInRegion(Collection<org.altbeacon.beacon.Beacon> collection, Region region) {
        if (collection.size() > 0) {

            Beacon firstBeacon = (Beacon) collection.iterator().next();
            double avgRSSI = firstBeacon.getRunningAverageRssi();

            if(mainActivity != null) {
                mainActivity.setTvBeaconRSSI(String.format("%.3f", avgRSSI));
            }

        }
    }

}

Mobile device model and OS version

Mobile Device: Oneplus 5 OS Version: 8.1.0

Android Beacon Library version

implementation ‘org.altbeacon:android-beacon-library:2+’ 2+

IMPORTANT: This forum is reserved for feature requests or reproducible bugs with the library itself. If you need help with using the library with your project, please open a new question on StackOverflow.com.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:19 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
davidgyoungcommented, Nov 13, 2018

I suspect there may be several problems here. Part if it may be related to OxygenOS, but I think the problem of ranging not restarting after the service restarts is this line of code:

if (mainActivity != null)

When the service restarts (automatically by Android OS after a crash sine the start sticky flag is set) no activities will get created, so no code after the if statement above will execute, and ranging will not start.

1reaction
AntonHellbecommented, Nov 13, 2018

Hi,

mBeaconManager.setEnableScheduledScanJobs(false); is already set. See the code I posted in the issue description.

Br, Anton

Read more comments on GitHub >

github_iconTop Results From Across the Web

AltBeacon Ranging in the background (when not killed)
First problem is that didDetermineState returns OUTSIDE - I made condition there, INSIDE --> start ranging, OUTSIDE --> stop ranging, so things ...
Read more >
Is it possible to use beacon ranging in the background?
Ranging beacons works always when the app is running, either in the foreground or in the background. However, as soon as the user...
Read more >
Phone makers are breaking your favorite apps with reckless ...
Starting in Android 8.0 Oreo, Google further imposed background execution limits that trimmed down the sort of resources available to apps ...
Read more >
Device compatibility overview - Android Developers
However, you do need to consider whether your app is compatible with each potential device configuration. Because Android runs on a wide range...
Read more >
Sensors Overview - Android Developers
As a result, devices can include a variety of sensors in a wide range of configurations. If your application relies on a specific...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found