Some apps in Android seem to be able to keep the screen on beyond the normal timeout (presumably done with FLAG_KEEP_SCREEN_ON), but on exiting the app lock the screen. I've seen this e.g. in navigation apps, that keep route guidance open, but the screen locks as soon as you leave the app.
How is this done?
(Note that the lock should happen when the application is goes into the background, not just when an activity is replaced by another activity within the same application.)
I managed to partially figure this out, based on "Launch activity when user taps on a notification from the lockscreen". Here is an example. Use this project https://github.com/googlesamples/android-CustomNotifications/ (e.g. Android Studio: File > New > Import Sample; look for ("Custom Notifications") and replace onCreate like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.sample_main);
}
and in the manifest add
<activity ...
android:showOnLockScreen="true"
...
You now observe that the activity persists if
You press power button to turn off the screen. Press power button to activate screen, and your activity resumes without need to unlock screen.
You let the screen time out: Again, press power button to activate screen, and your activity resumed without need to unlock screen.
But: Once the screen has been locked at least once (through timeout or power buttons), then, when you navigate away from the app, the screen locks (which provides a partial answer to Lock screen programatically when exiting app).
However, it doesn't work when you navigate away before the screen has been locked at least once. Does anybody have suggestions?
Related question here: Launch activity when user taps on a notification from the lockscreen (secure unlock)
Related
So my scenario is as such.
Let's say there is a MainActivity, which only job is to start, call installSplashScreen().setKeepOnScreenCondition { true } to show the Splash screen using the new backward compatible APIs, and then after checking some state it does startActivity(SomeActivity); finish()
Now we're on the SomeActivity and if we press the home button, the app is gone on the background. Then if we click on the launched icon, the SomeActivity is launched correctly, and the MainActivity's onCreate is never called, therefore the splash screen does not show again, and the SomeActivity shows instantly.
But if instead of pressing the home button, we press the back button, and the app is backgrounded that way, then when we click on the launcher icon, the MainActivity's oncreate is called again, and the splash screen icon flashes for a tiny fraction too making it look jarring.
My question is, does this sound like it's some wrong configuration on my part, or am I stuck with this behavior as long as I am not on a single activity architecture?
You are confused. Pressing the BACK button does not "send the app to the background". The default behaviour of the BACK button (assuming that you don't override this and provide your own behaviour) is to finish the current Activity. Normally this will take the user to the previous Activity in the current task. In your case, there is no other Activity in the task stack, so the current task is empty. This may appear to the user as "the app is sent to the background", but in reality there is nothing in the background. Your app's task is empty and so it is gone.
When the user then taps the app icon on the HOME screen or taps on the app's task in the list of recent tasks, there is no existing task to bring to the foreground, so the app is started again by creating a new task and launching the root Activity (in your case MainActivity) into the newly created task.
If you want the BACK button to just put your app into the background (instead of calling finish() on SomeActivity, which is the default behaviour) then just override onBackPressed() in SomeActivity and do this instead:
moveTaskToBack(true);
It seems like there is no solution to what I am facing as long as the Activity I want to resume to is not the Launcher activity.
From the the docs:
"Root launcher activities are activities that declare an Intent filter with both ACTION_MAIN and CATEGORY_LAUNCHER. These activities are unique because they act as entry points into your app from the app launcher and are used to start a task.
System behavior on Android 12 and higher
The system moves the activity and its task to the background instead of finishing the activity. This behavior matches the default system behavior when navigating out of an app using the Home button or gesture."
Reading the docs about the new back behavior on Android 12 and onwards tells us that pressing back when you got nothing else on the stack will act as if you pressed the home button.
There's a big exception here, and that is that when you re-open the application, if the one you just popped was not the launcher activity, it will then still need to launch that launcher activity and can't resume from where you left off in a hot state, exactly the reason why I am seeing the splash screen again.
So I think my best bet is to either ignore this for now, or fix my app to be a single-activity app, or at least keep the launcher activity be the top-level one that you exit the app from by pressing back
To indicate a couple of examples, if one wants to experience what I mean, the reproduction steps are to:
Open the app
Press the back button which will send you out of the app to the home screen
Click on the app icon again
As of today, apps like Google Photos, and Google Podcasts don't show the splash again. In contrast, apps like Google Maps, Twitter, Spotify do show the splash again for a brief second.
to call the launcher activity every time you have to clear the stack that means you have to use a flag in your manifest to tell your app not to keep activity in background try android:launchMode="singleTask" inside your activity tag in manifest the activity that you want to be killed everytime you go to background, and as far as how much time splash should be showing you can use timer for that after the timer is finished then your someActivity will be called.
I am developing a small app which shows passwords of the user through a Dialog screen.
When home button is pressed, I need to dim the screen (on the multi tasking window) so that any other person cannot see the password.
When user re-opens the app, it asks an application lock. But if the user leaves the password Dialog open and presses the home button, dialog and the password which user last looked at stays visible (on the multi tasking window) for a while (3-4 seconds!!) until a new dialog asks the lock.
So far I tried ever possible dialog.dissmiss() options. Dialog dismisses only when app is opened again (until a new lock dialog appears) even I put dismiss() in onPause, onStop etc.
Any idea appreciated.
I also tried,
android.os.Process.killProcess(android.os.Process.myPid());
this.finish();
System.exit(0);
none of them actually worked.
Suggestion 1: Double-check your implementation. Tying your dialog to the activity lifecycle seems like a good idea (especially to avoid leaked window errors as described here)
The following example works out well for me (with coachMark being derived from Dialog)
#Override
protected void onResume()
{
log.debug("onResume");
super.onResume();
// Show the coachMark depending on saved preference values
coachMark.mayBeShow();
}
#Override
protected void onPause()
{
log.debug("onPause");
// Hide the coachMark if it is showing to avoid leakedWindow errors
coachMark.maybeHide();
super.onPause();
}
onPause definately gets called when you press the home button, so if this approach does not work for you, try not recreating the dialog in the restarting part of the acitivty lifecycle (onRestart(), onStart() and onResume()) and see, if it gets dismissed correctly.
Suggestion 2: Should all of the above fail, you might consider overriding the home button as described here. I highly advise against it though, since this may cause the app to work in an way that the user does not expect it to.
I need show PIN Code activity after that (we have App with many Activities):
User press hardware button "Home" and go back to App.
List item App Screen go to sleep mode then go back.
What ways do I need to use?
capture home key event(KeyEvent.KEYCODE_HOME) and sleep event(Intent.ACTION_SCREEN_OFF) ,use a variable to record it.
when go back to app activity judge the vaviable and show your PIN code activity.
I want to disable the lock screen in a certain app. My problem is that this also disables the lock screen for the whole phone. So I added lock.reenableKeyguard(); to the onPause() method, but this is called not only when the user exits the app but everytime a new activity starts in that app. Do I have to disable the lock screen in every activity and add this onPause method? Is there way to manage this only in the first activity that is shows when the app starts?
Btw I also reenable the lock screen in the onStop and onDestroy methods. The other problem with onPause is that it is also called when I turn off the phone's screen (by pressing the power button or what is that called), so when I first open the app, I turn off the screen then turn it on, there is no lock screen, but when I turn it off-on again, there is it, as I reenable it in the onPause method.
After playing with this a couple of hours I figured out I forget to implement onResume():
public void onResume() {
lock.disableKeyguard();
super.onResume();
}
This way every time I open the activity/turn on the screen, the lock screen is disabled.
Hi my app has 3 activities one of which is a dialog. I've done this by using this code in the AndroidManifest.xml
android:theme="#android:style/Theme.Dialog"
the application also has a service which can open the dialog even if the application is not visible, however when it does this it also opens one of the other activities in the background. Is there a way to stop this happening so it opens the dialog in front of the current activity (even if the activity is from a different application)?
Thanks,
ng93
I solved this by adding:
android:taskAffinity=".MyDialog"
to my dialog in the AndroidManifest.xml. Then it is not related to your other tasks and can be shown without bringing up the suspended activity.
You're not able to display something in front of another application's activity. "in front" is somewhat ambiguous, so I'll clarify in that your application can't simultaneously share the screen with another application.
The way I understand it, Android's design inherently requires that when you're doing something on-screen, your app's process/task is in the foreground and in focus, thus bringing the other activities for that task into focus. This implies that other applications are not running with UI focus while your application is in focus.
This means that, for example, when your app launches an activity, it brings your app's stack of activities into focus and puts the new activity (in this case, your dialog box) on top of your app's stack. The result is that if you hit 'back' while displaying the dialog, you'll go back to the activity that was previously displayed. If the stack is cleared of previous activities, 'back' will take you to the application that was previously being displayed on screen.
There are ways of clearing the stack such as: http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP
Depending on your scenario you might want to clear the stack, or you might "exit" the app when the user closes the dialog. Additionally, the dialog activity could override onBackPressed so that if the user hits 'back' the activity "exits" your app, returning the user to what they were doing before the dialog.
Further reading for activities and stacks: http://developer.android.com/guide/topics/fundamentals.html#acttask
i ended up closing all my apps activities before opening the dialog activity, not ideal but seems like the only way to get the functionality im after