Start Android App on same activity every time - android

I'm working on an Android app that will show college fitness professors how their students are doing in their classes. Since this data is fairly sensitive (biometrics are shown, including weight, something many college students are self-conscious about) I don't want the data to be available to anyone who picks up the tablet. While I have a proper login screen created, complete with authentication for the database, etc. I have an issue when the home button is pressed. Since Android doesn't close a program immediately on leaving the app, it's possible to reopen it and return to where you were. I would like to force the app to return to the login screen each time (I've altered onBackPressed so you can't just return to the previous view from the login screen) so that you have to re-enter your credentials to get back into the app. However, I can't seem to do this. An answer I found on here said to use the following line:
android:clearTaskOnLaunch="true"
However, no matter what XML file I put it in, be it the Manifest or the individual Activity XMLs, it appears to do nothing. So, how do I ensure the login screen comes up each time the app is launched, regardless of whether it is starting from scratch or not?

Try to play around with onUserLeaveHint() method. If you read its documentation, it says:
Its Called as part of the activity lifecycle when an activity is about to go into the background as the result of user choice. For example, when the user presses the Home key, onUserLeaveHint() will be called, but when an incoming phone call causes the in-call Activity to be automatically brought to the foreground, onUserLeaveHint() will not be called
So, when ever you detected home button pressed, you can finish the running activity/activities. So next time user click the app, it will start from the first login screen.
Hope this helps.

You should override onUserLeaveHint()
#Override
protected void onUserLeaveHint() {
// do your logic
//finish() or start login activity
}

You could set a flag when onPause() is initiated within the activity. And then when you return you could check the flag from within onResume() and then request a login from that point. This will be sure to request it each time; in a simple case of course.
Edit:
With multiple activities, you could check against a saved context to see if they are the same when you start a new activity. If the contexts differ then you can discard the context previous activities context and start a new activity.
If they are the same, then you have come back to the activity from itself (you have lowered and brought the screen back). You would have to use some form of saved state such as that to do it in this manner with multiple activities when outside the case of a simple application.

I found out how to do it in my case. For any others with the same problem, try following the example here:
Android detecting if an application entered the background

Related

How to show disclaimer once per run of app

