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
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.
This is the scenario. I have 2 activities in my application and a Dialog activity that is started when I click on the notification created by my application.
The problem is that when I click on the notification, only the Dialog should show, not the other activity of my app, if it was stopped on pressing the home button.
When I close my application by pressing the back button, the dialog activity shows the dialog, but when the application is running in the background, that activity also opens up on creating the dialog activity.
I use #android:style/Theme.Dialog for my dialog activity.
How to only show the Dialog activity, not other activities in the backgroud?
The solution to the OP issue is setting a different Task affinity for that activity in the Manifest.
<activity android:name="MyIndependentActivity"
android:theme="#android:style/Theme.Dialog"
android:taskAffinity="a_unique_id">
The taskAffinity string must be different from the package name (com.whatever.myapp)
I also use android:excludeFromRecents="true", to hide the dialog from the recent apps list, as it usually makes no sense returning to a dialog.
More info: http://developer.android.com/guide/components/tasks-and-back-stack.html#Affinities
Yeah that'll happen.
When you declare a theme of Dialog it affects the activity lifecycle and the previous activity doesn't go into onStop so some Android functions still think it's the active activity which is technially true as your dialog Activity is acting like a dialog.
One possible work around if you don't 'care' that you can see the previous activity behind the dialog is to change the dialog to be a DialogFragment, put the theme of dialog on the fragment and show this in it's own activity, that'll do it.
The way I have done this (and this can't be the best way to do this) is to have some logic in the activity.onPause() and activity.onResume() methods, that will perform actions based on what I want. My experience is more around separate activities and transitioning between them than using dialogs alot.
You can pass information between activities through setResult(). This will enable you to work out why the child activity has decided to close. That combined with the onResume function should enable you to disable the parent activity.
To override the dialog so that the other activity is not visible behind it, is probably to use the onPause() method to make it go translucent.
I have found onStop() very irratic to use and often unnecessary. The reason for this, is that it is called unpredictably from a developers point of view because onStop can be called based at strange times based on whether the OS has enough memory etc. onPause however in my experience is always called predicably.
Here i have a few activities that consist different menus in my app..
The problem is that i want to add a are you sure popup box to exit the current menu and return back but calling finish() method on the click event of yes button of popup box causes all activities to terminate and app exits...
I want to make a way to terminate only the foreground activity and
return to last activity programatically (i.e without using back key)
Can u post some source code regarding how you start you new activities? Are you starting multiple activities at all? finish() method only finishes the current activity and not the entire stack of activities, thus the system automatically brings to front the previous activity from the stack. I can't understand your question please provide some further details.
I'm ware of androids life cycle and that it's not needed to add a "exit" button in the application.
But still, this back button stuff isn't really working out well.
You maybe know this issue from the default SMS-App that android comes with: you open it when you get a new message and exit it using the menu button or something else.
After like 20 times doing this, you then decide to exit the app using the back button, what happens? you have to go back though 20 views. every time you press back you return to the "all messages (by sender)" listview and when you press back there again you return to the message opend 20-1 (message 19). again you press back and return to the listview and again you press back and end up at message 18. till, after40 times pressing back, you finally exit the messanger app.
same happens when for example you got a action bar with a "home" icon which opens the main screen of your app. the user picks a action and the new activity starts. than the user clicks the home button and returns to the main screen. when pressing the back button - no matter if you call finish() in the onButtonBack listener or not, you the user would expect the app to exit, but in fact the app returns to the previous activity which is wrong.
such cycleing may happen for various reasons, thats why - even thought i'm aware of the supposed to be lifecycle of android - i wan't to EXIT (& destroy) the app when pressing back within a defined activity.
calling finish() dosn't help. if there's a previous activity it will re-open it. calling system.exit(0) isn't nice to do.
so: whats the right way to prevent such back-press-cycles and/or exit a application (WITH destruction)?
for better illustration of what i want to achieve: consider A, B, C being activities. a arrow (-->) illustrations a new intent call from the activity leftside of the arrow, rightside of the arrow represents the activity that is called. ex.: A --> B means activity A starts activity B. now here's what i want:
1) A --> B --> C pressBack:--> B pressBack:-->A pressBack:--> Exit
2) A --> B pressBack: --> A pressBack: --> Exit
3) A --> B --> A pressBack:--> Exit
as you see, back works as always, BUT when in activity A it exits the application.
the behaviour i got now is 1) and 2) as above but
3) A --> B --> A pressBack:--> A pressBack: --> Exit
keep in mind, i've already overwritten the onBackPressed listener of activity A with a finish() call. even calling system.exit(0) dosnt work. however, even if it would: its not what i want, i want the REAL way to do it android style - i cant imagine system.exit(0) is best practise.
Well this is the default behavior.
If you have another approach, just implement it.
One approach to deal with this is to use the android:launchMode="singleInstance" for activities that can be launched in a singleton manner (only one activity can exist)
For example, if the SMS page in the SMS app was a singleTop, it would have needed only one back press to remove all the SMS pages. It is a matter of choice
Another more aggressive way would be to finish Activities when you start another activity. Of course, such decision would risk making the app less friendly (android users are not accustomed to this behavior). Nevertheless, if this is used only where it may be considered acceptable then it might be acceptable.
A very acceptable place to do this would be a login screen: Once login is successfull, you start another activity (probably designed for logged in users) and finish the login activity.
Enjoy Finally, in my personal opinion, you can add an Exit button. Users will find it nice.
Check my post: Adding an Exit button to Android Application
I'm using a custom Launcher application with Widgets that are used to launch (and provide status updates) for an application.
The application consists of a few Activities - let's call them A, B and C for simplicity.
A is the launched Activity. The user proceeds from A to B and then to C (never in any other order).
At any time the user can press the 'Home' button on the remote control and return to the launcher application.
If the user then presses the 'Back' button on the remote control they always return to the Activity they were last using (A, B, or C).
However, if they click on the widget (rather than pressing back) the Activity that is brought to the front seems inconsistent!
So, here is an example of what happens
From (custom) launcher, use widget to launch application
Activity A appears
User presses a button that launches Activity B
Activity B appears
User presses 'Home'
Launcher appears
From (custom) launcher, use widget to launch application
Activity A appears NOT B
Sometimes I get Activity B instead of Activity A - but I'm not sure under what circumstances. I want to get the Activity at the top of the stack to be displayed and never any other Activity (Activity B in the example above).
I've read Google's documentation about the Activity flags ("single-task", "single-instance", etc...) but nothing seemed to jump out as the solution to my problem.
In my case, Activities A, B, C only make sense when run in that order - and it never makes sense to see a previous activity unless you explicitly go back to it.
I'm not sure if the problem is the way the widget is launching the application or whether there is something I need to specify in my manifest or something else.
Any ideas?
Thanks,
Dan
Isn't that what's supposed to happen? Isn't your widget launching activity A? Would you expect it to launch activity B if you are asking it to launch activity A?
(Althought you say that you get B launched sometimes. Isn't this related to the app being forced out of the memory?)
I'm sorry, but this is not an answer, but rather some additional information related to that same question.
I have found a pattern for Activities when relaunched after home button is pressed.
See my question for all my research:
Android Activity Stack is not working as stated in the docs - last activity in task stack not shown
Hope this can be of help...
I have been reading that the suggested fix for this strange behavior is the use of a "Dispatcher" class as Main that will launch the activity based on the application state...or you can also keep track of all the activities opened that need to be restored...but this can become really cumbersome when having a complex UI application design.