6

I am using Android Beacon Library for BLE scanning with example. It works fine in foreground for both monitoring and ranging. However, for background, it only works for the cases of pressing "Home" in app and screen off. It is not work when I kill the app from task switcher. In the example, I cannot find anything like Service to make things working in background.

Questions:

  1. Does Android Beacon Library support background scanning if the app is killed in task switcher?
  2. If so, how to do this? Any example?
Rice
  • 155
  • 3
  • 11
  • Well in that case while app is not running in background you should use `Broadcast Receiver` and a `Service`. Set `Filters` for your broadcast on Bluetooth connect (start service for beacons) and disconnect (stop service for beacons) – Zubair Ahmed Nov 04 '15 at 04:30
  • Try `Estimote` beacons they have their own `SDK` and implementation. I've made an app in which i used these its very useful for any beginner to understand about Android Beacons and BLE. Try this from this link https://github.com/Estimote/Android-SDK – Zubair Ahmed Nov 04 '15 at 04:38
  • 1
    @ZubairAhmadKhan iBeacon Library search for Estimote beacons as well as custom beacons. – Dhruv Nov 04 '15 at 05:40

3 Answers3

4

I worked with android iBeaon library in that for background scanning I created a service and in service I defined both monitoring and ranging. I start the service when application is distroy and its work for me. Create new service like this.

public class Beaconservice extends Service implements IBeaconConsumer {
private ArrayList<IBeacon> arrayL = new ArrayList<IBeacon>();
private BeaconServiceUtility beaconUtill = null;
private IBeaconManager iBeaconManager = IBeaconManager.getInstanceForApplication(this);
private Handler hand;
private Runnable runn;
private int count = 30;



@Override
public void onIBeaconServiceConnect() {
    iBeaconManager.setRangeNotifier(new RangeNotifier() {
        @Override
        public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons, Region region) {
            arrayL.clear();
            arrayL.addAll((ArrayList<IBeacon>) iBeacons);
            if(count>0){
                count=0;    
            }
        }
    });

    iBeaconManager.setMonitorNotifier(new MonitorNotifier() {
        @Override
        public void didEnterRegion(Region region) {
            Log.e("BeaconDetactorService", "didEnterRegion");
            // logStatus("I just saw an iBeacon for the first time!");
        }

        @Override
        public void didExitRegion(Region region) {
            Log.e("BeaconDetactorService", "didExitRegion");
            // logStatus("I no longer see an iBeacon");
        }

        @Override
        public void didDetermineStateForRegion(int state, Region region) {
            Log.e("BeaconDetactorService", "didDetermineStateForRegion");
            // logStatus("I have just switched from seeing/not seeing iBeacons: " + state);
        }

    });

    try {
        iBeaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
    } catch (RemoteException e) {
        e.printStackTrace();
    }

    try {
        iBeaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", null, null, null));
    } catch (RemoteException e) {
        e.printStackTrace();
    }

}


@Override
public IBinder onBind(Intent arg0) {
    return null;
}
@Override
public void onCreate() {
    beaconUtill = new BeaconServiceUtility(this);
    Log.e("UUID","start service");

    hand = new Handler();
    runn = new Runnable() {

        @Override
        public void run() {
            count ++;
            hand.postDelayed(runn, 1000);
        }
    };

    hand.post(runn);
    super.onCreate();

}
@Override
@Deprecated
public void onStart(Intent intent, int startId) {
    beaconUtill.onStart(iBeaconManager, this);
    beaconUtill = new BeaconServiceUtility(this);
    super.onStart(intent, startId);
}
@Override
public void onDestroy() {
    beaconUtill.onStop(iBeaconManager, this);
    super.onDestroy();
}
}

In AndroidManifest.xml

 <service android:name="com.beacone.keyfinder.app.Beaconservice" >
 </service>
Narendra Motwani
  • 1,085
  • 10
  • 20
  • Is "android iBeacon library" you mentioned the same as [Android Beacon Library](https://github.com/AltBeacon/android-beacon-library)? And would you please share a bit more of how you do this by some code example? – Rice Nov 04 '15 at 09:18
  • 1
    The demo is just showing scanning in foreground and cannot work in background. Please advise for what your service do or bind to to get this done. Thanks. – Rice Nov 05 '15 at 05:35
  • No problem its my plesure – Narendra Motwani Nov 09 '15 at 05:13
4

Yes, the Android Beacon Library will continue detecting beacons after the app is killed, but it can take time for scanning to resume. See here for details: http://altbeacon.github.io/android-beacon-library/resume-after-terminate.html

The library uses an AlarmManager to accomplish this, and the scanning can take up to five minutes to resume.

The reference app you link to actually has an example of how to set this up using the RegionBootstrap class. A more descriptive example is in the code examples under the Starting an App in the Background section here: http://altbeacon.github.io/android-beacon-library/samples.html

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • I did take a look to this and tried the example. But I cannot see it worked after the app is killed. (Around 30 mins after killing the app, I turn on a beacon but the app didn't scan and notice) Did you try and would you please provide more details on how you do this? – Rice Nov 05 '15 at 05:44
  • 1
    The default background scan period is onece every 5 minutes on Android 4.x. So after killing the app from the task switcher, it can take five minutes to resume the scanning service, then up to another five minutes before an active scan cycle starts. You might also try connecting power, as this is used as a secondary way of triggering a restart of scanning if Alarms fail. – davidgyoung Nov 05 '15 at 11:36
  • I was wondering how does the scanning restart in 5 minutes if the AlarmManager has a minimum limit of 15 minutes? – Parth Parekh Jul 19 '19 at 17:22
  • 1
    The comment above is from four years ago, and was universally true when written, but now only true for Android 4-7. Since then, Android 8 was released blocking background services. For Android 8+, it will take 0-15 minutes to resume scanning after the app is killed, the same as the job interval. So on average it will take 7.5 minutes. – davidgyoung Jul 20 '19 at 04:31
  • @davidgyoung will it be possible to search more rapidly using a never-ending forground service? – ruben Mar 26 '20 at 20:15
-2
  1. No, nor does any other app. Killing a task via Task Switcher means killing the process of that app, and since your background scan relies on a service, that service is killed too since services don't start their own process.

  2. You can probably have an AlarmManager that periodically checks if your service is running and starts it automatically if it's not, but I'd imagine that would hit the battery big time if you set the interval too low.

josephus
  • 8,284
  • 1
  • 37
  • 57
  • 1
    while it is true that killing an app from a task switcher does kill all processes, it is possible for an app to restart itself so background services can run using various techniques. The Android Beacon Library does this with the AlarmManager. See my answer above. – davidgyoung Nov 04 '15 at 14:44