下面列出了怎么用android.view.accessibility.AccessibilityNodeProvider的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* If native accessibility is enabled and no other views are temporarily
* obscuring this one, returns an AccessibilityNodeProvider that
* implements native accessibility for this view. Returns null otherwise.
* Lazily initializes native accessibility here if it's allowed.
* @return The AccessibilityNodeProvider, if available, or null otherwise.
*/
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (mIsObscuredByAnotherView) return null;
if (mBrowserAccessibilityManager != null) {
return mBrowserAccessibilityManager.getAccessibilityNodeProvider();
}
if (mNativeAccessibilityAllowed && !mNativeAccessibilityEnabled
&& mNativeContentViewCore != 0) {
mNativeAccessibilityEnabled = true;
nativeSetAccessibilityEnabled(mNativeContentViewCore, true);
}
return null;
}
/**
* If native accessibility (not script injection) is enabled, and if this is
* running on JellyBean or later, returns an AccessibilityNodeProvider that
* implements native accessibility for this view. Returns null otherwise.
* Lazily initializes native accessibility here if it's allowed.
* @return The AccessibilityNodeProvider, if available, or null otherwise.
*/
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (mBrowserAccessibilityManager != null) {
return mBrowserAccessibilityManager.getAccessibilityNodeProvider();
}
if (mNativeAccessibilityAllowed &&
!mNativeAccessibilityEnabled &&
mNativeContentViewCore != 0 &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mNativeAccessibilityEnabled = true;
nativeSetAccessibilityEnabled(mNativeContentViewCore, true);
}
return null;
}
/**
* If native accessibility (not script injection) is enabled, and if this is
* running on JellyBean or later, returns an AccessibilityNodeProvider that
* implements native accessibility for this view. Returns null otherwise.
* Lazily initializes native accessibility here if it's allowed.
* @return The AccessibilityNodeProvider, if available, or null otherwise.
*/
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (mBrowserAccessibilityManager != null) {
return mBrowserAccessibilityManager.getAccessibilityNodeProvider();
}
if (mNativeAccessibilityAllowed &&
!mNativeAccessibilityEnabled &&
mNativeContentViewCore != 0 &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mNativeAccessibilityEnabled = true;
nativeSetAccessibilityEnabled(mNativeContentViewCore, true);
}
return null;
}
private AccessibilityNodeInfo findVirtualNodeByAccessibilityId(View view, int virtualId) {
final AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
if (provider == null) {
return null;
}
return provider.createAccessibilityNodeInfo(virtualId);
}
private boolean handleClickableSpanActionUiThread(
View view, int virtualDescendantId, Bundle arguments) {
Parcelable span = arguments.getParcelable(ACTION_ARGUMENT_ACCESSIBLE_CLICKABLE_SPAN);
if (!(span instanceof AccessibilityClickableSpan)) {
return false;
}
// Find the original ClickableSpan if it's still on the screen
AccessibilityNodeInfo infoWithSpan = null;
AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
if (provider != null) {
infoWithSpan = provider.createAccessibilityNodeInfo(virtualDescendantId);
} else if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
infoWithSpan = view.createAccessibilityNodeInfo();
}
if (infoWithSpan == null) {
return false;
}
// Click on the corresponding span
ClickableSpan clickableSpan = ((AccessibilityClickableSpan) span).findClickableSpan(
infoWithSpan.getOriginalText());
if (clickableSpan != null) {
clickableSpan.onClick(view);
return true;
}
return false;
}
private void prefetchSiblingsOfRealNode(View current,
List<AccessibilityNodeInfo> outInfos) {
ViewParent parent = current.getParentForAccessibility();
if (parent instanceof ViewGroup) {
ViewGroup parentGroup = (ViewGroup) parent;
ArrayList<View> children = mTempViewList;
children.clear();
try {
parentGroup.addChildrenForAccessibility(children);
final int childCount = children.size();
for (int i = 0; i < childCount; i++) {
if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
return;
}
View child = children.get(i);
if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
&& isShown(child)) {
AccessibilityNodeInfo info = null;
AccessibilityNodeProvider provider =
child.getAccessibilityNodeProvider();
if (provider == null) {
info = child.createAccessibilityNodeInfo();
} else {
info = provider.createAccessibilityNodeInfo(
AccessibilityNodeProvider.HOST_VIEW_ID);
}
if (info != null) {
outInfos.add(info);
}
}
}
} finally {
children.clear();
}
}
}
private void prefetchPredecessorsOfVirtualNode(AccessibilityNodeInfo root,
View providerHost, AccessibilityNodeProvider provider,
List<AccessibilityNodeInfo> outInfos) {
final int initialResultSize = outInfos.size();
long parentNodeId = root.getParentNodeId();
int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
while (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
return;
}
final int virtualDescendantId =
AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
if (virtualDescendantId != AccessibilityNodeProvider.HOST_VIEW_ID
|| accessibilityViewId == providerHost.getAccessibilityViewId()) {
final AccessibilityNodeInfo parent;
parent = provider.createAccessibilityNodeInfo(virtualDescendantId);
if (parent == null) {
// Going up the parent relation we found a null predecessor,
// so remove these disconnected nodes form the result.
final int currentResultSize = outInfos.size();
for (int i = currentResultSize - 1; i >= initialResultSize; i--) {
outInfos.remove(i);
}
// Couldn't obtain the parent, which means we have a
// disconnected sub-tree. Abort prefetch immediately.
return;
}
outInfos.add(parent);
parentNodeId = parent.getParentNodeId();
accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
parentNodeId);
} else {
prefetchPredecessorsOfRealNode(providerHost, outInfos);
return;
}
}
}
private void prefetchSiblingsOfVirtualNode(AccessibilityNodeInfo current, View providerHost,
AccessibilityNodeProvider provider, List<AccessibilityNodeInfo> outInfos) {
final long parentNodeId = current.getParentNodeId();
final int parentAccessibilityViewId =
AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
final int parentVirtualDescendantId =
AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
if (parentVirtualDescendantId != AccessibilityNodeProvider.HOST_VIEW_ID
|| parentAccessibilityViewId == providerHost.getAccessibilityViewId()) {
final AccessibilityNodeInfo parent =
provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
if (parent != null) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
return;
}
final long childNodeId = parent.getChildId(i);
if (childNodeId != current.getSourceNodeId()) {
final int childVirtualDescendantId =
AccessibilityNodeInfo.getVirtualDescendantId(childNodeId);
AccessibilityNodeInfo child = provider.createAccessibilityNodeInfo(
childVirtualDescendantId);
if (child != null) {
outInfos.add(child);
}
}
}
}
} else {
prefetchSiblingsOfRealNode(providerHost, outInfos);
}
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (!mHasSelectorWheel) {
return super.getAccessibilityNodeProvider();
}
if (mAccessibilityNodeProvider == null) {
mAccessibilityNodeProvider = new AccessibilityNodeProviderImpl();
}
return mAccessibilityNodeProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (!mHasSelectorWheel) {
return super.getAccessibilityNodeProvider();
}
if (mAccessibilityNodeProvider == null) {
mAccessibilityNodeProvider = new AccessibilityNodeProviderImpl();
}
return mAccessibilityNodeProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (!mHasSelectorWheel) {
return super.getAccessibilityNodeProvider();
}
if (mAccessibilityNodeProvider == null) {
mAccessibilityNodeProvider = new AccessibilityNodeProviderImpl();
}
return mAccessibilityNodeProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (!mHasSelectorWheel) {
return super.getAccessibilityNodeProvider();
}
if (mAccessibilityNodeProvider == null) {
mAccessibilityNodeProvider = new AccessibilityNodeProviderImpl();
}
return mAccessibilityNodeProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (!mHasSelectorWheel) {
return super.getAccessibilityNodeProvider();
}
if (mAccessibilityNodeProvider == null) {
mAccessibilityNodeProvider = new SupportAccessibilityNodeProvider();
}
return mAccessibilityNodeProvider.mProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
AccessibilityNodeProvider provider = mContentViewCore.getAccessibilityNodeProvider();
if (provider != null) {
return provider;
} else {
return super.getAccessibilityNodeProvider();
}
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (mAccessibilityNodeProvider == null) {
mAccessibilityNodeProvider = new VirtualTreeProvider();
}
return mAccessibilityNodeProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
if (!mHasSelectorWheel) {
return super.getAccessibilityNodeProvider();
}
if (mAccessibilityNodeProvider == null) {
mAccessibilityNodeProvider = new SupportAccessibilityNodeProvider();
}
return mAccessibilityNodeProvider.mProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
AccessibilityNodeProvider provider = getContentViewCore().getAccessibilityNodeProvider();
if (provider != null) {
return provider;
} else {
return super.getAccessibilityNodeProvider();
}
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
AccessibilityNodeProvider provider = getContentViewCore().getAccessibilityNodeProvider();
if (provider != null) {
return provider;
} else {
return super.getAccessibilityNodeProvider();
}
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
AccessibilityNodeProvider provider =
mProvider.getViewDelegate().getAccessibilityNodeProvider();
return provider == null ? super.getAccessibilityNodeProvider() : provider;
}
private boolean isVirtualNode(int nodeId) {
return nodeId != AccessibilityNodeProvider.HOST_VIEW_ID
&& nodeId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
}
/**
* Check if this message needs to be held off while the app prepares to meet either this
* request, or a request ahead of it.
*
* @param originalMessage The message to be processed
* @param callingPid The calling process id
* @param callingTid The calling thread id
*
* @return {@code true} if the message is held off and will be processed later, {@code false} if
* the message should be posted.
*/
private boolean holdOffMessageIfNeeded(
Message originalMessage, int callingPid, long callingTid) {
synchronized (mLock) {
// If a request is already pending, queue this request for when it's finished
if (mNumActiveRequestPreparers != 0) {
queueMessageToHandleOncePrepared(originalMessage, callingPid, callingTid);
return true;
}
// Currently the only message that can hold things off is findByA11yId with extra data.
if (originalMessage.what
!= PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID) {
return false;
}
SomeArgs originalMessageArgs = (SomeArgs) originalMessage.obj;
Bundle requestArguments = (Bundle) originalMessageArgs.arg4;
if (requestArguments == null) {
return false;
}
// If nothing it registered for this view, nothing to do
int accessibilityViewId = originalMessageArgs.argi1;
final List<AccessibilityRequestPreparer> preparers =
mA11yManager.getRequestPreparersForAccessibilityId(accessibilityViewId);
if (preparers == null) {
return false;
}
// If the bundle doesn't request the extra data, nothing to do
final String extraDataKey = requestArguments.getString(EXTRA_DATA_REQUESTED_KEY);
if (extraDataKey == null) {
return false;
}
// Send the request to the AccessibilityRequestPreparers on the UI thread
mNumActiveRequestPreparers = preparers.size();
for (int i = 0; i < preparers.size(); i++) {
final Message requestPreparerMessage = mHandler.obtainMessage(
PrivateHandler.MSG_PREPARE_FOR_EXTRA_DATA_REQUEST);
final SomeArgs requestPreparerArgs = SomeArgs.obtain();
// virtualDescendentId
requestPreparerArgs.argi1 =
(originalMessageArgs.argi2 == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)
? AccessibilityNodeProvider.HOST_VIEW_ID : originalMessageArgs.argi2;
requestPreparerArgs.arg1 = preparers.get(i);
requestPreparerArgs.arg2 = extraDataKey;
requestPreparerArgs.arg3 = requestArguments;
Message preparationFinishedMessage = mHandler.obtainMessage(
PrivateHandler.MSG_APP_PREPARATION_FINISHED);
preparationFinishedMessage.arg1 = ++mActiveRequestPreparerId;
requestPreparerArgs.arg4 = preparationFinishedMessage;
requestPreparerMessage.obj = requestPreparerArgs;
scheduleMessage(requestPreparerMessage, callingPid, callingTid,
IGNORE_REQUEST_PREPARERS);
mHandler.obtainMessage(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT);
mHandler.sendEmptyMessageDelayed(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT,
REQUEST_PREPARER_TIMEOUT_MS);
}
// Set the initial request aside
queueMessageToHandleOncePrepared(originalMessage, callingPid, callingTid);
return true;
}
}
private void findAccessibilityNodeInfosByTextUiThread(Message message) {
final int flags = message.arg1;
SomeArgs args = (SomeArgs) message.obj;
final String text = (String) args.arg1;
final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg2;
final MagnificationSpec spec = (MagnificationSpec) args.arg3;
final int accessibilityViewId = args.argi1;
final int virtualDescendantId = args.argi2;
final int interactionId = args.argi3;
final Region interactiveRegion = (Region) args.arg4;
args.recycle();
List<AccessibilityNodeInfo> infos = null;
try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
View root = null;
if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
root = findViewByAccessibilityId(accessibilityViewId);
} else {
root = mViewRootImpl.mView;
}
if (root != null && isShown(root)) {
AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
if (provider != null) {
infos = provider.findAccessibilityNodeInfosByText(text,
virtualDescendantId);
} else if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
ArrayList<View> foundViews = mTempArrayList;
foundViews.clear();
root.findViewsWithText(foundViews, text, View.FIND_VIEWS_WITH_TEXT
| View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION
| View.FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS);
if (!foundViews.isEmpty()) {
infos = mTempAccessibilityNodeInfoList;
infos.clear();
final int viewCount = foundViews.size();
for (int i = 0; i < viewCount; i++) {
View foundView = foundViews.get(i);
if (isShown(foundView)) {
provider = foundView.getAccessibilityNodeProvider();
if (provider != null) {
List<AccessibilityNodeInfo> infosFromProvider =
provider.findAccessibilityNodeInfosByText(text,
AccessibilityNodeProvider.HOST_VIEW_ID);
if (infosFromProvider != null) {
infos.addAll(infosFromProvider);
}
} else {
infos.add(foundView.createAccessibilityNodeInfo());
}
}
}
}
}
}
} finally {
updateInfosForViewportAndReturnFindNodeResult(
infos, callback, interactionId, spec, interactiveRegion);
}
}
private void performAccessibilityActionUiThread(Message message) {
final int flags = message.arg1;
final int accessibilityViewId = message.arg2;
SomeArgs args = (SomeArgs) message.obj;
final int virtualDescendantId = args.argi1;
final int action = args.argi2;
final int interactionId = args.argi3;
final IAccessibilityInteractionConnectionCallback callback =
(IAccessibilityInteractionConnectionCallback) args.arg1;
Bundle arguments = (Bundle) args.arg2;
args.recycle();
boolean succeeded = false;
try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null ||
mViewRootImpl.mStopped || mViewRootImpl.mPausedForTransition) {
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
View target = null;
if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
target = findViewByAccessibilityId(accessibilityViewId);
} else {
target = mViewRootImpl.mView;
}
if (target != null && isShown(target)) {
if (action == R.id.accessibilityActionClickOnClickableSpan) {
// Handle this hidden action separately
succeeded = handleClickableSpanActionUiThread(
target, virtualDescendantId, arguments);
} else {
AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
if (provider != null) {
succeeded = provider.performAction(virtualDescendantId, action,
arguments);
} else if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
succeeded = target.performAccessibilityAction(action, arguments);
}
}
}
} finally {
try {
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
callback.setPerformAccessibilityActionResult(succeeded, interactionId);
} catch (RemoteException re) {
/* ignore - the other side will time out */
}
}
}
/**
* @return An AccessibilityNodeProvider.
*/
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
return mAccessibilityNodeProvider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
AccessibilityNodeProvider provider =
mAwContents.getAccessibilityNodeProvider();
return provider == null ? super.getAccessibilityNodeProvider() : provider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
return mAccessibilityNodeProvider;
}
/**
* @return An AccessibilityNodeProvider on JellyBean, and null on previous versions.
*/
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
return null;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
AccessibilityNodeProvider provider =
mAwContents.getAccessibilityNodeProvider();
return provider == null ? super.getAccessibilityNodeProvider() : provider;
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
return mAccessibilityNodeProvider;
}
/**
* @return An AccessibilityNodeProvider on JellyBean, and null on previous versions.
*/
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
return null;
}