下面列出了android.view.accessibility.AccessibilityNodeInfo#getPackageName ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public void init(AccessibilityNodeInfo node) {
if (sealed) {
throw new IllegalArgumentException("sealed! " + super.toString());
}
mKey = node.hashCode();
mClassName = node.getClassName();
mPackageName = node.getPackageName();
mIsTextView = isATextView(node);
mIsEditText = isAEditText(node);
mIsWebView = isAWebView(node);
mBoundsInScreen = new Rect();
mBoundsInParent = new Rect();
mIsVisibleToUser = node.isVisibleToUser();
refresh(node);
}
/**
* Determines if the generating class of an
* {@link AccessibilityNodeInfo} matches a given {@link Class} by
* type.
*
* @param node A sealed {@link AccessibilityNodeInfo} dispatched by
* the accessibility framework.
* @param referenceClass A {@link Class} to match by type or inherited type.
* @return {@code true} if the {@link AccessibilityNodeInfo} object
* matches the {@link Class} by type or inherited type,
* {@code false} otherwise.
*/
public static boolean nodeMatchesClassByType(
Context context, AccessibilityNodeInfo node, Class<?> referenceClass) {
if ((node == null) || (referenceClass == null)) {
return false;
}
// Attempt to take a shortcut.
final CharSequence nodeClassName = node.getClassName();
if (TextUtils.equals(nodeClassName, referenceClass.getName())) {
return true;
}
final ClassLoadingManager loader = ClassLoadingManager.getInstance();
final CharSequence appPackage = node.getPackageName();
return loader.checkInstanceOf(context, nodeClassName, appPackage, referenceClass);
}
/**
* Determines if the class of an {@link AccessibilityNodeInfo} matches
* a given {@link Class} by package and name.
*
* @param node A sealed {@link AccessibilityNodeInfo} dispatched by
* the accessibility framework.
* @param referenceClassName A class name to match.
* @return {@code true} if the {@link AccessibilityNodeInfo} matches
* the class name.
*/
public static boolean nodeMatchesClassByName(
Context context, AccessibilityNodeInfo node, CharSequence referenceClassName) {
if ((node == null) || (referenceClassName == null)) {
return false;
}
// Attempt to take a shortcut.
final CharSequence nodeClassName = node.getClassName();
if (TextUtils.equals(nodeClassName, referenceClassName)) {
return true;
}
final ClassLoadingManager loader = ClassLoadingManager.getInstance();
final CharSequence appPackage = node.getPackageName();
return loader.checkInstanceOf(context, nodeClassName, appPackage, referenceClassName);
}
/**
* 返回事件
*/
public static void performBack(final AccessibilityService service, AccessibilityNodeInfo nodeInfo) {
CharSequence packageName = nodeInfo.getPackageName();
if (!(packageName+"").equals(WECHAT_PACKAGE_NAME)) {
L.d("不是微信,不能后退 " + packageName);
return;
}
if (service == null) {
L.e("performBackWithDelay service is null");
return;
}
if (service.getRootInActiveWindow() == null) {
L.e("performBackWithDelay rootNode is null");
return;
}
L.d("performBack Reboot ");
service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
}
/**
* Last package to report accessibility events
* @return String name of package
*/
public String getCurrentPackageName() {
mUiAutomatorBridge.waitForIdle();
AccessibilityNodeInfo rootNode = getRootNode();
if (rootNode == null)
return null;
return rootNode.getPackageName() != null ? rootNode.getPackageName().toString() : null;
}
/**
* Last package to report accessibility events
*
* @return String name of package
*/
public String getCurrentPackageName() {
mUiAutomatorBridge.waitForIdle();
AccessibilityNodeInfo rootNode = getRootNode();
if (rootNode == null)
return null;
return rootNode.getPackageName() != null ? rootNode.getPackageName()
.toString() : null;
}
private static String print(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null)
return "";
CharSequence text = nodeInfo.getText();
CharSequence description = nodeInfo.getContentDescription();
CharSequence className = nodeInfo.getClassName();
CharSequence packageName = nodeInfo.getPackageName();
boolean focusable = nodeInfo.isFocusable();
boolean clickable = nodeInfo.isClickable();
Rect rect = new Rect();
nodeInfo.getBoundsInScreen(rect);
String viewId = nodeInfo.getViewIdResourceName();
return "| "
+ "text: " + text + " \t"
+ "description: " + description + " \t"
+ String.format("%-40s", "ID: " + viewId) + " \t"
+ String.format("%-40s", "class: " + className) + " \t"
+ String.format("%-30s", "location: " + rect) + " \t"
// + "focusable: " + focusable + " \t"
// + "clickable: " + clickable + " \t"
// + String.format("%-30s", "package: " + packageName) + " \t"
;
}
private void handleScrapeAll_MAIN(String reason, PerformNodeAction nodeAction) {
checkHandlerThread();
mTree.clear();
AccessibilityNodeInfo rootNode = null;
try {
rootNode = getRootInActiveWindow();
} catch (Exception ex) {
Ln.e(ex);
return;
}
try {
if (rootNode != null) {
//fail-fast if this is not a package we're interested in
CharSequence csPackageName = rootNode.getPackageName();
if (csPackageName == null) return;
String aPackageName = rootNode.getPackageName().toString();
boolean ours = mCore.getDb().isShowDecryptOverlay(aPackageName);
if (!ours) {
mCore.onAcsScrapeCompleted(aPackageName, null);
return;
}
findFocusedNodePreLollipop_startTransaction();
if (LoggingConfig.INSTANCE.getLOG()) {
Ln.d("SKRAPE: FULL SCAN, root=%s", rootNode.hashCode());
}
mTree.addRootNode(rootNode);
scrapeSubtree_MAIN(rootNode, "handleScrapeAll_MAIN-> " + reason, nodeAction);
rootNode.recycle();
findFocusedNodePreLollipop_commitTransaction();
publishChanges_MAIN();
} else {
Ln.w("SKRAPE: getRootInActiveWindow returned null node!");
clearFocusedNode_PreLollipop();
//TODO: one reason for this might be a too large binder transaction -> maybe at least give some feedback to the user
//TODO: or somehow scrape sub-nodes first in order to have separate smalle transactions?#
// How to Prevent MAX binder transaction / max parcel overflow, Could happen when getting a list node with many immediate GPG text views (the listnode prefetches its children, and if all of them have a long pgp encoded text, this may just be too much for a single binder transaction)
// size is 1 mb, let's say 50 nodes gives 20 k per node, worst case every character is encoded with 4 bytes gives 5 k text!!! -> might just be enough for pgp
// >hmmm, prefetching descendants works recursively, but will always fetch max. 50 nodes,
// -> hopefully not needed but there's noreal way around it!other than using reflection to get the child node's IDs and then manually doing refresh
}
} finally {
if (nodeAction != null) {
nodeAction.onScrapeComplete();
}
}
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
super.onAccessibilityEvent(event);
AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
if (rootInActiveWindow == null) {
L.d("openContactInfo nodeInfo is null");
return;
}
L.d("得到当前包名 "+rootInActiveWindow.getPackageName() + " 类名 " + rootInActiveWindow.getClass());
if (rootInActiveWindow.getPackageName() != null &&
!(rootInActiveWindow.getPackageName() + "").equals("com.tencent.mm")) {
L.e("不是 微信 返回");
return;
}
if (mIsNeedCloseWeChat) {
if (rootInActiveWindow.getPackageName() != null &&
(rootInActiveWindow.getPackageName() + "").equals(AccessUtil.WECHAT_PACKAGE_NAME)) {
if (AccessUtil.isWeChatMain(rootInActiveWindow)) {
mIsNeedCloseWeChat = false;
L.d("ismain");
mActivity.startActivity(mIntent);
} else {
AccessUtil.performBack(this, rootInActiveWindow);
}
return;
} else {
// mIsNeedCloseWeChat = false;
// if (mIntent != null && mActivity != null) {
// mActivity.startActivity(mIntent);
// }
}
}
int eventType = event.getEventType();
switch (eventType) {
//第一步:监听通知栏消息
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
WeChatMsg.sendNotify(event);
break;
//第二步:监听是否进入微信聊天界面
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
// WeChatNearly.nearly(this, getRootInActiveWindow(), this, "你好");
L.d("type " + type);
switch (type) {
case Mode.autoHello://自动打招呼
mWeChatNearly.change(this, rootInActiveWindow, this, "你好");
break;
case Mode.group://群发
mWeChatGroup.change(this, rootInActiveWindow, this, "你好");
break;
case Mode.autoChat://自动聊天
mWeChatAutoReply.change(this, rootInActiveWindow, this, "你好");
break;
case Mode.closeService://无法实现
AccessUtil.openNext(rootInActiveWindow, "测试");
break;
}
break;
default:
break;
}
}
Builder(int id, @Nullable ViewHierarchyElementAndroid 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;
// API 21+ properties
if (AT_21) {
ImmutableList.Builder<ViewHierarchyActionAndroid> actionBuilder =
new ImmutableList.Builder<>();
actionBuilder.addAll(
Lists.transform(
fromInfo.getActionList(),
action -> ViewHierarchyActionAndroid.newBuilder(action).build()));
this.actionList = actionBuilder.build();
}
// API 24+ properties
this.drawingOrder = AT_24 ? fromInfo.getDrawingOrder() : null;
// API 29+ properties
this.hasTouchDelegate = AT_29 ? (fromInfo.getTouchDelegateInfo() != null) : null;
// Base properties
this.className = fromInfo.getClassName();
this.packageName = fromInfo.getPackageName();
this.accessibilityClassName = fromInfo.getClassName();
this.contentDescription = SpannableStringAndroid.valueOf(fromInfo.getContentDescription());
this.text = SpannableStringAndroid.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.touchDelegateBounds = new ArrayList<>(); // Populated after construction
android.graphics.Rect tempRect = new android.graphics.Rect();
fromInfo.getBoundsInScreen(tempRect);
this.boundsInScreen = new Rect(tempRect.left, tempRect.top, tempRect.right, tempRect.bottom);
this.nonclippedHeight = null;
this.nonclippedWidth = null;
this.textSize = null;
this.textColor = null;
this.backgroundDrawableColor = null;
this.typefaceStyle = null;
this.enabled = fromInfo.isEnabled();
}