List of usage examples for android.view.accessibility AccessibilityNodeInfo getViewIdResourceName
public String getViewIdResourceName()
From source file:Main.java
public static String getViewIdResourceName(AccessibilityNodeInfo nodeInfo) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { return nodeInfo.getViewIdResourceName(); }//from ww w. j a va 2s . com return null; }
From source file:com.googlecode.eyesfree.brailleback.utils.LabelingUtils.java
/** * Gets the text of a <code>node</code> by returning the content description * (if available) or by returning the text. Will use the specified * <code>CustomLabelManager</code> as a fall back if both are null. * If the label manager is null, does the same funciton as * {@code getNodeText} in {@code AccessibilityNodeInfoUtils} * * @param node The node./* w ww. j ava2 s. c o m*/ * @param labelManager The label manager. * @return The node text. */ public static CharSequence getNodeText(AccessibilityNodeInfoCompat node, CustomLabelManager labelManager) { CharSequence text = AccessibilityNodeInfoUtils.getNodeText(node); if (!TextUtils.isEmpty(text)) { return text; } if (labelManager != null && labelManager.isInitialized()) { // TODO: Don't need to do this when support libs fixed. final AccessibilityNodeInfo unwrappedNode = (AccessibilityNodeInfo) node.getInfo(); Label label = labelManager.getLabelForViewIdFromCache(unwrappedNode.getViewIdResourceName()); if (label != null) { return label.getText(); } } return null; }
From source file:com.google.android.marvin.talkback.speechrules.RuleNonTextViews.java
@Override public CharSequence format(Context context, AccessibilityNodeInfoCompat node, AccessibilityEvent event) { final CharSequence text = super.format(context, node, event); final boolean isClickable = AccessibilityNodeInfoUtils.isClickable(node); final boolean hasLabel = !TextUtils.isEmpty(text); if (hasLabel) { // We speak labeled images as buttons if acitonable, or simply speak // their text if non-actionable. if (isClickable) { return context.getString(R.string.template_button, text); } else {/*from w w w.j ava2 s .c o m*/ return text; } } else { if (mLabelManager != null) { // TODO(caseyburkhardt): Eliminate this dance when support library is fixed. final AccessibilityNodeInfo unwrappedNode = (AccessibilityNodeInfo) node.getInfo(); // Check to see if a custom label exists for the unlabeled control. final Label label = mLabelManager.getLabelForViewIdFromCache(unwrappedNode.getViewIdResourceName()); if (label != null) { final CharSequence labelText = label.getText(); if (isClickable) { return context.getString(R.string.template_button, labelText); } else { return labelText; } } } // We provide as much information about the control as possible in // the case it is unlabeled. final int nodeInt = (node.hashCode() % 100); if (isClickable) { return context.getString(R.string.template_unlabeled_button, nodeInt); } else { return context.getString(R.string.template_unlabeled_image_view, nodeInt); } } }
From source file:com.google.android.marvin.talkback.menurules.RuleUnlabeledImage.java
@Override public List<RadialMenuItem> getMenuItemsForNode(TalkBackService service, AccessibilityNodeInfoCompat node) { final AccessibilityNodeInfoCompat nodeCopy = AccessibilityNodeInfoCompat.obtain(node); // TODO(caseyburkhardt): Undo when the support library is fixed. final AccessibilityNodeInfo unwrappedCopy = (AccessibilityNodeInfo) nodeCopy.getInfo(); final CustomLabelManager labelManager = service.getLabelManager(); final List<RadialMenuItem> items = new LinkedList<RadialMenuItem>(); final Label viewLabel = labelManager.getLabelForViewIdFromCache(unwrappedCopy.getViewIdResourceName()); if (viewLabel == null) { final RadialMenuItem addLabel = new RadialMenuItem(service, RadialMenu.NONE, R.id.labeling_breakout_add_label, RadialMenu.NONE, service.getString(R.string.label_dialog_title_add)); items.add(addLabel);//from w w w . j a v a2 s. c om } else { final RadialMenuItem editLabel = new RadialMenuItem(service, RadialMenu.NONE, R.id.labeling_breakout_edit_label, RadialMenu.NONE, service.getString(R.string.label_dialog_title_edit)); final RadialMenuItem removeLabel = new RadialMenuItem(service, RadialMenu.NONE, R.id.labeling_breakout_remove_label, RadialMenu.NONE, service.getString(R.string.label_dialog_title_remove)); items.add(editLabel); items.add(removeLabel); } for (MenuItem item : items) { item.setOnMenuItemClickListener( new UnlabeledImageMenuItemClickListener(service, unwrappedCopy, viewLabel)); } return items; }
From source file:com.googlecode.eyesfree.brailleback.BrailleMenuNavigationMode.java
/** * Activates the currently selected menu item. *//*w w w .jav a 2 s . co m*/ public boolean activateCurrentMenuItem() { // Grab the state we need before closing the menu, since that // clears out all state. final int itemId = mMenuItems.get(mCurrentIndex).getId(); AccessibilityNodeInfoCompat node = mInitialNode.release(); try { closeMenu(); if (node == null) { return false; } // This must be checked before we try to grab a label. if (itemId == R.string.menu_item_update_talkback) { return launchIntentToPlayStoreTalkBack(); } AccessibilityNodeInfo unwrapped = (AccessibilityNodeInfo) node.getInfo(); final Label existingLabel = mLabelManager.getLabelForViewIdFromCache(unwrapped.getViewIdResourceName()); if (itemId == R.string.menu_item_label_add) { return LabelOperationUtils.startActivityAddLabelForNode(mAccessibilityService, unwrapped); } else if (itemId == R.string.menu_item_label_edit) { return LabelOperationUtils.startActivityEditLabel(mAccessibilityService, existingLabel); } else if (itemId == R.string.menu_item_label_remove) { return LabelOperationUtils.startActivityRemoveLabel(mAccessibilityService, existingLabel); } } finally { AccessibilityNodeInfoUtils.recycleNodes(node); } return false; }
From source file:com.google.android.marvin.talkback.menurules.RuleUnlabeledImage.java
@Override public boolean accept(Context context, AccessibilityNodeInfoCompat node) { final AccessibilityNodeInfo unwrapped = (AccessibilityNodeInfo) node.getInfo(); final boolean isImage = AccessibilityNodeInfoUtils.nodeMatchesClassByType(context, node, android.widget.ImageView.class); final boolean hasDescription = !TextUtils.isEmpty(AccessibilityNodeInfoUtils.getNodeText(node)); final Pair<String, String> parsedId = CustomLabelManager .splitResourceName(unwrapped.getViewIdResourceName()); final boolean hasParseableId = (parsedId != null); // TODO(caseyburkhardt): There are a number of views that have a // different resource namespace than their parent application. It's // likely we'll need to refine the database structure to accommodate // these while also allowing the user to modify them through TalkBack // settings. For now, we'll simply not allow labeling of such views. boolean isFromKnownApp = false; if (hasParseableId) { try {//from ww w. ja v a 2 s .c om context.getPackageManager().getPackageInfo(parsedId.first, 0); isFromKnownApp = true; } catch (NameNotFoundException e) { // Do nothing. } } return (isImage && !hasDescription && hasParseableId && isFromKnownApp); }
From source file:com.googlecode.eyesfree.brailleback.BrailleMenuNavigationMode.java
/** * Returns a list of menu item strings to be shown for the specified node. * May be empty if no items needed (already labeled by developer). *///from ww w .j a v a2s.c o m private List<MenuItem> getItemsForNode(AccessibilityNodeInfoCompat node) { List<MenuItem> items = new ArrayList<MenuItem>(); AccessibilityNodeInfo unwrapped = (AccessibilityNodeInfo) node.getInfo(); boolean hasDescription = !TextUtils.isEmpty(AccessibilityNodeInfoUtils.getNodeText(node)); final Pair<String, String> parsedId = CustomLabelManager .splitResourceName(unwrapped.getViewIdResourceName()); boolean hasParseableId = (parsedId != null); // TODO(caseyburkhardt): There are a number of views that have a // different resource namespace than their parent application. It's // likely we'll need to refine the database structure to accommodate // these while also allowing the user to modify them through TalkBack // settings. For now, we'll simply not allow labeling of such views. boolean isFromKnownApp = false; if (hasParseableId) { try { mAccessibilityService.getPackageManager().getPackageInfo(parsedId.first, 0); isFromKnownApp = true; } catch (NameNotFoundException e) { // Do nothing. } } // Return empty list if it has a description, has no parseable id since // we don't support those in the label manager right now, or if it's id // is in a different namespace than a known package. if (hasDescription || !hasParseableId || !isFromKnownApp) { return items; } // If label manager is not initialized, it is because user has a // version of TalkBack that doesn't support labeling. // Tell the user to update. if (!mLabelManager.isInitialized()) { items.add(new MenuItem(R.string.menu_item_update_talkback, mAccessibilityService)); return items; } final Label viewLabel = mLabelManager.getLabelForViewIdFromCache(unwrapped.getViewIdResourceName()); // If no custom label, only have "add" option. If there is already a // label we have the "edit" and "remove" options. if (viewLabel == null) { items.add(new MenuItem(R.string.menu_item_label_add, mAccessibilityService)); } else { items.add(new MenuItem(R.string.menu_item_label_edit, mAccessibilityService)); items.add(new MenuItem(R.string.menu_item_label_remove, mAccessibilityService)); } return items; }
From source file:com.google.android.apps.common.testing.accessibility.framework.ContrastInfoCheck.java
@Override public List<AccessibilityInfoCheckResult> runCheckOnInfoHierarchy(AccessibilityNodeInfo root, Context context, Bundle metadata) {/* w w w . j a v a 2 s . co m*/ List<AccessibilityInfoCheckResult> results = new ArrayList<AccessibilityInfoCheckResult>(); Bitmap screenCapture = null; if (metadata != null) { screenCapture = metadata.getParcelable(AccessibilityCheckMetadata.METADATA_KEY_SCREEN_CAPTURE_BITMAP); } if (screenCapture == null) { results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.NOT_RUN, "This check did not execute because it was unable to obtain screen capture data.", null)); return results; } AccessibilityNodeInfoCompat rootCompat = new AccessibilityNodeInfoCompat(root); List<AccessibilityNodeInfoCompat> candidates = AccessibilityNodeInfoUtils.searchAllFromBfs(context, rootCompat, FILTER_CONTRAST_EVAL_ELIGIBLE); List<AccessibilityNodeInfoCompat> nonCandidates = AccessibilityNodeInfoUtils.searchAllFromBfs(context, rootCompat, FILTER_CONTRAST_EVAL_INELIGIBLE); // Ineligible nodes all receive NOT_RUN results for (AccessibilityNodeInfoCompat nonCandidate : nonCandidates) { AccessibilityNodeInfo unwrappedNonCandidate = (AccessibilityNodeInfo) nonCandidate.getInfo(); results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.NOT_RUN, "This view's contrast was not evaluated because it contains neither text nor an image.", unwrappedNonCandidate)); } Rect screenCaptureBounds = new Rect(0, 0, screenCapture.getWidth() - 1, screenCapture.getHeight() - 1); for (AccessibilityNodeInfoCompat candidate : candidates) { AccessibilityNodeInfo unwrappedCandidate = (AccessibilityNodeInfo) candidate.getInfo(); Rect viewBounds = new Rect(); unwrappedCandidate.getBoundsInScreen(viewBounds); if (!screenCaptureBounds.contains(viewBounds)) { // If an off-screen view reports itself as visible, we shouldn't evaluate it. String message = String.format("View bounds %1$s were not within the screen capture bounds %2$s.", viewBounds, screenCaptureBounds); results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.NOT_RUN, message, unwrappedCandidate)); continue; } ContrastSwatch candidateSwatch = new ContrastSwatch( ScreenshotUtils.cropBitmap(screenCapture, viewBounds), viewBounds, unwrappedCandidate.getViewIdResourceName()); double contrastRatio = candidateSwatch.getContrastRatio(); if (AccessibilityNodeInfoUtils.nodeMatchesAnyClassByType(context, candidate, TextView.class)) { if (contrastRatio < ContrastUtils.CONTRAST_RATIO_WCAG_LARGE_TEXT) { String message = String.format( "This view's foreground to background contrast ratio " + "(%1$.2f) is not sufficient.", contrastRatio); results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.ERROR, message, unwrappedCandidate)); } else if (contrastRatio < ContrastUtils.CONTRAST_RATIO_WCAG_NORMAL_TEXT) { String message = String.format( "This view's foreground to background contrast ratio " + "(%1$.2f) may not be sufficient unless it contains large text.", contrastRatio); results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.WARNING, message, unwrappedCandidate)); } } else if (AccessibilityNodeInfoUtils.nodeMatchesAnyClassByType(context, candidate, ImageView.class)) { // Lower confidence in heuristics for ImageViews, so we'll report only warnings and use // the more permissive threshold ratio since images are generally large. if (contrastRatio < ContrastUtils.CONTRAST_RATIO_WCAG_LARGE_TEXT) { String message = String.format("This image's foreground to background contrast ratio " + "(%1$.2f) is not sufficient. NOTE: This test is experimental and may be less " + "accurate for some images.", contrastRatio); results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.WARNING, message, unwrappedCandidate)); } } candidateSwatch.recycle(); } AccessibilityNodeInfoUtils.recycleNodes(candidates); AccessibilityNodeInfoUtils.recycleNodes(nonCandidates); return results; }
From source file:com.google.android.apps.common.testing.accessibility.framework.uielement.ViewHierarchyElement.java
ViewHierarchyElement(int id, @Nullable ViewHierarchyElement parent, AccessibilityNodeInfo fromInfo) { // Bookkeeping this.id = id; this.parentId = (parent != null) ? parent.getId() : null; // API 18+ properties this.resourceName = AT_18 ? fromInfo.getViewIdResourceName() : null; this.editable = AT_18 ? fromInfo.isEditable() : null; // API 16+ properties this.visibleToUser = AT_16 ? fromInfo.isVisibleToUser() : null; // Base properties this.className = fromInfo.getClassName(); this.packageName = fromInfo.getPackageName(); this.accessibilityClassName = fromInfo.getClassName(); this.contentDescription = SpannableString.valueOf(fromInfo.getContentDescription()); this.text = SpannableString.valueOf(fromInfo.getText()); this.importantForAccessibility = true; this.clickable = fromInfo.isClickable(); this.longClickable = fromInfo.isLongClickable(); this.focusable = fromInfo.isFocusable(); this.scrollable = fromInfo.isScrollable(); this.canScrollForward = ((fromInfo.getActions() & AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) != 0); this.canScrollBackward = ((fromInfo.getActions() & AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) != 0); this.checkable = fromInfo.isCheckable(); this.checked = fromInfo.isChecked(); this.hasTouchDelegate = false; /* Touch delegates are not considered by AccessibilityServices */ android.graphics.Rect tempRect = new android.graphics.Rect(); fromInfo.getBoundsInScreen(tempRect); this.boundsInScreen = new Rect(tempRect); this.nonclippedHeight = null; /* AccessibilityServices cannot discover nonclipped dimensions */ this.nonclippedWidth = null; /* AccessibilityServices cannot discover nonclipped dimensions */ this.textSize = null; this.textColor = null; this.backgroundDrawableColor = null; this.typefaceStyle = null; this.enabled = fromInfo.isEnabled(); }