I have an LogIn activity screen for a user to log into my app.
I wrote this in my manifest as I want the app to start on this logIn activity:
<activity android:name=".LogInActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".UserPostActivity" android:label="#string/app_name"></activity>
Once the user logs on, the app saves a token / boolean into SharedPreferences so that the app knows the user has logged in already and doesn't not load the logon activity next time the user starts my app - instead it will go to the UserPostActivity which will show user posts. It starts the UserPostActivity using an intent.
This is typical of apps like Facebook where you login once and then it moves onto the user Feeds each time you use your app.
I'm unsure if this is the most efficient pattern to code the app as then it always has to go to LogInActivity first, check the boolean / token and then use the intent to move to UserPostActivity each time a logon user uses the app. I'm concerned about the impact on startup time of the app with this current flow.
Is there a better way to code this?
Making the decision whether or not to show the login activity cannot be done inside the LogInActivity because it is always launched because the the deciding takes place inside it.
Normally the flow is to start with a SplashActivity, where you do these kind of checks.
In SplashActivity, you can show a splash screen with your app's logo and a progressbar for example, in the meanwhile you check if it's the first start or not. If it is, continue to LogInActivity, if it's not the first time, continue to UserPostActivity.
If you are worried about impact on loading time, you can make a splash activity without a UI so that it doesn't have to parse an xml file and set up the UI. Read more about that here Must every activity have a layout?
By the way, check out this Once library. It was made for handling actions that should only happen 'Once'.
There are a number of ways you might structure this, depending on your requirements.
If you are concerned about the user seeing the login screen every time they open the app you can prevent this by starting your UserPostActivity inside the onCreate of your LogInActivity - this should ensure the user sees the 'UserPostActivity' straight away (and should reduce load time as you can do it event before setContentView).
Depending on your activity stack it may become annoying to have the logon activity behind the UserPostActivity so you may want to make sure you finish() the LogInActivity as soon as you are done with it.
An alternative structure you could use is have the UserPostActivity appear first and then startActivityForResult the LogInActivity. The LogInActivity can then return with the success/failure of logon. A note about what this will look like visually - the user will see the same as a 'back' animation from the logon activity to the UserPostActivity. This may be something you desire or not... You can obviously always change animations around but it's nice to have your coded structure match the visual structure you show the user (and you get the benefit of always having the 'system' animations that the user will be familiar with).
Another alternative idea:
Start with the UserPostActivity and check for your credential. If you don't find it, move to the LogInActivity and finish() the UserPostActivity immediately. After the login is complete, it can start the UserPostActivity again. This should give you a forward flow through your app and will give you the UserPostActivity loaded first, which is correct 99% of the time...
I hope that gives you some ideas, make sure you check that the app behaves correctly when you background it and open it from the launcher icon again. There are a bunch of issues related to this that might trip you up!
Related
I'm developing an Android application and I would like to emulate the same behavior of the official Google Plus app when it is opened, which is:
If the app is still in the Recent Apps list and you open it (from icon or from recent apps, it doesn't matter) you will resume the app from where you left.
If the app is no longer in the Recent Apps list and you open it, you will be greeted with a splash screen and then directed to the Home page.
My app has one activity that uses a navigation drawer and several fragments as pages. My goal is to retain the current fragment and display it when the app is resumed from the Recent Apps. I can manage to do so using SharedPreferences by storing the tag of the current fragment and loading it when the user reopens the app. The problem with is solution is that this kind of data is persistent so the user will always be greeted to the last page even if he first removes the app from the Recent Apps list and reopens it.
So how can I detect whether the app is already in the Recent Apps list or not? Or is there any method that is called when an app is removed from that list so I can clear the last fragment tag from SharedPreferences? Or am I using the wrong approach?
Thank you for you patience in reading this.
When you return to your app through the recent-tasks list, there are three possibilities:
It has been a long time, over 30 minutes, and your process is not running. In that case, Android just launches your app as if the user tapped on your home screen launcher icon. You are not given your saved instance state, as it is deemed to be stale.
It has not been a long time, so Android wants the user to think that your app has been running since they left it. However, due to memory pressure, Android terminated your process while it was in the background. In this case, Android forks a new process for you, creates an instance of your activity, and passes to you your saved instance state Bundle in onCreate() and onRestoreInstanceState().
Your process is already running. In that case, your activity is just brought back to the foreground. You do not need your instance state, as your activity instance is still running. Android has not touched your widgets, and so if your UI is not the way you want it to be, that is your own fault, because you did something (e.g., in onPause() or onStop()) that screwed up your UI. From your descriptions, I am interpreting it that you are testing this scenario, in which case onRestoreInstanceState() is not called, because it is not needed.
So, as long as you do not screw up your own UI, your app will work as you described it for Google Plus, so long as you handle the saved instance state for scenario #2 above.
On Android 5.0+, there are related scenarios tied into the PersistableBundle that you can use with variations of onSaveInstanceState() and kin. I have not played with the PersistableBundle much and so I do not have any particular advice related to it.
As it turns out, the behavior I mentioned is automatic and there was a problem with my project that prevented it: this was the activity in my AndroidManifest.xml
<activity android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
android:noHistory needs to be set false:
A value of "true" means that the activity will not leave a historical trace. It will not remain in the activity stack for the task, so the user will not be able to return to it. - Documentation
Thank you for taking the time to help.
I have created an Android application thats starts up with a splash screen, then depending if the user is logged in, the application opens either the login or main activity.
When the user presses the home button and then click's the application icon I would like the application to resume at the last activity the user was at (For example the login screen).
This works fine when the APK is installed onto the device via Android Studio, but if I try to install the APK manually (the exact same APK), every time I press the home button and reopen the application it acts as if I killed and then started the application (The splash screen starts again).
Any idea why this could be happening?
Thanks
add following line to your manifest in your launching activity means 1st activity
android:launchMode="singleTask" android:clearTaskOnLaunch="true"
on other activities add:
android:finishOnTaskLaunch="true"
What you want to achieve is already the default behaviour of Android, but there is one possible way this can happen which is if your device need more space in memory then it may kill other applications which are on pause state. I believe that you're running into that situation and i'm afraid you don't have anything to avoid that.
Refer to
Edit: By the way, you can check that by logging something onDestroy and onPause method to see when your activity pauses and when it gets destroyed by system. Until it gets destroyed, you should be able to see the behaviour what you seek.
I met the same problem.
Сhange android:launchMode="singleTask" to android:launchMode="singleTop" helped me.
Im building an android app that uses facebook SDK. I have an activity which perform some operations that require facebook login. I designed the activity so the actual Session.openActiveSession() will happen only upon performing an operation that requires it and only when there is no active session present. And when the activity finishes i close the session. So far so good.
But... I noticed that everytime the session is opened (meaning, the first facebook operation performed on the activity), LoginActivity is displayed. Since i have FB android app installed on the device, no credentials are needed, the login is occuring immediatly and LoginActivity closes. But still, LoginActivity is shown for a split second. Its really annoying and looks like flickering of the screen. I would be really glad to lose this.
Appreciate any help.
ok, it was simpler than i thought. you just add the following style to LoginActivity in the manifest.
<activity android:name="com.facebook.LoginActivity" android:theme="#android:style/Theme.NoDisplay" />
The parameter of the Session.openActiveSession() method called boolean allowLoginUi needs to be set to false. But be careful using it that way. If there is no cached access token, basically if the user hasn't logged into the app before, you may have to figure out some other kind of login flow.
I am making an application.
Now what i want is that whenever user Press HOME key on android, it does not go in Background Mode.
Can any body give any suggestions how to implement all that?
Please Reply.
Thanks a bunch in advance
You cannot (easily) force your app's process to exit, nor should you. You can force an activity to disappear from the stack when the user navigates away from it by adding android:noHistory="true" to the manifest for that activity. But that will apply even to another activity in your app. You can also add android:finishOnTaskLaunch="true" to force an activity to be closed down if the user launches it again from the home screen. However, the activity will run until then (or until the system shuts down the process for other reasons).
Android naturally keeps your application alive, but calls the onPause because it's not an active activity, then calls onResume when the user goes back to your application.
If you need to run code without a UI or you want it to be checking something then opening your app at some point You can use a service.
API Demos have some great examples of how to use a service
Hi I have application with more than 20 activities.I want to close my app when Home button is pressed.
There is no notion of "close my app" in Android. Android will get rid of your activities, followed by your process, after some period of inactivity by the user.
You could use the launchMode and clearTaskOnLaunch flags on your root activity from your AndroidManifest.xml:
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
When you again start your app, all activities will be killed.
You don't want to do System.exit() -- that's not how the Android Activity Lifecycle normally works (read this also).
What you should do is move the App to the background with moveTaskToBack(). Android will then keep your app running in the background, and kill it if it's unused and something needs its resources later.
If you want it to close all of the open Activities when your App is no longer visible, you can set noHist = "True" for all of the child activities (leave the main activity with noHist = "False", though). This will make it where instead of reopening your application on the last Activity they were on, it will open it on the "main" activity (i.e. it will be as if they just restarted the app).
Anyhow, read through the following answers for more information: Close application and launch home screen on Android
I have the same problem. Im writing a banking app and am required, by contract, to log off the user (or exit) when the app is put into background. There are obvious security concerns there.
There are a couple of ways Im looking to do this:
1. Intercept home button (and back button for the root activity) key press events to call logoff and/or finish()
2. In the onStop() method, for every activity, detect whether the activity is being stopped due to a new activity being show - if not, assume app is being put to background so logoff and/or finish()
The first may not work if a notification is brought to the front then the user clicks home (I havent investigated yet). Or maybe there are other ways for an app to be put into the background without pressing these buttons
The second way sounds messy & difficult to maintain
Id welcome any other ideas
Drapes
I know android has been designed this way, but it seems naive to think that apps wouldnt want an applicationOnStop event
Hi guys what I understood is that u need to know when app goes in background and how to detect it and if I am wrong plz correct me----
The user can go in background if ur app does not provide any way by pressing Back key or Home Key.
You need to use methods "dispatchKeyEvent(KeyEvent event)" to get home key event or back key event and after getting the event you can execute your task.
you can even restrict user from pressing any key but u can not control the home key.