We have a requirment for accessibility that when a given activity opens and the user has TalkBack accessibility on, the client wants the Talk Back to not just read the activity name, but also the text of our welcomeText TextView. That text view is dynamic in that it will say "Welcome, "
I tried doing this in the activity onCreate() by saying:
welcomeText =(TextView)getView().findViewById(R.id.authenticatedNoWishlistWelcomeText);
welcomeText.setFocusableInTouchMode(true);
welcomeText.requestFocus();
but this is not working.. can anyone tell me how i can get Talk Back to read a given TextView upon launch without the user interaction?
The important thing to realize here, is that Focus and Accessibility Focus are not the same thing.
You are looking for the following:
welcomeText.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
Be careful about when you do this. Doing this in onCreate is probably a bad idea, as then it will only happen when the application activity is loaded. What you probably want is for it to happen each time it is resumed. Also, the AT (TalkBack) creates its connection to the Activity at some point in this lifecycle, and so you want to be sure you don't have a race condition. TalkBack must connect to your activity before you post your Accessibility Event.
Though note, that this may be a bad requirement. WCag 3.2.1 and 3.2.3 clearly state that navigation should be consistent and predictable, and part of this is avoiding unexpected shifts of focus. This could be considered a violation of these guidelines, and actually less accessible than not doing so.
Related
I have a MainActivity and a second Activity which has an EditText. I want that the content of EditText always gets saved. However I don't want a EditTextChangedListener which writes a file after 1 char has changed.
What is a good solution? I thought about onPause or onBackPressed.
What about the home button? I think the app remains open, so is there any need to save? And what about other interrupts like phone calls? Does onPause catch all that?
Thank you.
Yes onPause gets called whenever your app gets interrupted or goes to background check Activity life cycle
A good solution is to include such logic in the onPause() method. It will always be called in all situations. This is what the developer documentation says:
you should use the onPause() method to write any persistent data (such as user edits) to storage.
One thing you should keep in mind is that this method may be called more frequently than desired, for example, when your screen light goes off (some ppl have 15sec screen light timeouts). So, you should not put in too many expensive operations inside there.
As for pressing of home button, it is recommended that you save the data (at onPause()). The reason is that your activity is in the background but it may get destroyed. The system may destroy the activity if it needs to reclaim the memory. (For example you start too any other apps afterwards and put them all in the background) From the documentation:
Stopped: The activity is completely obscured by another activity (the
activity is now in the "background"). A stopped activity is also still
alive (the Activity object is retained in memory, it maintains all
state and member information, but is not attached to the window
manager). However, it is no longer visible to the user and it can be
killed by the system when memory is needed elsewhere.
No. The correct answer here is to listen for the "return" key event. That signifies that the user has completed input to the field, and trigger the save of the field contents to the file. It's useful in many other circumstances too.
See this answer: Android Use Done button on Keyboard to click button
Peter.
I've searched at length and tried the usual suspects, but it's time to ask for help.
My Android activity loads EditText, Spinner and CheckBox values from SQLite happily enough.
The problem is sensing if the user thereafter actually changes a value so I can warn at onBackPressed if unsaved changes were made (i.e. s/he had not hit the 'Save' button).
For example, with an EditText I've tried:
using a TextWatcher.onTextChanged listener, but it gets fired when the EditText is first instantiated, which makes setting a 'data changed' flag meaningless
trapping the various KEY_DOWN events for the DONE, ENTER, NEXT and DEL keys, but with mixed results that wouldn't help with my Spinners and CheckBoxes anyway
onTouchListener (I think, but I'm a little foggy by now), to no avail
I guess what I'm looking for is a View class listener, attached only after the activity has settled down, that fires for subsequent state changes. But, nothing I've searched for fits the bill.
How do others handle this problem?
Thank you for any guidance.
I can't think of any general mechanism that could apply to all kinds of widgets.
Nevertheless, a cleaner solution would be :
to have a model (POJO) that represents all data you display on screen
every change in widgets are reflected in the model
every time a setter is called in the POJO, it compares the new set value with the old one
if a change is made, then it raises an internal flag.
if the flag is raised at onBackPressed, then you show an AlertDialogFragment asking whether changed values should be saved or not.
I have a multi-activity application. Say I set up a listener for some type of event in activity A, but then switch to a different activity B (within the same app) before the event has triggered the listener. What is the status of that listener? Does it always get destroyed? Or does it depend on the type of event? Or does it depend on whether the listener was set up within the main UI thread of activity A? Or some other conditions?
EDIT: The reason I ask is that I wish to interrogate the purchase states of a variety of in-app purchase items right at the start of my app's splash screen. This involves instigating some code and setting up a listener for "ok_here_is_the_answer()".. the problem is I'm worried that it may take longer to get the answer than the duration of the splash-screen activity. In that case do I have to start all over again in my application's second activity?
If your listener is created within Activity A and is tight to its context, then it would be destroyed when the activity pause i.e. go to the background.
If you want to do operation that should survive across activities, you can define it within the application context or in a dedicated service.
This might not be the answer to your question but you shouldn't use a splash activity (or even a splash) for many good reasons. I'd recommend you to use a full screen dialog instead which also would solve your problem.
But about your question it depend on what kind of listener we are talking about? Anything involving the context is over and done. Handlers, threads etc. is still running though (afaik).
I'm developing an Activity that does some of its own state management. I'm trying to differentiate the following onResume cases:
New launch
task switch (home button long-click)
resume after other activity in the same application
wake-up after sleep
orientation change
Is there something in the Activity's intent, or elsewhere, that can help me differentiate these?
For the curious and some context... I'd like to preserve my internal history stack on 4 & 5. On cases 2 & 3, I would preserve the same current page, but erase the history (allow the normal back button functionality to take over at that point). Case 1 would initialize to the activity's internal start page (and can be detected easily enough with some help from onCreate).
Is there something in the Activity's intent, or elsewhere, that can help me differentiate these?
Item #4 has nothing to do with onResume(), AFAIK.
Item #5 would be better handled via android:configChanges and onConfigurationChange() though you could "detect" it by returning something from onRetainNonConfigurationInstance() and seeing if it is there in onResume() via getLastNonConfigurationInstance().
The others aren't just three cases, but probably twice that, once you start taking into account things like "being kicked out of memory to free up RAM" as a possibility.
Off the cuff, it feels like you made some unfortunate architectural decisions ("internal history stack...erase the history...allow the normal back button functionality to take over at that point"). Android is designed around lots of cheap activities, and you appear to be violating that precept. You are welcome to do so, but bear in mind that Android support for your chosen pattern may be limited.
I am confused about activity lifecycle usage in the notepad example,notepad example use "edit in place" user model,inserting new record in onCreate method,
saving persistent state in onPause method,and save away the original text in onSaveInstanceState method.
I am a J2EE programer,I can not understand the logic described above. why not make things simple as following:
1.Not inserting new record in onCreate method.
2.When user pressing BACK,it is equal as pressing save button in the editorform,so execute inserting or updating in onPause method if activity.isFinishing() is true.
don't persiste use data if activity.isFinishing() is not true.
3.Not save the original text in onSaveInstanceState method,It is no necessary.If the activity is killed and back,restore user inputing data in the editorForm is adequately.
I think this logic is more traditional and natural.
Maybe I not understand the essence of the activity lifecycle.Please air your's opinion.
Thanks
L.J.W
the lifecycle of an adroid app under various conditions (e.g. switching screens, freezing, stopping etc.) is described in an excellent video tutorial by google. You may also want to refer to the slides of that talk, in particular, slide 16ff may be of great interest for you.
In any case you are right in thinking that understanding the lifecycle of an android app is the key to coding for android.