Changing the main launcher activity programmatically - android

My app works as launcher. 10 mins later another activity starts automatically. When this activity started, if user presses home button, he returns to the main activity. However, I want to change the launcher activity as the second one. It must be forbidden to return to the main activity even if he presses home button.

Instead of playing around with the intent filters, I suggest you create a blank Activity, with no UI, and register it as your launcher.
This Activity's sole role is to choose the correct actual Activity you wanna show, launch it as a new task, and then quit silently.

Related

Android skipping the splash screen when re-opening the app after having pressed back

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.

Start activity of another task and stay within current task

I have an application with, let say, two activities. One of the activity is already launched and after pressing "home" button it is in background. Now, from the ANOTHER application the second activity is launched. And when this second activity is finished I got to the first launched activity, not in the application that started the second activity. Is it normal behaviour? If it is, is there some way to change it? I need to stay in the application that launches the second activity, and not in the application which this second activity from.

Do not activate my application when activity launched by intent filter

I have utility application with two activities inside - one is main as explanation and some settings changing and second one is utility activity that is responsible for utility action itself. The utility activity has NoWindow theme.
I want that launching utility action from another application is not bringing my application into foreground if user still have it running.
Steps to reproduce:
I have activity A (launcher) and activity B (utility activity with intent filter, has NoWindow theme)
User lunches application from home screen (A is visible)
User navigates to another application without closing mine
User initiate some action that starts activity B (my app is foregrounded and presented to user but because B is NoWindow users sees A)
I want that when user initiate activity B he won't see activity B.
Could yo give me any advise how to achieve this? I think if I set noHistory flag to activity A it won't be shown but I afraid in this case if I move to activity C (About) then activity A disappears forms stack and won't be available if user presses back.

Confuse about launchMode

I have Activity A which calls B, at which point let's say the user presses the home button:
1) If the user long presses the home button and brings out the recently launch application, it will bring the user back to activity B.
2) If the user opens my application via the shortcut ( pressing the icon of the application), it will create another instance of Activity A.
I did not set any launchMode for my activity, so I guess it's launchMode="standard", the default behaviour I want is to go back activity B.
Why is point number 2 happening? I always thought that both of the actions will lead to the same result.
Every time it should call activity B unless Dalvik machine thinks that activity B is a background process and the process space might be required for other applications,
At that point your activity may be killed and it may launch afresh when you click the icon.
It's weird...I did a total uninstall and reinstall of the app.
Without declaring launchMode, it's default to "standard", and it works just as designed.

Calling back to an Activity in the bottom of the stack from a global Activity

I already know that I can pass Bundled data through setResult from one Activity back to another. However, suppose I have an global Activity that can be launched from anywhere in my app since it is mapped to a button that appears in my title bar in almost all of my activities.
Long story short, after it completes its user-driven process, I want it to signal back to the very first activity in the back stack, basically my Home activity, so that it updates the UI accordingly.
Part of the problem is that since if I use a BroadcastReceiver, it is unregistered when my activity is in the background, and it will not get the signal to refresh its data set.
What I want to achieve is the following:
From either Home (ActivityA), or any other activity (Activity B, C, etc...) that can open out my global activity (ActivityX), it should find a way to call back to ActivityA without bringing it to the front.
Should I use FLAG_ACTIVITY_FORWARD_RESULT and if so, how should I model it from my subsequent activities after Home. In other words, if I launch a child activity from Home, should I launch it with startActivityForResult with whatever request code I define and then pass FLAG_ACTIVITY_FORWARD_RESULT when opening my global activity so that the result will be set from there?
Also, suppose I launch a child activity from Home with a result, and then from my child activity I add more to the stack, from which I open ActivityX. Would the system still remember the result chain as long as I opened the first child from Home with a result?
EDIT: I am not looking for just clearing the entire stack back to home immediately after the process is completed in ActivityX; just a way to signal the Home activity to refresh it's UI when the user eventually returns to the Home screen. I guess probably setting a SharedPreference flag that Home checks in onStart when the user re-focuses on that Activity which in turn gives me the condition to do the end result, after which the flag is reset.
Your home-screen should just update it's UI in onResume, this way whenever a user returns to it will be displaying the latest data. There's no need to pass callbacks. Otherwise you could register a Broadcast receiver in onCreate (and unregister in onDestroy... not ideal) in your home activity and then send out a broadcast when you want the home activity to update (although the home activity shouldn't actually update itself until it is resumed).
Here's how to get back to your home activity:
Intent goHome = new Intent(getContext(), HomeActivity.class);
goHome.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
goHome.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(goHome);
FLAG_ACTIVITY_CLEAR_TOP: This ensures that when the activity is launched, it displays its initial activity.
FLAG_ACTIVITY_NEW_TASK: we're starting a new task (i.e. the back button should not go back to the previous screen so that pressing back at your home screen will exit your app).
I'll update on the rest tomorrow.

Categories

Resources