2

My alarm is killed when OS kills the app. I thought that was one of the points of an Alarm, that it would keep running even though OS killed the app? I check the life of the Alarm using the "./adb shell dumpsys alarm" command, and every time OS kills my app, the Alarm is also gone. How I start my Alarm:

public static void startLocationAlarm(Context context){
    if(ActivityLifecycleHandler.isApplicationInForeground()) {
        return;   // If App is in foreground do not start alarm!
    }

    String alarm = Context.ALARM_SERVICE;
    AlarmManager am = ( AlarmManager ) context.getSystemService( alarm );

    Intent intent = new Intent(locationBroadcastAction);
    PendingIntent pi = PendingIntent.getBroadcast( context.getApplicationContext(), 0, intent, 0 );

    int type = AlarmManager.ELAPSED_REALTIME_WAKEUP;
    long interval = ONE_MINUTE;
    long triggerTime = SystemClock.elapsedRealtime() + interval;

    am.setRepeating(type, triggerTime, ONE_MINUTE, pi );    
}

To add some more context, I am trying do some location operation in a service (not IntentService) in background. Here is my receiver. Used Wakeful because I did not want the service to be killed before it was done.

public class LocationBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent ) {

    Intent myIntent = new Intent( context, LocationServiceAlarmOwnGoogleClient.class );
    //context.startW( myIntent );
    LocationBroadcastReceiver.startWakefulService(context, myIntent);
}
}

For some more information: I cancel the alarm in OnStart method of several activities that the user can return to after having it in the background. I do not know if that can cause this weird behaviour? Here is my cancel method:

public static void stopLocationAlarm(Context context){
    Intent intent = new Intent(locationBroadcastAction);
    PendingIntent sender = PendingIntent.getBroadcast(context.getApplicationContext(), 0, intent, 0);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
    alarmManager.cancel(sender);
}
Slagathor
  • 852
  • 7
  • 23
  • That is the default behavior – Shaishav Aug 09 '16 at 14:35
  • "every time OS kills my app, the Alarm is also gone" -- please explain, in detail, what you mean by "OS kills my app". – CommonsWare Aug 09 '16 at 14:37
  • @Shaishav Aaah, okey. I thought Alarms were suppose to keep living even though the app was killed by OS. How can I make it keep living even though OS kills it? – Slagathor Aug 09 '16 at 14:37
  • I'm going to point to another answer by Commonsware: http://stackoverflow.com/questions/9101818/how-to-create-a-persistent-alarmmanager – Shaishav Aug 09 '16 at 14:39
  • @CommonsWare when I put my app my in background for a while the system will kill it (or that is what I think it does, cause It suddenly shows up as DEAD in Android Studio). I guess it does it to save resources or something. And when that happens the Alarm is canceled. I dont mind that the Alarm is canceled if the user is killing it. – Slagathor Aug 09 '16 at 14:39
  • no that is not default behaviour, if the setRepeating is set, it should go off. Only when the device is restarted, alarms should be set again – DennisVA Aug 09 '16 at 14:40
  • If you are testing on Marshmallow, the setRepeating should be changed i think because of Doze – DennisVA Aug 09 '16 at 14:42
  • What device is this? The behavior that you describe is not normal. – CommonsWare Aug 09 '16 at 14:43
  • @user2395334 ah okey. Why not? Starting the Alarm actually works just fine and I dont want to start the alarm if app is in the foreground. So its for security. Is just the problem with system canceling my alarm while app is in background – Slagathor Aug 09 '16 at 14:54
  • This may be due to the debug version of the app. Try testing the Google Clock and see if it follows the same behaviour. – Piyush Aug 09 '16 at 14:57
  • @Piyush okey, so it may have a different behaviour when its the production version? Is not that a little bit weird? Anyway, what is the Google Clock? And how do I test if it follows the same behaviour? (Sorry for all the questions) – Slagathor Aug 09 '16 at 15:00
  • @CommonsWare actually I am testing on kit kat at the moment. 4.4.2 API 19. Honor 6 Huawei. – Slagathor Aug 09 '16 at 16:30
  • Try testing on other hardware. Huawei is not bound by the Google Play compatibility requirements, and so they may have modified that Android build to get rid of alarms prematurely. You might also consider reducing the frequency of the alarms to see if that helps. You might also poke around your Settings app to see if there is anything Huawei may have added for power saving that you could disable, to see if that is the source of the difficulty. – CommonsWare Aug 09 '16 at 17:03
  • @CommonsWare thank you for the tip! Your answer brought me to another StackOverflow question that may be the source of my problem. http://stackoverflow.com/questions/34729966/alarmmanager-not-working-in-several-devices I will try it out. – Slagathor Aug 09 '16 at 17:59
  • The answer in http://stackoverflow.com/questions/34729966/alarmmanager-not-working-in-several-devices solved my problem! The alarm did not work due to some Huawei specific battery settings – Slagathor Aug 09 '16 at 19:16

2 Answers2

0

You can add service which listens to the phone's turning on callback. add this permission into the manifest

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

and register reciever

<receiver android:name=".util.notification.local.MyBootCompletedService">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
</receiver>

public class MyBootCompletedService extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        AlarmReceiver.startLocalNotificationService(context);
    }
}
  • Hi! Thanks for the answer! But I do not want the Alarm or service to run on boot up. Only if the Users have already opened my app, and then put it in the background do I want the Alarm to run that triggers a the service. – Slagathor Aug 09 '16 at 15:04
0

The error that caused the Alarm to be canceled had actually nothing to do with the code, but had to do with special battery settings on Huawei devices. If your app is not set as "protected" in "protected apps", the system will cancel your alarm when it kills the app. Adding your app to "protected apps" will solve this problem. Same goes for Xiaomi devices. Have to add them to "Protected apps", then the Alarm will work as intended. Thank you @CommonsWare for leading me to the solution.

Slagathor
  • 852
  • 7
  • 23