I have an application and the launcher activity is a login activity. I want the user to be able to close the app in another activity and when he opens it again the application to start again from the login activity (in other words to close the app and not just send it to background).
I have found a lot of ways to close an app:
1.finish();
2. Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
3. finishAffinity();
4. finishAndRemoveTask();
5. System.exit(0);
and combinations of the above. Which one is more efficient? What is the best practice?
Use whichever one you like. System.exit(0) probably is the most efficient, being a system method that directly exits the JVM running your app.
Related
The problem seems to be known, but I could not find the right solution.
I will describe the scenario:
There is an application making requests to the API. In some FirstActivity, a request is made to the API, upon positive result of which startActivity () is called in SecondActivity. The problem is that if, while sending the request, the application is minimized to the background (that is, startActivity () will be called in the background), then:
If android version> = 29 then startActivity () basically won't work. The one following startActivity () finish () will work and upon restarting the application will restart (which is logical)
If the android version is < 29, then startActivity () will fire and bring this SecondActivity to the foreground.
Based on this, the question is. How can I force the application, regardless of version, to transition between activities and not bring them to the front?
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
finish();
As per documentation
Android 10 (API level 29) and higher place restrictions on when apps
can start activities when the app is running in the background.
Workaround : In specific situations, 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 for this purpose by launching an activity while your app was in the background.
To provide similar behavior on a device running Android 10 (API level 29) or higher, complete the steps described in this guide.
you can show a high-priority notification with a full-screen intent.
More Details
Updated answer for new requirement: For your comment
(Well, please tell me how to make startActivity () in the background start the activity also in the background, and not raise the application from the background)
you can add a LifecycleObserver that will be notified when the LifecycleOwner changes state.
Inside your activity api response callback use the following condition
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
// Activity is in resumed state, Open new activity immediately
} else {
// else add a LifecycleObserver that will be notified when the LifecycleOwner changes state
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
// remove observer immediately so that it will not get triggered all the time
lifecycle.removeObserver(this)
// Activity is in start state again, Open new activity here
}
})
}
https://developer.android.com/preview/privacy/background-activity-starts
From this, it results that my payment app, which shows an Activity when a NFC transaction is performed, will not be able anymore to show anything to the user.
Has anyone have a clue what would be the new approach ?
Thanks!
I currently use the NFC service and it starts an Activity intent.
Intent intent = new Intent(mApplicationContext, PaymentActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
mApplicationContext.startActivity(intent);
The Activity should be shown. It works now, but from Android Q, it won't
According to the link, if you are having a HostApduService, then your app should work the same in Android Q.
If that is not your case, the simplest work around is to get "Draw over other apps" permissions. You can open activities if the app has been granted the SYSTEM_ALERT_WINDOW permission by the user. I have tested this and working.
Technically, you are showing something on top of other apps without user's interaction, so this might be the right way to go.
I'm working with an android application that has three activities A(Splash Screen) B(login) C(Home)
My app works as following:
1-A(Splash Screen)->B(login): in the splash screen I check if the user is not logged in, start new B(login) activity
2-A(Splash Screen)->C(Home): in the splash screen I check if the user is logged in, start new C(Home) activity
3-C(Home)->B(login): in home activity the user can logged out, start new B(login) activity
4-Notificatioin->C(Home): when the user opens a notification from the notification area, starts new activity C(home)
Every thing is working fine except
assume that I'm in C(home)1 ,when I open a notification a new C(home)2 activity is created then when I logged out new B(login) activity is also created, However when I pressed back button C(home)1 is opened.
what is the appropriate launchMode or flag intent for each activity?
For this type of flow you can use some of the following suggestions
Firstly, if you want to create only a single instance of the activity try using single top property in the manifest file.
<activity>
...
android:launchMode="singleTop"
...
</activity>
Secondly, if you you want your user to only access the current activity and don't return to previously opened activity then you can use intent filters while opening a new activity as mentioned here. For instance following flags will clear all of the back stack end the current activity and user will not be able to access any of the previously opened activities.
Intent intent = new Intent(this,Login.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
For more help on managing your tasks and activities you can refer here.
Found lots of similar questions but none that suited my situation.
Basically I have an Android app that flows like so:
HOME >> CHECKOUT 1 >> CHECKOUT 2 >> CONFIRMATION PAGE
Once we get to the confirmation page I want to 'finish' both checkout pages as I don't want the user seeing orders that have been submitted if they were to hit the back button. I know how to finish the Checkout 2 page once I confirm the order but I don't know how to 'cascade' down the stack to finish both.
When the user hits Back on the confirmation page they should go to the Home screen. I know how to do this with Intents but that's no good for the back button. Unless I override the back button behaviour and do something like:
Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
But I feel like this is very hacky. Anyone know the proper way to do it? Some sort of session variable that Checkout1.onResume looks for maybe?
Cheers
I ended up just overriding the onBackPressed method and using doing this
Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
I'll wait a while before marking the answer in case someone has a better way.
I'm currently trying to place a call in the background.
Therefore I call this in my Main-Activity:
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:123456789"));
startActivity(callIntent);
I also wrote an Outgoing Call Receiver which changes the activity:
Intent myIntent = new Intent(context, DisplayCalcActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
The problem is now, that the call-screen is in the foreground. If I switch manually from the call screen to my app, the activity has changed as I wanted, but how is it possible to start the activity in the foreground, so that the call-screen won't be shown at all?
The Android SDK does not allow to make a call in "foreground" maybe you can do accessing to private members but this is not recommended. The only way to call is by dialer app.
Got the solution!
I used another Receiver to listen to "android.intent.action.PHONE_STATE".
The outgoing call, activates the receiver which starts the other activity.