Everything works fine at the beginning. After more than 1 hour, scan period become problematic. When i debug the application scan period increasing with time.(sometimes it can reach 30 minutes). I guess OS wants to save battery and increase the scan period. But what i need is fixed scan period. How can i achieve this?
I am using estimote sdk library. There was a Android AlarmManager usage for trigger next scan period. I think AlarmManager could be our problem. There is a note in docs as follow:
Note: Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to “batch” alarms together across the entire system, minimizing the number of times the device needs to “wake up” and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.
What you are observing is so called device’s deep sleep. We do use AlarmManager to get phone our of deep sleep. We will be this week investigating this issue so stay tuned (follow Android SDK released on GitHub).
Have you considered using monitoring API? That is startMonitoring on BeaconManager.
My main goal is to find the closest beacon. I guess startRanging method is preferable than startMonitoring. I don’t mind entering region. I haven’t tried monitoring API yet. But if it’s a solution, i could try. Also i can try another ways of solutions depending on your advices.
I am looking forward to new sdk release. I hope this problem will be solved.
In v0.9.2 release we did tune monitoring default scan times.
That said we have pending changes (we are testing them as we speak) for more reliable on time scanning even if phone goes into deep sleep.
I think I misread your original question. You tuned scan time to 30 minutes?
FYI: we have a notion of scan time (active scanning) and wait time (not scanning, letting battery rest).
It just have struck me. Where do you hold reference to BeaconManager? If in Activity then after one hour your activity can be stopped and destroyed. For longer periods of ranging, it is better to store BeaconManager inside you Application class.
I want to explain in detail. I am doing this operation in my custom service.
I made my service a foreground service. App is working as expected when the phone is awake.
My main problem is BeaconManager.RanginListener is not working properly when the phone is sleeping. According to my code, waiting time should be 3 seconds between two scan. As far as the phone is in the sleep mode, waiting time increasing like 3, 4, 12, 21, 30 minutes. I think phone enter deep sleep mode and waiting time is not what I want it to be.
I want to set and observe a fixed waiting time even if the phone is in the deep sleep mode.
Here is my shortened code.
public class BluetoothService extends Service {
private static final Region ALL_ESTIMOTE_BEACONS_REGION = new Region("rid", null, null, null);
public static BeaconManager beaconManager;
private static String lastSeenBeaconMAC = "";
MyBeaconRangingListener rangingListener;
private String proximityString = "";
@Override
public void onCreate() {
super.onCreate();
if (beaconManager == null) {
beaconManager = new BeaconManager(this);
}
if (rangingListener == null) {
rangingListener = new MyBeaconRangingListener();
}
beaconManager.setRangingListener(rangingListener);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
connectToService();
turnOnForegroundService("Content");
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
try {
beaconManager.stopRanging(ALL_ESTIMOTE_BEACONS_REGION);
beaconManager.disconnect();
} catch (RemoteException e) {
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void connectToService() {
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
@Override
public void onServiceReady() {
try {
beaconManager.setBackgroundScanPeriod(2000, 3000);
beaconManager.setForegroundScanPeriod(2000, 3000);
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS_REGION);
} catch (RemoteException e) {
}
}
});
}
public class MyBeaconRangingListener implements BeaconManager.RangingListener {
@Override
public void onBeaconsDiscovered(Region region, List<Beacon> beacons) {
try {
Double accuracy = Utils.computeAccuracy(beacons.get(0));
Proximity nearestBeaconProximity = Utils.proximityFromAccuracy(accuracy);
proximityString = "";
switch (nearestBeaconProximity) {
case IMMEDIATE: proximityString = "IMMEDIATE";
break;
case NEAR: proximityString = "NEAR";
break;
case FAR: proximityString = "FAR";
break;
default: proximityString = "UNKNOWN PROXIMITY";
break;
}
//Calling Rest Service according to my business.
} catch (Exception e) {
}
}
}
}
I switched to the newest SDK and tested it again.
Result is much better but problem still goes on.
Waiting time should be 3 seconds between two scan but it reaches 14 minutes. (old SDK reached 30 minutes)