waiting for keyboard input - android

I'm writing an app using Android 2.1
At some point, I call setOnKeyListener
In particular, I write...
editfield=(EditText)findViewById(R.id.edittext);
editfield.setOnKeyListener(this);
This is in the main thread, in the onCreate callback.
At this point in the code, I would like the processing to stop and wait for the
keyboard input. If I let the code run on, the logic will break, soon enough.
I suppose I could put the machine in a wait loop until a keystroke invokes the onClick method. I could also create a wait loop at the point where the input from the user was required. But I don't feel comfortable with either of these solutions. (A related problem is this -- at a certain point in the code, the screen must be lit up. Must I check this before proceeding past that point?
Perhaps I'm not good with documentation, but I have not been able to find anything specific that answers these questions.
Can someone explain to me how to accomplish the timing I need and, more generaly, where I can find info on these questions?
Thanks in advance.
-looking in DC

The Android key system is event-based, it does not work like the old ask-and-wait mechanisms of C/C++ etc for obtaining user input.
If you blocked/waited - then what would happen if the user pressed the Home key (you can't catch that) or navigated to another app - your app would force close because it would still be waiting and your onPause etc would not execute.
My suggestion would be:
Put all the code that should occur after the click into some function
Place the listener at the end of onCreate, this way no more code will be executed after you set the listener
When you get a key-down, call your function. Thus the statements in your function will only execute after a key down
If however, this is for a game, then it is acceptable to have a thread dedicated to touch/key-events which sleeps for 50s or so to avoid event overload (but this must not be the main UI thread!)

Related

In what order should I call events in this logout sequence?

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 .

In android, how can I get the precise time a button was clicked (as opposed to when the onclick handler gets called)?

I want to get the exact time that a button is pressed.
Of course I can use System.currentTimeMillis() in the onClick handler, but presumably there is a fair bit of processing that happens between the button physically getting tapped and the onClick handler getting called. I don't know if this is of the order of nanoseconds or milliseconds (say if a garbage collection is running), but I'm wondering if there is any accessible value that is stored earlier in the processing that I could reference.
I suspect the answer is no, but I thought I'd ask anyway. Perhaps there is some undocumented, but accessible value?
Many thanks!
I think there are no ways to do it, all UI controls work in the Main-thread, the signals from low-level drivers (overlay-driver) don't handling immediately and put in a special queue for handling on the Main-thread. I guess, you're trying to catch an interval between the physical click and the button event in your code, isn't it?

Can you indicate to Android the time to wait or tell it that the app is still "active" before displaying "App isn't responding? If so, how?

I'd like to know the code or configuration needed to set that.
In my app, there are some places where I'm willingly make the app to sleep for several seconds, as it's needed for some reasons, with a Thread.sleep(long millis) function.
Problem is that on some Android APIS, at least on 25 and 26, usually that system message pops up in few seconds, confusing the user and maybe even causing the application not to fulfill the needed operations that need to happen while that sleep is happening if the user ends the app, which might cause even malfunctioning of the application.
I'd like to find a way of either forcing Android to wait for a good time like, for example, 1 minute, or to make Android aware that it's not that app isn't responding, that is willingly on a Thread.sleep function.
Is there any way to do that?
I'd like to find a way of either forcing Android to wait for a good time like, for example, 1 minute, or to make Android aware that it's not that app isn't responding, that is willingly on a Thread.sleep function.
TL;DR there is none.
Android apps should at all times be able to yield their position in the foreground to other apps. It's up to the users if they want to wait while some lengthy download is taking place or if they prefer to do something else and come back later.
You can't execute Thread.sleep() on the UI thread for long because this would "freeze the UI".
An example: Users should be able to leave your app by pressing the BACK Button at any time they wish to. If your method is blocking the UI thread, Activity#onBackPressed() can't be executed so the users can't quit.
What can you do? Move the heavy work to another thread (using e.g. AsyncTask or IntentService or some plain worker thread) and show some type of progress indicator to the users if necessary. You can/ should also toggle visibility or enabled state of Buttons etc. if required to avoid clicks which can't be processed at that point in time.
I think you have an implementation problem. The system message, known as ANR (Application Not Responding) occurs when the application cannot respond to user inputs, this may be caused by Ui thread blocking and that may be your case.
To avoid blocking the UI Thread just run your long time operations asynchronously. There are many ways to do that. You could use AsyncTask, AsyncTaskLoader, Thread, RxJava... Here you have some links to help you with that:
https://developer.android.com/training/articles/perf-anr
https://google-developer-training.gitbooks.io/android-developer-fundamentals-course-concepts/content/en/Unit%203/71c_asynctask_and_asynctaskloader_md.html
http://www.vogella.com/tutorials/RxJava/article.html

What is running on UI thread?

When all the drawing and other tasks have been finished, what code is running on the main thread? After the loading is finished, the application actually has nothing else to handle. But it could not be really idle otherwise it cannot deal with touch event. I think there should be a loop checking for user iteration, but I fail to find related information.
Thanks.
As far as I know that :
In basically to say that AndroidOS always listen the User's
interaction and then pass it to the active application.
Example when your application is running and on the top of the
application stack (that mean current active application), when have some interact from User, AndroidOS will receive and ask you application first that do you want to handle this action? (with what's the action and coordinate x = ?, y = ?). If you application answer that ok, it's mine, let me handle it - that mean your application has been implement to handle that action (it's the listener for touch events (click, drag, swipe...)) and then your application will take care the rest. Other wise if your App said that NO, it's not my part, AndroidOS will continue to ask other app in the stack until there is an App say Yes. Finally if no app say YES, AndroidOS will determine to handle it by OS or Ignore.
So, To answer your question:
what code is running on the main thread? --> NO CODE (nothing)
The Second part
After the loading is finished, the application actually has nothing
else to handle. But it could not be really idle otherwise it cannot
deal with touch event. I think there should be a loop checking for
user iteration when all the things had been loaded --> Application will not do anything, just loop handling from AndroidOS working and then if there is an interact action, AndroidOS will notify for application
If you are working on apart from main thread then if you want to perform any action in main thread you should write
runOnUiThread

What is the correct control flow for getting a one-time fix on the user's location (via GPS)?

I'm looking to find the "correct" way to get a fix on the user's location as a one-time task. At the moment, my execution flow is roughly:
The user presses a button.
The handler (contained in the main Activity code) registers a GPS location listener with the system, set to update as fast as possible, launches an ASyncTask, and finishes.
Pre-execution, the ASyncTask generates a ProgressDialog, effectively blocking any other UI usage.
For it's background task the ASyncTask waits for either a timeout or for a location fix for the GPS.
Post-execution, the ASyncTask either displays some relevant data to the user if a location was found, or displays an error in a toast if it was not. It also de-registers the listener of course.
Now, while this works, there are numerous downsides. Firstly, and quite obviously, all other UI interaction with the app is blocked while a request is being made. This isn't too bad currently, as the app's main function is to perform this task, and there isn't much else to do while it's working - it also stops the user from spamming the button. Additionally, I'm not sure if the post-execution phase of the ASyncTask is really the place to put my location-found logic (it makes an internet call, which is something that itself might be better off inside an ASyncTask?). However, I'm not sure how else to pass back the fact that a location has been found and that the main thread should do something.
I was hoping that someone could inform me as to the "right" way to do this - i.e. is using an ASyncTask like this correct, should there be a Service involved, and how should I deal with the internet-call post-location-found), and perhaps even give some wise words on how in general to deal with the control flow of an app which has to make somewhat "blocking" calls.
I can provide code if needed, might take a bit to get it cut down to a minimum solution.
Blocking calls and blocking UIs are generally to be avoided. See Reto Meier's take on the subject.
Hence, I'd dump the AsyncTask entirely. Disable the Button that the user uses to kick off the fix request. Use a postDelayed() Runnable for your timeout mechanism. And, allow the user to do something (read help, etc.). Use the progress indicator in the title bar to indicate that you're working on getting the location, dismissing the indicator when you get a fix or when your timeout occurs.
(it makes an internet call, which is something that itself might be better off inside an ASyncTask?)
It certainly should not be done on the main application thread. When the location fix comes in, kick off the AsyncTask to fetch the data.

Categories

Resources