John Poust
John Poust

Reputation: 1

Keep android app awake until user terminates

Summary: My alarm App is killed despite use of wake lock and configuration on phone to allow unrestricted battery use. The app is killed if the app is open and active as well as the case when the phone is locked (screen off) - after about 3 minutes of operation.

The purpose of the app is to send a periodic audible alarm to a user every 5 seconds as a reminder to do a task until the task is done, and when the task is done, the user turns the alarm off. Because the app is being closed by the system, this app cannot fulfill its purpose.

The app uses Alarm Manager to send a message every 5 seconds to a Result Receiver object and the onReceiveResult method in the Result Receiver class calls the code to make the audible alarm annunciate. In the code below, Init() acquires the wake lock, instantiates alarmMgr and sets a pending intent to signal the alarm. Please note, Init() is called from a foreground service with FOREGROUND_SERVICE as well as the foreground service declared in the AndroidManifest.XML. All seems to work fine for about 3 minutes (timing varies, between approximately 2:30 and 3:30) when the app is killed. The app gets killed both in the case when the app is visible on the phone's screen and the case when the phone is locked (and screen off). As an aside, if the app is visible, the phone then shows the home screen after the app is killed. I am using a Samsung S21 phone and in Apps | Battery - my app is set to Unrestricted (the text reads "Allow this app to use battery in the background without restriction" on this option). Note that in the settings option "Settings | Battery | Background usage limits | Never auto sleeping apps", my app is not listed here with other apps installed on the phone, so I cannot make use of this option.

Note: WorkManager is not an alternative due to the 15 minute minimum scheduling interval of WorkManager

Note also: this problem is similar to the question "Keep android app awake at all timesKeep Android app alive for a while" except the solution in this post did not work for me.

public void Init(Context context, int iPeriod, NextStep iNextStep, boolean iRepeat){

    mPeriod = iPeriod;  // Save timer period
    mRepeat = iRepeat;  // Save repeat
    mResultReceiverInstance = new ResultReceiverInstance(null, iNextStep);

    // Invoke wake lock, do not let OS put it so sleep
    powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,   
    "SmartTimer:DoUserFeedback2");
    wakeLock.acquire(10);
    if ( ! wakeLock.isHeld()) {
        // todo send Notification.
        Log.e(String.valueOf("Warn"), "WakeLockNotAcq");
    }

    // Setup timer
    alarmMgr =
            (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmObjInstance.class);
    intent.putExtra("Running", true);
    pendingIntent = PendingIntent.getBroadcast(
            context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT |
                    PendingIntent.FLAG_IMMUTABLE);

    // Set alarm wait period
    SetTimeNext();
}

// Stop timer by canceling pending intent
public void StopTmr(){
    pendingIntent.cancel();
    wakeLock.release();
}

// Set wait period of timer
public void SetTimeNext()
{
    Calendar time = Calendar.getInstance();
    time.setTimeInMillis(System.currentTimeMillis());
    time.add(Calendar.SECOND, mPeriod);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                    pendingIntent);
    }
}

// Handle message received when timer expires
@Override
public void onReceive (Context context, Intent intent){
    // Send message to Result receiver to invoke time tick
    Bundle bundle = new Bundle();
    mResultReceiverInstance.send(0, bundle); // Payload set to default values
    if (mRepeat) {
        SetTimeNext();
    }
}

I would appreciate any suggestion on how to keep my app running and any references to documentation that explain the logic the system uses for killing apps. Thanks

Upvotes: 0

Views: 49

Answers (0)

Related Questions