My android application tracks the number of correct answers while the user is in process of taking a quiz. If the user's answer matches the correct answer, a counter to track this is incremented. This logic takes place in the "onResume" method.
The problem is, if the user presses the home button from this activity, then re-enters the application, it resumes at this activity, and the counter gets incremented again.
The only solution I can think of is to set the correct answer field to a "magic number" such as 99 when a correct answer happens, and check for that first before going into the answer-checking logic. If it's 99, then skip the answer-checking logic and just redisplay.
Is there a better way to do this?
I'm not quite sure about the real problem you have and in specific why you're incrementing a counter of correct answers in the onResume event. You have for sure some kind of button where the user confirms his answer. Don't you verify the correctness of the given answer there, i.e. in the button's click method?
Implementing such logic in the onResumeevent is somehow dangerous, because it is called by the underlying Android OS.
It seems like you are using an application lifecycle method to cause a non-lifecycle effect. Please post some code. If you are relying on onResume to indicate that you have returned from a different Activity, you should take a look at startActivityForResult. If this isn't the case, you'll need to post some more description of your program. You shouldn't, however, be using onResume for anything besides setting up your applications state, since you can't always control how its called.
Related
Writing a kotlin social media app. I want to do 3 things within the logout sequence:
logoutbutton.setOnClickListener() {
//1. db.logout()
//2. finish()
//3. go to login screen
}
Does the order of events matter here? This is the order I am going with right now, but I don't know where the best place to put finish() would be.
Call finish when you want the current activity to popped off the activity stack. You typically do that when the user has indicated they no longer want to interact with it. Other than that, the order of these things don't really matter.
A trap that has caught me a few times is that finish() is actually asynchronous, so can give the illusion that instructions following it are "safe"... until they take a little longer and the activity gets torn down before they complete.
That can make for very difficult bugs to find.
I suggest for safety, call finish last.
I'm assuming db.logout may take some time to complete and/or may have to run on a background thread so some caution may be needed there. Fortunately Coroutines can help a lot .
I dont think putting finish() in onPause() is cutting it.
I have a Location activity and it is proving very hard to test, what I would like to do is be able to, when I leave the activity, completely destroy/kill any existence of it. So that when I go back, both when I leave the app or just the activity, everything is new, there is no cache, nothing and it has to start all over again.
The reason being is I don’t want it to remember Last Know Locations, they are not useful in this app, all I want is the current location and if it can’t be found, it can’t be found.
Cheers,
Mike.
This gets into some deep discussions about how android manages activities and memory and all kinds of things which you probably don't want to think about.
If you are currently trying to finish the activity in your onPause method (sounds like a horrible idea to me since your phone will call this whenver your screen goes to sleep -- after about 15 seconds of inactivity depending on your settings). But if that really is what you want to do then why not just make the call to get the last known location in your onResume method?
Put finish in onPause and in manifest add this for that activity android:stateNotNeeded="true"
so it want remember your last state on relaunch of that activity
For solving this problem you can use preferences for storing the data and you can use it for future.
Inactivity is a very important EVENT. For many apps if the user does not interact with it for a certain number of seconds its time to reset the app and go back to main activity logout, or conserve power. So I would really like to get some feedback on the best way to detect this. In fact I think everyone will benefit from a good solution to this.
So my question is twofold:
1) Is there a better way to detect user inactivity than using a combination of
activity.onUserInteraction() to reset a CountDownTimer?
Note: One reported downside to this approach is that softkeypad interaction might not be
caught by this approach.
Note: Another reported downside is the CountDownTimer is off main thread and might not update
correctly. I am not sure how big an issue this is?
Note: CountDownTimer appears to have cancellation issues as well:
how to stop/cancel android CountDownTimer
2) Lets say that onUserInteraction()/CountDownTimer is the best/only solution to this problem
there are still some questions:
a) should each activity launch its own countdown timer?
b) Should a single countdown timer be restarted in the onCreate method of each activity?
c) lets say I want to dim the screen or goto main activity when the countdown expires where
should the timeout handler be located? In each activity? In a service?
Thanks
Just stumbled upon this question as I've answered something similar just now.
Personally, I'd opt for option 2 that you have suggested, and put a timer into a singleton so its available across all activities. Theres no need for a separate countdown timer unless you have a specific requirement to react different under different features of your application.
Why would you want to reset the timer in the onCreate? You should do that each time the user interacts with the application, such as in the activity.onUserInteraction() method.
To quote from my previous answer:
You'll need to invest a little thought into exactly what your
requirements are here, but from what I can tell, you want to keep
track of the user interactions and if a time limit expires since the
last interaction, perform some action, in your case logging them out
of your application.
Firstly, you'll need some place that you can track when the last
interaction occured, since you'll want this to be application wide you
could use a singleton to hold this, or override the Application class,
either way should do.
Next, you'll need to start tracking user interactions. From your
activities, you can override the onUserInteraction method, this gets
invoked anytime the user interacts with the application such as key
event. Each time you hit this method, update your singleton and let it
know something has happened, with a timestamp.
Finally, you'll need some kind of looping check to constantly check if
anything has happened recently. Theres various was of doing this, you
could have a continuous loop that compares current timestamp to the
last recorded event, a bit of draft code :
while(true)
{
if (timeLastEventRecorded < (now - 15))
{
//nothing has happened in 15 minutes, so take corrective action
}
}
Presumably you'll already have some code in your application that
takes care of logouts, such as when the user clicks "logout", you
should just be able to invoke that in the sample above.
I am working on an Android app that deals with sensitive user information. One of the requirements is that the user is required to log back into the application whenever they leave it and come back. This is easily dealt with for the case when the user presses the Home button and then relaunches the app (android:clearTaskOnLaunch attribute on the Activity in AndroidManifest.xml). However, we need to do the same thing when the user long presses the Home button, switches to another application, then comes back.
I have researched this every way that I can think of and have not found a workable solution. Is this even possible with Android?
When answering, please keep in mind that this is a business requirement which I have no control over.
Well, I had the same problem yesterday. This is what I did and it works fine:
Added android:launchMode="singleTask" to the main activity in the AndroidManifest.xml
Called my boss and say: ey, this is going to take a long while... hold on!
Went and drank beer all night.
Just to clarify, my main activity only has a button that says login and launches the login page.
What have you tried? You can always clear whatever session you are saving in the proper Activity lifecycle method.
If I understand you correctly that you want to require an authorisation every time someone backs into the app, whether afresh or coming back to it, then you can override the onRestart() activity lifecycle event on the activity (or activities). So in onRestart() you can redirect the user to the login screen (you may also wish to consider onResume() depending on your requirements)
The lifecycle chart on this page will make this clearer:
http://developer.android.com/reference/android/app/Activity.html
Would it be possible to make it a time based thing, rather than strictly left the app and returned?
You could have a separate service that keeps track of when the last time the user accessed the application was.
I.e, in each onPause the Activity tells the service that an Activity was paused. The service records the time of that.
In each onResume, the Activity informs the Service that it wishes to resume. If some amount of time has passed since the last onPause, then the Service indicates that a login is required.
I think this would make a nicer user experience than just every time they leave the app. That could be very frustrating, to take 30 seconds to read a text, and then have to sign in again.
I suppose if you tweak it to have the timeout be very short, it has very similar behavior to what you requested anyways, but with the option of making it less draconion.
I think the easiest way to implement this, would be to add a field to your main activity like private boolean isLocked = true;.
To lock the app when another one is shown, set isLocked = true in the onPause() method. To make sure, that your don't lock your app, when returning from your own activities, start them via startActivityForResult() and unlock it in onActivityResult.
You can now check in onResume() wether your app is locked and redirect the user to your login screen.
I have been looking it up and I just cant seem to wrap myself around the onCreate and Bundles. I understand that the onCreate is called when the program starts but its how the Bundles get passed around and how they are pertinent. Can anyone try to put this into plain english because I cant seem to find it well described.
Thanks
The Bundle in the onCreate method should hold the state of you activity before it was killed.
Simple example, when you change the orientation of your device your activity is recreated.
Imagine the user is filling a long form and he/she accidentally changes the orientation. When the app gets restarted all data entered will be lost unless you persist that information. One possibility is using a Bundle.
If you want to know how to use it, I would recommend that you read this question.