I am calling a background Service
at interval of 30 min to read the latitude/longitude of current location and sending it to server by POST API .
I am using
The problem might be your PendingIntent
calling a Service
. The device can go back to sleep before your Service
finishes (or even starts) execution.
I'd suggest you to use a BroadcastReceiver
instead (since a WakeLock
is guaranteed during onReceive()
).
Acquire a WakeLock
in onReceive()
, start your Service
from there and release the WakeLock
from the Service
, when appropriate.
To simplify this process you can use the WakefulBroadcastReceiver helper class:
PendingIntent.getBroadcast()
instead of PendingIntent.getService()
.IntentService
from onReceive()
by calling WakefulBroadcastReceiver.startWakefulService()
.onHandleIntent()
and call WakefulBroadcastReceiver.completeWakefulIntent()
when finished.For example, a BroadcastReceiver
that starts a wakeful Service
:
public class ExampleReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent wakefulServiceIntent = new Intent(context,
ExampleWakefulService.class);
WakefulBroadcastReceiver.startWakefulService(context,
wakefulServiceIntent);
}
}
And the Service
:
public class ExampleWakefulService extends IntentService {
private static final String NAME = "com.example.ExampleWakefulService";
public ExampleWakefulService() {
super(NAME);
}
@Override
protected void onHandleIntent(Intent intent) {
// doing stuff
WakefulBroadcastReceiver.completeWakefulIntent(intent);
}
}
Also, check out this article from the developer's guide on keeping the device awake.
On API level 23+ you have to deal with Doze.
From the documentation:
To help with scheduling alarms, Android 6.0 (API level 23) introduces two new
AlarmManager
methods:setAndAllowWhileIdle()
andsetExactAndAllowWhileIdle()
. With these methods, you can set alarms that will fire even if the device is in Doze.
Unfortunately there is no alternative for setRepeating()
, so you have two choices:
As per Android developer document Note:
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
You need to use a BroadcastReceiver
and a wakelock to reliably make this happen when the device is idle. Also, note that starting with API 19 alarms are inexact by default, which will play into this. if you are targeting API 21 or newer, consider using JobScheduler
. Similar to this post Alarm Manager with 2 pending intents only 1 works?