下面列出了android.view.accessibility.AccessibilityNodeInfo#performAction ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 模拟输入
*
* @param nodeInfo nodeInfo
* @param text text
*/
public void inputText(AccessibilityNodeInfo nodeInfo, CharSequence text) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Bundle args = new Bundle();
args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args);
} else {
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
if (cm == null)
return;
ClipData clipData = ClipData.newPlainText("label", text);
cm.setPrimaryClip(clipData);
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PASTE);
}
}
/**
* set text into input text at USSD widget
*
* @param event AccessibilityEvent
* @param data Any String
*/
private static void setTextIntoField(AccessibilityEvent event, String data) {
USSDController ussdController = USSDController.Companion.getInstance();
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, data);
for (AccessibilityNodeInfo leaf : getLeaves(event)) {
if (leaf.getClassName().equals("android.widget.EditText")
&& !leaf.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)) {
ClipboardManager clipboardManager = ((ClipboardManager) ussdController.getContext()
.getSystemService(Context.CLIPBOARD_SERVICE));
if (clipboardManager != null) {
clipboardManager.setPrimaryClip(ClipData.newPlainText("text", data));
}
leaf.performAction(AccessibilityNodeInfo.ACTION_PASTE);
}
}
}
public static void inputText(Context context, AccessibilityService service, AccessibilityNodeInfo nodeInfo,
final String hello) {
//找到当前获取焦点的view
// AccessibilityNodeInfo target = nodeInfo.findFocus(AccessibilityNodeInfo.FOCUS_INPUT);
AccessUtil.findNodeInfosByName(nodeInfo, "android.widget.EditText");
AccessibilityNodeInfo target = editText;
if (target == null) {
L.d("inputHello: null");
return;
} else {
L.d("inputHello: not null " + target.getText());
}
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("message", hello);
clipboard.setPrimaryClip(clip);
L.d("设置粘贴板");
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
// target.performAction(AccessibilityNodeInfo.ACTION_PASTE);
// }
target.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
L.d("获取焦点");
target.performAction(AccessibilityNodeInfo.ACTION_PASTE);
L.d("粘贴内容");
// openNext2("发送", nodeInfo, service);//点击发送
}
private void clickAction(List<AccessibilityNodeInfo> infolist)
{
for (AccessibilityNodeInfo node :infolist)
{
String text=node.getText().toString();
AccessibilityNodeInfo info=getClickableNode(node);
if (info == null) continue;
// Log.i(TAG, "模拟点击>>>" + text);
info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
if (text.equals(QQ_KEYWORD_HONGBAO[1]))
{
onClick();
}
else
{
isNeedBack = true;
}
}
runState = false;
ToastUtil.show(this,(System.currentTimeMillis() - time) + "*", Toast.LENGTH_SHORT);
//Log.i(TAG, "总共耗时:" + (System.currentTimeMillis() - time) + "ms");
}
private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo != null) {
int childCount = nodeInfo.getChildCount();
if ("android.widget.Button".equals(nodeInfo.getClassName())) {
String nodeContent = nodeInfo.getText().toString();
// Log.d("TAG", "content is " + nodeContent);
if ("安装".equals(nodeContent)|| "完成".equals(nodeContent) || "确定".equals(nodeContent)) {
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
return true;
}
} else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
}
for (int i = 0; i < childCount; i++) {
AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
if (iterateNodesAndHandle(childNodeInfo)) {
return true;
}
}
}
return false;
}
private boolean watchList(AccessibilityEvent event) {
// Not a message
if ((event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && event.getEventType() != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) || event.getSource() == null)
return false;
List<AccessibilityNodeInfo> nodes = event.getSource().findAccessibilityNodeInfosByText(WECHAT_NOTIFICATION_TIP);
if (!nodes.isEmpty()) {
CharSequence contentDescription;
AccessibilityNodeInfo nodeToClick;
synchronized (this) {
nodeToClick = nodes.get(0);
if (nodeToClick == null) return false;
contentDescription = nodeToClick.getContentDescription();
if (contentDescription != null)
if (!lastContentDescription.equals(contentDescription)) {
nodeToClick.performAction(AccessibilityNodeInfo.ACTION_CLICK);
lastContentDescription = contentDescription.toString();
return true;
}
}
}
return false;
}
private void clickAction(List<AccessibilityNodeInfo> infolist) {
for (AccessibilityNodeInfo node : infolist) {
String text = node.getText().toString();
AccessibilityNodeInfo info = getClickableNode(node);
if (info == null) continue;
// Log.i(TAG, "模拟点击>>>" + text);
info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
if (text.equals(QQ_KEYWORD_HONGBAO[1])) {
onClick();
} else {
isNeedBack = true;
}
}
runState = false;
ToastUtil.show(this, (System.currentTimeMillis() - time) + "*", Toast.LENGTH_SHORT);
//Log.i(TAG, "总共耗时:" + (System.currentTimeMillis() - time) + "ms");
}
/**
* Clears the existing text contents in an editable field.
*
* The {@link UiSelector} of this object must reference a UI element that is editable.
*
* When you call this method, the method sets focus on the editable field, selects all of its
* existing content, and clears it by sending a DELETE key press
*
* @throws UiObjectNotFoundException
* @since API Level 16
*/
public void clearTextField() throws UiObjectNotFoundException {
Tracer.trace();
// long click left + center
AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
if(node == null) {
throw new UiObjectNotFoundException(mUiSelector.toString());
}
CharSequence text = node.getText();
// do nothing if already empty
if (text != null && text.length() > 0) {
if (UiDevice.API_LEVEL_ACTUAL > Build.VERSION_CODES.KITKAT) {
setText("");
} else {
Bundle selectionArgs = new Bundle();
// select all of the existing text
selectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
selectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT,
text.length());
boolean ret = node.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
if (!ret) {
Log.w(LOG_TAG, "ACTION_FOCUS on text field failed.");
}
ret = node.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, selectionArgs);
if (!ret) {
Log.w(LOG_TAG, "ACTION_SET_SELECTION on text field failed.");
}
// now delete all
getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);
}
}
}
/**
* click a button using the index
*
* @param event AccessibilityEvent
* @param index button's index
*/
protected static void clickOnButton(AccessibilityEvent event, int index) {
int count = -1;
for (AccessibilityNodeInfo leaf : getLeaves(event)) {
if (leaf.getClassName().toString().toLowerCase().contains("button")) {
count++;
if (count == index) {
leaf.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
/**
* 在检测到空通知体的时候 enable flag
* 在之后的10次 onContentChange 都去检查微信登录
*/
private void autoLoginWX() {
while (App.WeChatAutoLoginTimes > 0) {
AccessibilityNodeInfo root = getRootInActiveWindow();
if (root == null) {
Log.d(TAG, "autoLoginWX: root is null, return");
return;
}
App.WeChatAutoLoginTimes--;
Log.v(TAG, "autoLoginWX");
if (root.getChildCount() != 1) {
Log.v(TAG, "autoLoginWX: 1");
return;
}
AccessibilityNodeInfo node = root.getChild(0);
if (node.getChildCount() != 5) {
Log.v(TAG, "autoLoginWX: 2");
return;
}
//不直接判断字符串是因为多语言适应
AccessibilityNodeInfo loginBtn = node.getChild(3);
if (!loginBtn.isClickable()) {
Log.v(TAG, "autoLoginWX: 3");
return;
}
if (!node.getChild(0).isClickable()) {
Log.v(TAG, "autoLoginWX: 4");
return;
}
if (!node.getChild(4).isClickable()) {
Log.v(TAG, "autoLoginWX: 5");
return;
}
loginBtn.performAction(AccessibilityNodeInfo.ACTION_CLICK);
Log.w(TAG, "autoLoginWX: Perform Click");
App.WeChatAutoLoginTimes = 0;
}
}
/**
* Clears the existing text contents in an editable field.
*
* The {@link UiSelector} of this object must reference a UI element that is editable.
*
* When you call this method, the method sets focus on the editable field, selects all of its
* existing content, and clears it by sending a DELETE key press
*
* @throws UiObjectNotFoundException
* @since API Level 16
*/
public void clearTextField() throws UiObjectNotFoundException {
Tracer.trace();
// long click left + center
AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
if(node == null) {
throw new UiObjectNotFoundException(mUiSelector.toString());
}
CharSequence text = node.getText();
// do nothing if already empty
if (text != null && text.length() > 0) {
if (UiDevice.API_LEVEL_ACTUAL > Build.VERSION_CODES.KITKAT) {
setText("");
} else {
Bundle selectionArgs = new Bundle();
// select all of the existing text
selectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
selectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT,
text.length());
boolean ret = node.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
if (!ret) {
Log.w(LOG_TAG, "ACTION_FOCUS on text field failed.");
}
ret = node.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, selectionArgs);
if (!ret) {
Log.w(LOG_TAG, "ACTION_SET_SELECTION on text field failed.");
}
// now delete all
getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);
}
}
}
/**
* Perform accessibility action ACTION_SET_PROGRESS on the node
*
* @param value desired progress value
* @return true if action performed successfully
*/
@TargetApi(Build.VERSION_CODES.N)
public static boolean setProgressValue(final AccessibilityNodeInfo node, final float value) {
if (!node.getActionList().contains(AccessibilityAction.ACTION_SET_PROGRESS)) {
Logger.debug("The element does not support ACTION_SET_PROGRESS action.");
return false;
}
Logger.debug(String.format(
"Trying to perform ACTION_SET_PROGRESS accessibility action with value %s", value));
final Bundle args = new Bundle();
args.putFloat(AccessibilityNodeInfo.ACTION_ARGUMENT_PROGRESS_VALUE, value);
return node.performAction(AccessibilityAction.ACTION_SET_PROGRESS.getId(), args);
}
private void performClick(String resourceId) {
Log.i("mService","点击执行");
AccessibilityNodeInfo nodeInfo = this.getRootInActiveWindow();
AccessibilityNodeInfo targetNode = null;
targetNode = findNodeInfosById(nodeInfo,"com.youmi.android.addemo:id/"+resourceId);
if (targetNode.isClickable()) {
targetNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
public boolean moveThumbBackward() throws UiObjectNotFoundException {
AccessibilityNodeInfo ani =
findAccessibilityNodeInfo(Configurator.getInstance().getWaitForSelectorTimeout());
if (ani == null) {
throw new UiObjectNotFoundException(getSelector().toString());
}
return ani.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
}
/**
* performClickAction
* @param aAccessibilityNodeInfo aAccessibilityNodeInfo
* @return
*/
private boolean performClickAction(AccessibilityNodeInfo aAccessibilityNodeInfo) {
int targetAction = AccessibilityNodeInfo.ACTION_CLICK;
if ((aAccessibilityNodeInfo != null) && aAccessibilityNodeInfo.isEnabled() && aAccessibilityNodeInfo.isClickable()
&& aAccessibilityNodeInfo.performAction(targetAction)) {
return true;
}
return false;
}
/**
* 点击事件
*/
public static void performClick(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
return;
}
if (nodeInfo.isClickable()) {
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
} else {
performClick(nodeInfo.getParent());
}
}
private void bringUpSkb(AccessibilityNodeInfo node) {
//note: bringing up SKB works only for >= Lollipop,
//kitkat and such will have to live with the SKB going away when back from encryption params and such
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
//this will bring up the SLB only from Lollipop onwards, see http://stackoverflow.com/questions/26405371/android-accessibility-service-focus-edittext
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
public static void perform_scroll_forward(AccessibilityNodeInfo nodeInfo) {
if(nodeInfo == null) {
return;
}
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
}
public static void perform_scroll_backward(AccessibilityNodeInfo nodeInfo) {
if(nodeInfo == null) {
return;
}
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
}
/**
* Set text of an element
*
* @param element - target element
* @param text - desired text
* @return true if the text has been successfully set
*/
public static boolean setText(final Object element, @Nullable final String text) {
// Per framework convention, setText(null) means clearing it
String textToSend = toNonNullString(text);
AccessibilityNodeInfo nodeInfo = AccessibilityNodeInfoGetter.fromUiObject(element);
if (nodeInfo == null) {
throw new ElementNotFoundException();
}
/*
* Execute ACTION_SET_PROGRESS action (introduced in API level 24)
* if element has range info and text can be converted to float.
* Falling back to element.setText() if something goes wrong.
*/
if (nodeInfo.getRangeInfo() != null && Build.VERSION.SDK_INT >= 24) {
Logger.debug("Element has range info.");
try {
if (AccessibilityNodeInfoHelpers.setProgressValue(nodeInfo,
Float.parseFloat(Objects.requireNonNull(text)))) {
return true;
}
} catch (NumberFormatException e) {
Logger.debug(String.format("Can not convert \"%s\" to float.", text));
}
Logger.debug("Unable to perform ACTION_SET_PROGRESS action. " +
"Falling back to element.setText()");
}
/*
* Below Android 7.0 (API level 24) calling setText() throws
* `IndexOutOfBoundsException: setSpan (x ... x) ends beyond length y`
* if text length is greater than getMaxTextLength()
*/
if (Build.VERSION.SDK_INT < 24) {
textToSend = AccessibilityNodeInfoHelpers.truncateTextToMaxLength(nodeInfo, textToSend);
}
Logger.debug("Sending text to element: " + textToSend);
Bundle args = new Bundle();
args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, textToSend);
return nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args);
}