This is harder than it sounds, which is why I'm asking for solutions.
Basically I only want the disclaimer Toast shown once per run of the app.
The app is in two parts, all are Activities.
It's shown when it starts in the first part, but you can hit a menu button
taking you to the second part of the app, which has another menu button
to take you back to the first.
The problem is that whatever initial settings you try to make in the first
part, when it starts up, are run again when returning from the second
part of the app, so it'll show again.
My last idea was that in the first part's onDestroy(), when the app exits, but is not the case in this situation, you set a boolean in settings,
to reset that the disclaimer can be shown, but apparently, onDestroy() is called on the first part before it goes to the second part.
Or, if you can get it to not show the first run, but behave properly
every time after that, that would be okay.
And there doesn't seem to be any method to be called when the app truly
is "killed", if there was that would be the way to do it, you could reset it there. Or if there was a method that was only called when the app first started..
Thanks!
You just need a boolean flag. Say we call it disclaimerShown. In onCreate() of Activity A, we check both the Intent Bundle and the savedInstanceState Bundle for this flag.
You can add the boolean to a Bundle when launching the Intent to start Activity A from Activity B.
If the user is in Activity B and presses the Back button to return to Activity A, you can override onBackPressed() in Activity B and include your flag there as well (though you'll have to catch this flag on onActivityResult() in Activity A).
If system initiated process death occurs in Activity A, the system will call onSaveInstanceState(Bundle bundle). So you add your flag to this bundle as well.
And if system initiated process death occurs in Activity B, you have nothing to worry.
And that handles all possible cases.
An elegant solution for this problem would be the ProcessLifecycleOwner.
This class provides callbacks to the lifecycle of your whole app (not individual activities) and you could use the Lifecycle.Event.ON_CREATE callback to show your toast once. Look at this stackoverflow question for a usage example of the ProcessLifecycleOwner.
It turns out that I already had an Activity that started before
my "Activity A", and I moved my disclaimer Toast there
and it works fine. You can't beat that simplicity lol.
Thanks for your answers!

Close all Activities when the app returns from being in the background

It is important in my app that when a user presses the home button and the app enters the "Background" the app reverts to the login screen next time it is opened.
I have tried using the
android:noHistory
in the manifest but this means when pressing back on activities it reverts also to the login screen so is no good. I have also tried using
android:clearTaskOnLaunch="true"
in my initial activity but this doesn't seem to have any effect. I don't finish() the first activity so i am not sure why this doesn't work.
Can anyone help with a way of doing this.
I got this working by using
android:clearTaskOnLaunch="true"
Turns out that I didn't have it in my root activity, this was because I have a second login screen which asks for less details depending on if you have logged in before.
Although it works exactly as i want it to, apparently using this "Android" feature is incorrect because i am going "against" android by clearing the tasks (activities) when the home button is pressed and my app should follow someone else opinion of what an "app" should do. Who Knew!
Why don't you use the onPause()-Method? This should be called every time the Activity gets in Background.
So something like:
#Override
public void onPause(){
super.onPause();
finish();
}
Due to the fact that only one Activity of your App can be active at a time you don't have to worry about others still being active.

How do I determine if an activity is being launched from a back navigation versus being launched by the user in Android?

The home screen of my app needs to have different behavior when the app is being launched from outside the app versus when a back navigation occurs. For example, imagine an Android Twitter client which on launch tries to get your updated feed but when you click on an item to hit its detail page and hit back, the screen doesn't reload new feeds but is instead where you left from.
So far I've tried looking at the calling package property but this hasn't helped since it seems to be null both when app is launched by the user for the first time or when I hit back from a detail page.
When user launches it first time, onCreate() then onresume() will be called for sure. When navigating back and getting your activity from backstack, just onResume will be called.
Also if you activity has singleTop set, then you can look into onNewIntent() which will be called when you navigate back to your activity from other screens.
So, the solution I can suggest you is to set singleTop for your activity. Then while navigating back using onNewIntent(). For 1st time launch onCreate() will be called.
Sorry if I could not understand your question well..

How to check which activity finished

In my Android application I need to Override the onResume() method to check which of two possible activities just finished. The user will either have entered an amount of money, or named and chosen a percent for a category. How can I do that? Also, if a user presses home and then goes back to my app, is onResume() called? If so, I can just call super.onResume(), right?
I have three classes: PaySaver, NewSavingCategory, and NewPaycheck. PaySaver.java is the main Activity, and there are two buttons: New Paycheck (launches a dialog box where a user inputs $ (NewPaycheck.java)) and New Saving Category (launches a dialogbox where a user inputs a name and a % (NewSavingCategory.java)). When the dialog box is closed via an enter button, I want the main activity to be updated with the information entered.
Thanks!
How can I do that?
Most likely, you don't. Both of those other activities updated your central data model. In onResume(), you update your UI from that same central data model. Hence, it does not matter where the user came from -- you are grabbing the latest data.
Also, if a user presses home and then goes back to my app, is onResume() called?
On the activity they return to, yes.
If so, I can just call super.onResume(), right?
Not only "can" you do that, you have to call super.onResume(), or your activity will crash.

Does pressing Back always cause Activity to finish()?

I've heard that pressing the back button will essentially cause the current Activity to finish(). Is this always the case? Seems like it would be with the way it pops the Activity off the stack.
The one situation I'm not so sure about is when the root Activity in a Task has back pressed. I'm currently experiencing a very weird effect, described as follows:
On loading my application, the first Activity is for initialization, and once it finishes, it calls my main Activity (a TabActivity). This first init activity has android:noHistory="true" set in the Manifest so pressing Back from my main Activity won't go back to that. It goes to the Launcher. When I click on my App in the Launcher a second time, the initialization activity loads again, and loads the main Activity when done. Almost immediately after, it loads a second instance of my main Activity. But ONLY after the Application has already been run once, and was exited by pressing BACK from the main Activity. It does it every subsequent time until I force quit the app or load a new version from the IDE.
Based on this, I am suspecting some kind of Activity instance is lying around and being reused, since it only happens on the second+ time I run the application (and exit with BACK -- using HOME just returns to the last state of the app, no big deal). Anyone have any thoughts??
I've heard that pressing the back button will essentially cause the current Activity to finish(). Is this always the case?
No it is not. The most activities have this behaviour but not all. For example you could create a Dialog and set it setCancelable(false) and it won't close if you click BACK button.
Furthermore you could customize activity behaviour on BACK button pressed by overriding onBackPressed
Called when the activity has detected the user's press of the back key. The default implementation simply finishes the current activity, but you can override this to do whatever you want.
About your application behaviour..Did you verify if the activity launcher is finished after it loads your main activity? I mean if the onDestroy() method is called. Maybe after it runs the main activity it remains there and when you click back you just go back to the old Launcher...
hope this helps..
Read through the Activity and Task design guidelines on the Android developer site; they explain how the Home and Back buttons work. Obviously, if you override the default behavior (as mentioned by hara above), the back button will not finish the activity.
On your specific issue, check your logcat. You should be able to see there whether it is bringing an old process back to life or starting up a new one. If that is unclear, insert a couple of log statements into onCreate, onPause, onDestroyed, etc., so that you can see exactly what is happening with your process.
You can control BACK-BUTTON by writing the following code.
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK ) {
//preventing default implementation previous to
//android.os.Build.VERSION_CODES.ECLAIR
return false;
}
return super.onKeyDown(keyCode, event);
}
Are you running your activities with any special flags, such as singleInstance or singleTop? Those could be causing the oddities you're seeing. The easiest way to track down what's causing your problem is to absolutely fill it with debugging messages. For example:
In your initialisation activity, add a log in the beginning of onCreate to get the name of the activity such as this.toString(). More on why you want this line later.
When it launches the main tabbed activity, get the name of the launching activity and a message saying it's launched the tabbed one.
Override the onPause(), onStop() and onDestroy() callbacks and add debugging lines with this.toString() and also a message telling you which callback it is.
What this will do is tell you whether you've got multiple instances of the initialisation activity lying around. To this by comparing the name of the activities calling your main activity with the ones that were just created and the ones that went through to onDestroy.
If you don't know how to debug, use Log.d(LOG_TAG, "Your message here");. And then define a constant LOG_TAG String somewhere. After that, show the LogCat perspective in Eclispe by going to Window, show perspective (or view, don't remember exactly), other, Android, LogCat. The purpose of having a LOG_TAG constant is that you can set up LogCat to filter to that String and only show you those messages. It will make it easier to see them among the mass of system log messages.
The short answer to the original question is 'no'. This is largely because, unfortunately, not every developer follows the guidelines referenced by previous answers.
Yet the guidleines themselves mention exceptions, when the Back key should not call finish(). the most prominent exception is the Web browser, which has its own "back stack" for each window, so it must have its own custom handling of the Back key.
If there are no fragments on the back stack and a developer has not overridden onBackPressed, the activity will finish when the back button is pressed.
Here is the source code for Android 4.4.2 Activity.onBackPressed():
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}
}
just override onbackpressed().. on back press this method will get execute remove super and do what u want to do.

Categories

Resources