How long should the device be woke with PowerManager for making sure that an activity created with BroadcastReceiver is shown?

532 Views Asked by At

I have my AlarmManager which after any hours leads to my BroadcastReceiver. So of course the device can be in IDLE(sleep) mode including password locking. I would like to know if it´s good practice and necessary using the PowerManager because https://developer.android.com/training/scheduling/wakelock.html#java says

"Creating and holding wake locks can have a dramatic impact on the host device's battery life. Thus you should use wake locks only when strictly necessary and hold them for as short a time as possible. For example, you should never need to use a wake lock in an activity. As described above, if you want to keep the screen on in your activity, use FLAG_KEEP_SCREEN_ON."

For better understanding: In the end it should be a copy of the default Android Alarm Clock.

Manifest:

    <receiver android:name=".AlarmReceiver">
        <intent-filter>
            <category
            android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

    <activity android:name=".RingtoneAlarm">
    </activity>

BroadcastReceiver:

public class AlarmReceiver extends BroadcastReceiver {
@Override
    public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyApp::MyWakelockTag");
wakeLock.acquire(10*60*1000L /*10 minutes*/);

intent.setClassName(context, "com.example.myName.myWork.RingtoneAlarm");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}

Activity opened by intent:

public class RingtoneAlarm extends AnyOfMyActivitynamesIGuess{
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ringtonealarm);
 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
   //(setShowWhenLocked(true);setTurnScreenOn(true); My sidenote: both methods are too new for most required API levels)
   //Remember to implement: PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyApp::MyWakelockTag"); wakeLock.release();
[...]
}
}

This is the only way I could make the device wake up at the exact time when phone had been in IDLE(sleep) mode and locked with a password. If I put the PowerManager into the RingtoneAlarm Activity it doesn´t work because the Activity isn´t created, therefore getWindow().addFlags(....); isn´t activated. I can´t find a way to make it work without PowerManager (as already stated: docs say it´s not good practice). What is more it feels like PowerManager is just a workaround because I only need it for that little time between BroadcastReceiver and creation of RingtoneAlarm activity and it may be deprecated in the future just like FLAG_TURN_SCREEN_ON.

So how many seconds should it be in wakeLock.acquire(X); in the BroadcastReceiver? 3 seconds is too short and doesn´t work, 10 minutes might be kind of an overkill... Or is there an even better solution without PowerManager?

1

There are 1 best solutions below

2
ianhanniballake On

As per the Restrictions to background activity starts documentation, starting an activity from the background is not at all allowed when running on an Android Q (API 29) and higher device.

As explained in that documentation:

In nearly all cases, apps that are in the background should create notifications to provide information to the user instead of directly starting an activity.

In specific cases, your app might need to get the user's attention urgently, such as an ongoing alarm or incoming call. You might have previously configured your app to launch a background activity for this purpose.

They default alarm clock has actually done this exact thing back since API 11, when the setFullScreenIntent API was added (which is also available in NotificationCompat). This allows you to add an Intent to your notification that automatically starts an activity if the device's screen is off and is the recommended practice for alarm clock apps.