Merge "initial accessibility class commit" into ics-mr1
This commit is contained in:
committed by
Android (Google) Code Review
commit
95dc3b50fc
@@ -278,6 +278,23 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="toggle-list">
|
||||
<div><a href="<?cs var:toroot ?>training/accessibility/index.html">
|
||||
<span class="en">Implementing Accessibility</span>
|
||||
</a> <span class="new">new!</span></div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/accessibility/accessible-app.html">
|
||||
<span class="en">Developing Accessible Applications</span>
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/accessibility/service.html">
|
||||
<span class="en">Developing Accessibility Services</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
194
docs/html/training/accessibility/accessible-app.jd
Normal file
194
docs/html/training/accessibility/accessible-app.jd
Normal file
@@ -0,0 +1,194 @@
|
||||
|
||||
page.title=Developing Accessible Applications
|
||||
parent.title=Implementing Accessibility
|
||||
parent.link=index.html
|
||||
|
||||
trainingnavtop=true
|
||||
next.title=Developing an Accessibility Service
|
||||
next.link=service.html
|
||||
|
||||
@jd:body
|
||||
|
||||
|
||||
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#contentdesc">Add Content Descriptions</a></li>
|
||||
<li><a href="#focus">Design for Focus Navigation</a></li>
|
||||
<li><a href="#events">Fire Accessibility Events</a></li>
|
||||
<li><a href="#testing">Test Your Application</a></li>
|
||||
</ol>
|
||||
|
||||
<!-- other docs (NOT javadocs) -->
|
||||
<h2>You should also read</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making
|
||||
Applications Accessible</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Android has several accessibility-focused features baked into the platform,
|
||||
which make it easy to optimize your application for those with visual or
|
||||
physical disabilities. However, it's not always obvious what the correct
|
||||
optimizations are, or the easiest way to leverage the framework toward this
|
||||
purpose. This lesson shows you how to implement the strategies and platform
|
||||
features that make for a great accessibility-enabled Android application.</p>
|
||||
|
||||
<h2 id="contentdesc">Add Content Descriptions</h2>
|
||||
<p>A well-designed user interface (UI) often has elements that don't require an explicit
|
||||
label to indicate their purpose to the user. A checkbox next to an item in a
|
||||
task list application has a fairly obvious purpose, as does a trash can in a file
|
||||
manager application. However, to your users with vision impairment, other UI
|
||||
cues are needed.</p>
|
||||
|
||||
<p>Fortunately, it's easy to add labels to UI elements in your application that
|
||||
can be read out loud to your user by a speech-based accessibility service like <a
|
||||
href="https://market.android.com/details?id=com.google.android.marvin.talkback">TalkBack</a>.
|
||||
If you have a label that's likely not to change during the lifecycle of the
|
||||
application (such as "Pause" or "Purchase"), you can add it via the XML layout,
|
||||
by setting a UI element's <a
|
||||
href="{@docRoot}reference/android/view.View#attr_android:contentDescription">android:contentDescription</a> attribute, like in this
|
||||
example:</p>
|
||||
<pre>
|
||||
<Button
|
||||
android:id=”@+id/pause_button”
|
||||
android:src=”@drawable/pause”
|
||||
android:contentDescription=”@string/pause”/>
|
||||
</pre>
|
||||
|
||||
<p>However, there are plenty of situations where it's desirable to base the content
|
||||
description on some context, such as the state of a toggle button, or a piece
|
||||
selectable data like a list item. To edit the content description at runtime,
|
||||
use the {@link android.view.View#setContentDescription(CharSequence)
|
||||
setContentDescription()} method, like this:</p>
|
||||
|
||||
<pre>
|
||||
String contentDescription = "Select " + strValues[position];
|
||||
label.setContentDescription(contentDescription);
|
||||
</pre>
|
||||
|
||||
<p>This addition to your code is the simplest accessibility improvement you can make to your
|
||||
application, but one of the most useful. Try to add content descriptions
|
||||
wherever there's useful information, but avoid the web-developer pitfall of
|
||||
labelling <em>everything</em> with useless information. For instance, don't set
|
||||
an application icon's content description to "app icon". That just increases
|
||||
the noise a user needs to navigate in order to pull useful information from your
|
||||
interface.</p>
|
||||
|
||||
<p>Try it out! Download <a
|
||||
href="https://market.android.com/details?id=com.google.android.marvin.talkback">TalkBack</a>
|
||||
(an accessibility service published by Google) and enable it in <strong>Settings
|
||||
> Accessibility > TalkBack</strong>. Then navigate around your own
|
||||
application and listen for the audible cues provided by TalkBack.</p>
|
||||
|
||||
<h2 id="focus">Design for Focus Navigation</h2>
|
||||
<p>Your application should support more methods of navigation than the
|
||||
touch screen alone. Many Android devices come with navigation hardware other
|
||||
than the touchscreen, like a D-Pad, arrow keys, or a trackball. In addition,
|
||||
later Android releases also support connecting external devices like keyboards
|
||||
via USB or bluetooth.</p>
|
||||
|
||||
<p>In order to enable this form of navigation, all navigational elements that
|
||||
the user should be able to navigate to need to be set as focusable. This
|
||||
modification can be
|
||||
done at runtime using the
|
||||
{@link android.view.View#setFocusable View.setFocusable()} method on that UI
|
||||
control, or by setting the <a
|
||||
href="{@docRoot}android.view.View#attr_android:focusable">{@code
|
||||
android:focusable}</a>
|
||||
attrubute in your XML layout files.</p>
|
||||
|
||||
<p>Also, each UI control has 4 attributes,
|
||||
<a href="{@docRoot}reference/android/view/View#attr_android:nextFocusUp">{@code
|
||||
android:nextFocusUp}</a>,
|
||||
<a
|
||||
href="{@docRoot}reference/android/view/View#attr_android:nextFocusDown">{@code
|
||||
android:nextFocusDown}</a>,
|
||||
<a
|
||||
href="{@docRoot}reference/android/view/View#attr_android:nextFocusLeft">{@code
|
||||
android:nextFocusLeft}</a>,
|
||||
and <a
|
||||
href="{@docRoot}reference/android/view/View#attr_android:nextFocusRight">{@code
|
||||
android:nextFocusRight}</a>,
|
||||
which you can use to designate
|
||||
the next view to receive focus when the user navigates in that direction. While
|
||||
the platform determines navigation sequences automatically based on layout
|
||||
proximity, you can use these attributes to override that sequence if it isn't
|
||||
appropriate in your application. </p>
|
||||
|
||||
<p>For instance, here's how you represent a button and label, both
|
||||
focusable, such that pressing down takes you from the button to the text view, and
|
||||
pressing up would take you back to the button.</p>
|
||||
|
||||
|
||||
<pre>
|
||||
<Button android:id="@+id/doSomething"
|
||||
android:focusable="true"
|
||||
android:nextFocusDown=”@id/label”
|
||||
... />
|
||||
<TextView android:id="@+id/label"
|
||||
android:focusable=”true”
|
||||
android:text="@string/labelText"
|
||||
android:nextFocusUp=”@id/doSomething”
|
||||
... />
|
||||
</pre>
|
||||
|
||||
<p>Verify that your application works intuitively in these situations. The
|
||||
easiest way is to simply run your application in the Android emulator, and
|
||||
navigate around the UI with the emulator's arrow keys, using the OK button as a
|
||||
replacement for touch to select UI controls.</p>
|
||||
|
||||
<h2 id="events">Fire Accessibility Events</h2>
|
||||
<p>If you're using the view components in the Android framework, an
|
||||
{@link android.view.accessibility.AccessibilityEvent} is created whenever you
|
||||
select an item or change focus in your UI. These events are examined by the
|
||||
accessibility service, enabling it to provide features like text-to-speech to
|
||||
the user.</p>
|
||||
|
||||
<p>If you write a custom view, make sure it fires events at the appropriate
|
||||
times. Generate events by calling {@link
|
||||
android.view.View#sendAccessibilityEvent(int)}, with a parameter representing
|
||||
the type of event that occurred. A complete list of the event types currently
|
||||
supported can be found in the {@link
|
||||
android.view.accessibility.AccessibilityEvent} reference documentation.
|
||||
|
||||
<p>As an example, if you want to extend an image view such that you can write
|
||||
captions by typing on the keyboard when it has focus, it makes sense to fire an
|
||||
{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
|
||||
event, even though that's not normally built into image views. The code to
|
||||
generate that event would look like this:</p>
|
||||
<pre>
|
||||
public void onTextChanged(String before, String after) {
|
||||
...
|
||||
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
|
||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
|
||||
}
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2 id="testing">Test Your Application</h2>
|
||||
<p>Be sure to test the accessibility functionality as you add it to your
|
||||
application. In order to test the content descriptions and Accessibility
|
||||
events, install and enable an accessibility service. One option is <a
|
||||
href="https://play.google.com/store/details?id=com.google.android.marvin.talkback">Talkback</a>,
|
||||
a free, open source screen reader available on Google Play. With the service
|
||||
enabled, test all the navigation flows through your application and listen to
|
||||
the spoken feedback.</p>
|
||||
|
||||
<p>Also, attempt to navigate your application using a directional controller,
|
||||
instead of the touch screen. You can use a physical device with a d-pad or
|
||||
trackball if one is available. If not, use the Android emulator and it's
|
||||
simulated keyboard controls.</p>
|
||||
|
||||
<p>Between the service providing feedback and the directional navigation through
|
||||
your application, you should get a sense of what your application is like to
|
||||
navigate without any visual cues. Fix problem areas as they appear, and you'll
|
||||
end up with with a more accessible Android application.</p>
|
||||
56
docs/html/training/accessibility/index.jd
Normal file
56
docs/html/training/accessibility/index.jd
Normal file
@@ -0,0 +1,56 @@
|
||||
page.title=Implementing Accessibility
|
||||
|
||||
trainingnavtop=true
|
||||
startpage=true
|
||||
next.title=Developing Accessible Applications
|
||||
next.link=accessible-app.html
|
||||
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>Dependencies and prerequisites</h2>
|
||||
<ul>
|
||||
<li>Android 2.0 (API Level 5) or higher</li>
|
||||
Playback</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>You should also read</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>When it comes to reaching as wide a userbase as possible, it's important to
|
||||
pay attention to accessibility in your Android application. Cues in your user
|
||||
interface that may work for a majority of users, such as a visible change in
|
||||
state when a button is pressed, can be less optimal if the user is visually
|
||||
impaired.</p>
|
||||
|
||||
<p>This class shows you how to make the most of the accessibility features
|
||||
built into the Android framework. It covers how to optimize your app for
|
||||
accessibility, leveraging platform features like focus navigation and content
|
||||
descriptions. It also covers how to build accessibility services, that can
|
||||
facilitate user interaction with <strong>any</strong> Android application, not
|
||||
just your own.</p>
|
||||
|
||||
<h2>Lessons</h2>
|
||||
|
||||
<dl>
|
||||
<dt><b><a href="accessible-app.html">Developing Accessible Applications</a></b></dt>
|
||||
<dd>Learn to make your Android application accessible. Allow for easy
|
||||
navigation with a keyboard or directional pad, set labels and fire events
|
||||
that can be interpreted by an accessibility service to facilitate a smooth
|
||||
user experience.</dd>
|
||||
|
||||
<dt><b><a href="service.html">Developing Accessibility Services</a></b></dt>
|
||||
<dd>Develop an accessibility service that listens for accessibility events,
|
||||
mines those events for information like event type and content descriptions,
|
||||
and uses that information to communicate with the user. The example will
|
||||
use a text-to-speech engine to speak to the user.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
286
docs/html/training/accessibility/service.jd
Normal file
286
docs/html/training/accessibility/service.jd
Normal file
@@ -0,0 +1,286 @@
|
||||
|
||||
page.title=Developing an Accessibility Service
|
||||
parent.title=Implementing Accessibility
|
||||
parent.link=index.html
|
||||
|
||||
trainingnavtop=true
|
||||
previous.title=Developing Accessible Applications
|
||||
previous.link=accessible-app.html
|
||||
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#create">Create Your Accessibility Service</a></li>
|
||||
<li><a href="#configure">Configure Your Accessibility Service</a></li>
|
||||
<li><a href="#events">Respond to AccessibilityEvents</a></li>
|
||||
<li><a href="#query">Query the View Heirarchy for More Context</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>You should also read</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}guide/topics/ui/accessibility/services.html">Building
|
||||
Accessibility Services</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<p>Accessibility services are a feature of the Android framework designed to
|
||||
provide alternative navigation feedback to the user on behalf of applications
|
||||
installed on Android devices. An accessibility service can communicate to the
|
||||
user on the application's behalf, such as converting text to speech, or haptic
|
||||
feedback when a user is hovering on an important area of the screen. This
|
||||
lesson covers how to create an accessibility service, process information
|
||||
received from the application, and report that information back to the
|
||||
user.</p>
|
||||
|
||||
|
||||
<h2 id="create">Create Your Accessibility Service</h2>
|
||||
<p>An accessibility service can be bundled with a normal application, or created
|
||||
as a standalone Android project. The steps to creating the service are the same
|
||||
in either situation. Within your project, create a class that extends {@link
|
||||
android.accessibilityservice.AccessibilityService}.</p>
|
||||
|
||||
<pre>
|
||||
package com.example.android.apis.accessibility;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
|
||||
public class MyAccessibilityService extends AccessibilityService {
|
||||
...
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterrupt() {
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Like any other service, you also declare it in the manifest file.
|
||||
Remember to specify that it handles the {@code android.accessibilityservice} intent,
|
||||
so that the service is called when applications fire an
|
||||
{@link android.view.accessibility.AccessibilityEvent}.</p>
|
||||
|
||||
<pre>
|
||||
<application ...>
|
||||
...
|
||||
<service android:name=".MyAccessibilityService">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
. . .
|
||||
</service>
|
||||
...
|
||||
</application>
|
||||
</pre>
|
||||
|
||||
<p>If you created a new project for this service, and don't plan on having an
|
||||
application, you can remove the starter Activity class (usually called MainActivity.java) from your source. Remember to
|
||||
also remove the corresponding activity element from your manifest.</p>
|
||||
|
||||
<h2 id="configure">Configure Your Accessibility Service</h2>
|
||||
<p>Setting the configuration variables for your accessibility service tells the
|
||||
system how and when you want it to run. Which event types would you like to
|
||||
respond to? Should the service be active for all applications, or only specific
|
||||
package names? What different feedback types does it use?</p>
|
||||
|
||||
<p>You have two options for how to set these variables. The
|
||||
backwards-compatible option is to set them in code, using {@link
|
||||
android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}.
|
||||
To do that, override the {@link
|
||||
android.accessibilityservice.AccessibilityService#onServiceConnected()} method
|
||||
and configure your service in there.</p>
|
||||
|
||||
<pre>
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
// Set the type of events that this service wants to listen to. Others
|
||||
// won't be passed to this service.
|
||||
info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
|
||||
AccessibilityEvent.TYPE_VIEW_FOCUSED;
|
||||
|
||||
// If you only want this service to work with specific applications, set their
|
||||
// package names here. Otherwise, when the service is activated, it will listen
|
||||
// to events from all applications.
|
||||
info.packageNames = new String[]
|
||||
{"com.example.android.myFirstApp", "com.example.android.mySecondApp"};
|
||||
|
||||
// Set the type of feedback your service will provide.
|
||||
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
|
||||
|
||||
// Default services are invoked only if no package-specific ones are present
|
||||
// for the type of AccessibilityEvent generated. This service *is*
|
||||
// application-specific, so the flag isn't necessary. If this was a
|
||||
// general-purpose service, it would be worth considering setting the
|
||||
// DEFAULT flag.
|
||||
|
||||
// info.flags = AccessibilityServiceInfo.DEFAULT;
|
||||
|
||||
info.notificationTimeout = 100;
|
||||
|
||||
this.setServiceInfo(info);
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Starting with Android 4.0, there is a second option available: configure the
|
||||
service using an XML file. Certain configuration options like
|
||||
{@link android.R.attr#canRetrieveWindowContent} are only available if you
|
||||
configure your service using XML. The same configuration options above, defined
|
||||
using XML, would look like this:</p>
|
||||
|
||||
<pre>
|
||||
<accessibility-service
|
||||
android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
|
||||
android:packageNames="com.example.android.myFirstApp, com.example.android.mySecondApp"
|
||||
android:accessibilityFeedbackType="feedbackSpoken"
|
||||
android:notificationTimeout="100"
|
||||
android:settingsActivity="com.example.android.apis.accessibility.TestBackActivity"
|
||||
android:canRetrieveWindowContent="true"
|
||||
/>
|
||||
</pre>
|
||||
|
||||
<p>If you go the XML route, be sure to reference it in your manifest, by adding
|
||||
a <a
|
||||
href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data></a> tag to
|
||||
your service declaration, pointing at the XML file. If you stored your XML file
|
||||
in {@code res/xml/serviceconfig.xml}, the new tag would look like this:</p>
|
||||
|
||||
<pre>
|
||||
<service android:name=".MyAccessibilityService">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.accessibilityservice"
|
||||
android:resource="@xml/serviceconfig" />
|
||||
</service>
|
||||
</pre>
|
||||
|
||||
<h2 id="events">Respond to AccessibilityEvents</h2>
|
||||
<p>Now that your service is set up to run and listen for events, write some code
|
||||
so it knows what to do when an {@link
|
||||
android.view.accessibility.AccessibilityEvent} actually arrives! Start by
|
||||
overriding the {@link
|
||||
android.accessibilityservice.AccessibilityService#onAccessibilityEvent} method.
|
||||
In that method, use {@link
|
||||
android.view.accessibility.AccessibilityEvent#getEventType} to determine the
|
||||
type of event, and {@link
|
||||
android.view.accessibility.AccessibilityEvent#getContentDescription} to extract
|
||||
any label text associated with the fiew that fired the event.</pre>
|
||||
|
||||
<pre>
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
final int eventType = event.getEventType();
|
||||
String eventText = null;
|
||||
switch(eventType) {
|
||||
case AccessibilityEvent.TYPE_VIEW_CLICKED:
|
||||
eventText = "Focused: ";
|
||||
break;
|
||||
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
|
||||
eventText = "Focused: ";
|
||||
break;
|
||||
}
|
||||
|
||||
eventText = eventText + event.getContentDescription();
|
||||
|
||||
// Do something nifty with this text, like speak the composed string
|
||||
// back to the user.
|
||||
speakToUser(eventText);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2 id="query">Query the View Heirarchy for More Context</h2>
|
||||
<p>This step is optional, but highly useful. One of the new features in Android
|
||||
4.0 (API Level 14) is the ability for an
|
||||
{@link android.accessibilityservice.AccessibilityService} to query the view
|
||||
hierarchy, collecting information about the the UI component that generated an event, and
|
||||
its parent and children. In order to do this, make sure that you set the
|
||||
following line in your XML configuration:</p>
|
||||
<pre>
|
||||
android:canRetrieveWindowContent="true"
|
||||
</pre>
|
||||
<p>Once that's done, get an {@link
|
||||
android.view.accessibility.AccessibilityNodeInfo} object using {@link
|
||||
android.view.accessibility.AccessibilityEvent#getSource}. This call only
|
||||
returns an object if the window where the event originated is still the active
|
||||
window. If not, it will return null, so <em>behave accordingly</em>. The
|
||||
following example is a snippet of code that, when it receives an event, does
|
||||
the following:
|
||||
<ol>
|
||||
<li>Immediately grab the parent of the view where the event originated</li>
|
||||
<li>In that view, look for a label and a check box as children views</li>
|
||||
<li>If it finds them, create a string to report to the user, indicating
|
||||
the label and whether it was checked or not.</li>
|
||||
<li>If at any point a null value is returned while traversing the view
|
||||
hierarchy, the method quietly gives up.</li>
|
||||
</ol>
|
||||
|
||||
<pre>
|
||||
|
||||
// Alternative onAccessibilityEvent, that uses AccessibilityNodeInfo
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
|
||||
AccessibilityNodeInfo source = event.getSource();
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the parent of the view that fired the event.
|
||||
AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
|
||||
if (rowNode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Using this parent, get references to both child nodes, the label and the checkbox.
|
||||
AccessibilityNodeInfo labelNode = rowNode.getChild(0);
|
||||
if (labelNode == null) {
|
||||
rowNode.recycle();
|
||||
return;
|
||||
}
|
||||
|
||||
AccessibilityNodeInfo completeNode = rowNode.getChild(1);
|
||||
if (completeNode == null) {
|
||||
rowNode.recycle();
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine what the task is and whether or not it's complete, based on
|
||||
// the text inside the label, and the state of the check-box.
|
||||
if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) {
|
||||
rowNode.recycle();
|
||||
return;
|
||||
}
|
||||
|
||||
CharSequence taskLabel = labelNode.getText();
|
||||
final boolean isComplete = completeNode.isChecked();
|
||||
String completeStr = null;
|
||||
|
||||
if (isComplete) {
|
||||
completeStr = getString(R.string.checked);
|
||||
} else {
|
||||
completeStr = getString(R.string.not_checked);
|
||||
}
|
||||
String reportStr = taskLabel + completeStr;
|
||||
speakToUser(reportStr);
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
||||
<p>Now you have a complete, functioning accessibility service. Try configuring
|
||||
how it interacts with the user, by adding Android's <a
|
||||
href="http://developer.android.com/resources/articles/tts.html">text-to-speech
|
||||
engine</a>, or using a {@link android.os.Vibrator} to provide haptic
|
||||
feedback!</p>
|
||||
Reference in New Issue
Block a user