I am calling a background
Service
setRepeating()
AlarmManager
onCreate()
UserTrackingReceiver.java
registerUserTrackingReceiver()
public static void registerUserTrackingReceiver(Context context) {
try {
Intent intent = new Intent(context, UserTrackingReceiver.class);
boolean alarmUp = (PendingIntent.getService(context, 1001, intent, PendingIntent.FLAG_NO_CREATE) == null);
if (alarmUp) {
Calendar calendar = Calendar.getInstance();
if (calendar.get(Calendar.MINUTE) > 0 && calendar.get(Calendar.MINUTE) <= 30) {
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
} else if (calendar.get(Calendar.MINUTE) > 30) {
if (calendar.get(Calendar.HOUR_OF_DAY) == 23) {
calendar.set(Calendar.HOUR_OF_DAY, 0);
} else {
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
}
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
} else {
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
}
PendingIntent sender = PendingIntent.getService(context, 1001, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_HALF_HOUR, sender);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class UserTrackingReceiver extends Service
implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
@Override
public void onCreate() {
super.onCreate();
Calendar calendar = Calendar.getInstance();
Util.appendLog("Tracking Alarm Called on: " + calendar.get(Calendar.HOUR_OF_DAY) + " : " + calendar.get(Calendar.MINUTE) + " : " + calendar.get(Calendar.SECOND));
stopSelf();
}
}
appendLog()
public static void appendLog(String text) {
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
File logFile = new File(baseDir + "/" + Constant.AppNameSuper + "/log.txt");
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- Tracking Alarm Called on: 0 : 0 : 31(Start From 12:00 Night)
- Tracking Alarm Called on: 1 : 10 : 27
- Tracking Alarm Called on: 3 : 5 : 25
- Tracking Alarm Called on: 6 : 55 : 31
- Tracking Alarm Called on: 7 : 0 : 6
- Tracking Alarm Called on: 7 : 30 : 0
- Tracking Alarm Called on: 8 : 0 : 6
- Tracking Alarm Called on: 8 : 30 : 0
- Tracking Alarm Called on: 9 : 0 : 6
- Tracking Alarm Called on: 9 : 30 : 0
- Tracking Alarm Called on: 10 : 0 : 0
- Tracking Alarm Called on: 0 : 0 : 27(Start From 12:00 Night)
- Tracking Alarm Called on: 0 : 30 : 1
- Tracking Alarm Called on: 1 : 0 : 1
- Tracking Alarm Called on: 1 : 30 : 2
- Tracking Alarm Called on: 2 : 0 : 1
- Tracking Alarm Called on: 2 : 30 : 1
- Tracking Alarm Called on: 3 : 0 : 1
- Tracking Alarm Called on: 3 : 30 : 1
- Tracking Alarm Called on: 4 : 0 : 1
- Tracking Alarm Called on: 4 : 30 : 29
- Tracking Alarm Called on: 5 : 0 : 1
- Tracking Alarm Called on: 5 : 30 : 2
- Tracking Alarm Called on: 6 : 0 : 30
- Tracking Alarm Called on: 6 : 30 : 1
- Tracking Alarm Called on: 7 : 0 : 1
- Tracking Alarm Called on: 7 : 30 : 1
- Tracking Alarm Called on: 8 : 0 : 1
- Tracking Alarm Called on: 8 : 30 : 1
- Tracking Alarm Called on: 9 : 0 : 32
- Tracking Alarm Called on: 9 : 30 : 1
- Tracking Alarm Called on: 0 : 0 : 7(Start From 12:00 Night)
- Tracking Alarm Called on: 0 : 30 : 3
- Tracking Alarm Called on: 1 : 0 : 6
- Tracking Alarm Called on: 1 : 30 : 1
- Tracking Alarm Called on: 2 : 0 : 32
- Tracking Alarm Called on: 2 : 30 : 3
- Tracking Alarm Called on: 3 : 1 : 50
- Tracking Alarm Called on: 3 : 30 : 5
- Tracking Alarm Called on: 4 : 1 : 58
- Tracking Alarm Called on: 4 : 31 : 14
- Tracking Alarm Called on: 5 : 0 : 1
- Tracking Alarm Called on: 5 : 30 : 1
- Tracking Alarm Called on: 6 : 2 : 1
- Tracking Alarm Called on: 6 : 30 : 1
- Tracking Alarm Called on: 7 : 0 : 1
- Tracking Alarm Called on: 7 : 30 : 1
- Tracking Alarm Called on: 8 : 0 : 1
- Tracking Alarm Called on: 8 : 30 : 4
- Tracking Alarm Called on: 9 : 1 : 44
- Tracking Alarm Called on: 9 : 30 : 1
- Tracking Alarm Called on: 0 : 1 : 25(Start From 12:00 Night)
- Tracking Alarm Called on: 0 : 30 : 0
- Tracking Alarm Called on: 1 : 31 : 41
- Tracking Alarm Called on: 2 : 39 : 52
- Tracking Alarm Called on: 3 : 0 : 25
- Tracking Alarm Called on: 3 : 30 : 58
- Tracking Alarm Called on: 4 : 0 : 25
- Tracking Alarm Called on: 4 : 30 : 56
- Tracking Alarm Called on: 5 : 30 : 51
- Tracking Alarm Called on: 7 : 18 : 55
- Tracking Alarm Called on: 7 : 30 : 0
- Tracking Alarm Called on: 8 : 0 : 25
- Tracking Alarm Called on: 8 : 30 : 43
- Tracking Alarm Called on: 9 : 0 : 3
- Tracking Alarm Called on: 9 : 30 : 25
- Tracking Alarm Called on: 10 : 0 : 25
- Tracking Alarm Called on: 10 : 30 : 4
- Tracking Alarm Called on: 11 : 1 : 52
- Tracking Alarm Called on: 11 : 30 : 27
- Tracking Alarm Called on: 12 : 1 : 6
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()
), aquire 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.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:
Use one of the two methods above and reschedule the alarm every time it fires
Check out this answer
(according to the documentation above, your app should be eligible for whitelisting)