下集预告:
android 借助AccessibilityService实现模拟点击功能-onAccessibilityEvent接收事件的详细处理(三)
此篇附上我常用的工具类
日志工具。(打印出当前类名行号,快速定位代码)
public class L {
private static String className;//类名
private static String methodName;//方法名
private static int lineNumber;//行数
private static boolean isDebug = false;//是否是debug模式
private L() {
}
public static void setDebug(boolean b) {
isDebug = b;
}
private static boolean isDebuggable() {
// return BuildConfig.DEBUG;
return isDebug;
}
private static String createLog(String log) {
StringBuffer buffer = new StringBuffer();
buffer.append(methodName);
buffer.append("(").append(className).append(":").append(lineNumber).append(")");
buffer.append(log);
return buffer.toString();
}
private static void getMethodNames(StackTraceElement[] sElements) {
className = sElements[1].getFileName();
methodName = sElements[1].getMethodName();
lineNumber = sElements[1].getLineNumber();
}
public static void e(String message) {
if (!isDebuggable())
return;
getMethodNames(new Throwable().getStackTrace());
Log.e(className, createLog(message));
}
public static void i(String message) {
if (!isDebuggable())
return;
getMethodNames(new Throwable().getStackTrace());
Log.i(className, createLog(message));
}
public static void d(String message) {
if (!isDebuggable())
return;
getMethodNames(new Throwable().getStackTrace());
Log.d(className, createLog(message));
}
public static void v(String message) {
if (!isDebuggable())
return;
getMethodNames(new Throwable().getStackTrace());
Log.v(className, createLog(message));
}
public static void w(String message) {
if (!isDebuggable())
return;
getMethodNames(new Throwable().getStackTrace());
Log.w(className, createLog(message));
}
public static void wtf(String message) {
if (!isDebuggable())
return;
getMethodNames(new Throwable().getStackTrace());
Log.wtf(className, createLog(message));
}
}
辅助服务工具类。(获取节点对象,滑动,点击,)
public class AccessibilityHelper {
private static final String TAG = AccessibilityHelper.class.getSimpleName();
public static AccessibilityService mService;
/**
* 判断辅助服务是否正在运行
*/
public static boolean isServiceRunning(AccessibilityService service) {
if (service == null) {
return false;
}
AccessibilityManager accessibilityManager = (AccessibilityManager) service.getSystemService(Context.ACCESSIBILITY_SERVICE);
AccessibilityServiceInfo info = service.getServiceInfo();
if (info == null) {
return false;
}
List list = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
Iterator iterator = list.iterator();
boolean isConnect = false;
while (iterator.hasNext()) {
AccessibilityServiceInfo i = iterator.next();
if (i.getId().equals(info.getId())) {
isConnect = true;
break;
}
}
if (!isConnect) {
return false;
}
return true;
}
/**
* 打开辅助服务的设置
*/
public static void openAccessibilityServiceSettings(Activity context) {
try {
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 自动点击按钮
*
* @param event
* @param nodeText 按钮文本
*/
public static void handleEvent(AccessibilityEvent event, String nodeText) {
List unintall_nodes = event.getSource().findAccessibilityNodeInfosByText(nodeText);
if (unintall_nodes != null && !unintall_nodes.isEmpty()) {
AccessibilityNodeInfo node;
for (int i = 0; i < unintall_nodes.size(); i++) {
node = unintall_nodes.get(i);
if (node.getClassName().equals("android.widget.Button") && node.isEnabled()) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
/**
* 获取text
*/
public static String getNodeText(String id) {
List unintall_nodes = mService.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(id);
if (unintall_nodes != null && !unintall_nodes.isEmpty()) {
return unintall_nodes.get(0).getText().toString().trim();
}
return null;
}
/**
* 获取text
*/
public static String getNodeText(AccessibilityNodeInfo nodeInfo, String id) {
List unintall_nodes = nodeInfo.findAccessibilityNodeInfosByViewId(id);
if (unintall_nodes != null && !unintall_nodes.isEmpty()) {
return unintall_nodes.get(0).getText().toString().trim();
}
return null;
}
private AccessibilityHelper() {
}
//通过id查找
public static AccessibilityNodeInfo findNodeInfosById(AccessibilityNodeInfo nodeInfo, String resId) {
if (nodeInfo == null) return null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
List list = nodeInfo.findAccessibilityNodeInfosByViewId(resId);
if (list != null && !list.isEmpty()) {
return list.get(0);
}
}
return null;
}
//通过id查找
public static AccessibilityNodeInfo findNodeInfosById(String resId) {
if (mService.getRootInActiveWindow() != null) {
List list = mService.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(resId);
if (list != null && !list.isEmpty()) {
return list.get(0);
}
}
return null;
}
//通过id查找
public static List findNodeListInfosById(String resId) {
List result = new ArrayList<>();
if (mService.getRootInActiveWindow() != null) {
List list = mService.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(resId);
if (list != null) {
result.addAll(list);
}
}
return result;
}
//通过id查找 ,第i个组件
public static AccessibilityNodeInfo findNodeInfosById(String resId, int index) {
List list = mService.getRootInActiveWindow().findAccessibilityNodeInfosByViewId(resId);
if (list != null && list.size() > index) {
return list.get(index);
}
return null;
}
//返回指定位置的node
public static AccessibilityNodeInfo findNodeInfosByIdAndPosition(AccessibilityNodeInfo nodeInfo, String resId, int position) {
if (nodeInfo == null) return null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
List list = nodeInfo.findAccessibilityNodeInfosByViewId(resId);
for (int i = 0; i < list.size(); i++) {
if (i == position) {
return list.get(i);
}
}
}
return null;
}
//通过某个文本查找
public static AccessibilityNodeInfo findNodeInfosByText(AccessibilityNodeInfo nodeInfo, String text) {
if (nodeInfo == null) return null;
List list = nodeInfo.findAccessibilityNodeInfosByText(text);
if (list == null || list.isEmpty()) {
return null;
}
return list.get(0);
}
//通过某个文本查找
public static AccessibilityNodeInfo findNodeInfosByText(String text) {
if (mService.getRootInActiveWindow() != null) {
List list = mService.getRootInActiveWindow().findAccessibilityNodeInfosByText(text);
if (list == null || list.isEmpty()) {
return null;
}
return list.get(0);
}
return null;
}
//通过ClassName查找
public static AccessibilityNodeInfo findNodeInfosByClassName(AccessibilityNodeInfo nodeInfo, String className) {
if (TextUtils.isEmpty(className)) {
return null;
}
for (int i = 0; nodeInfo != null && i < nodeInfo.getChildCount(); i++) {
AccessibilityNodeInfo node = nodeInfo.getChild(i);
if (node != null) {
if (className.equals(node.getClassName())) {
return node;
} else if (node.getChildCount() > 0) {
findNodeInfosByClassName(node, className);
}
}
}
return null;
}
//通过ClassName查找
public static List findNodeInfoListByClassName(AccessibilityNodeInfo nodeInfo, String className) {
if (TextUtils.isEmpty(className)) {
return Collections.EMPTY_LIST;
}
List result = new ArrayList<>();
for (int i = 0; nodeInfo != null && i < nodeInfo.getChildCount(); i++) {
AccessibilityNodeInfo node = nodeInfo.getChild(i);
if (node != null && className.equals(node.getClassName())) {
result.add(node);
}
}
return result;
}
//通过ClassName查找
public static AccessibilityNodeInfo findNodeInfosByClassName(String className) {
return findNodeInfosByClassName(mService.getRootInActiveWindow(), className);
}
/**
* 找父组件
*/
public static AccessibilityNodeInfo findParentNodeInfosByClassName(AccessibilityNodeInfo nodeInfo, String className) {
if (nodeInfo == null) {
return null;
}
if (TextUtils.isEmpty(className)) {
return null;
}
if (className.equals(nodeInfo.getClassName())) {
return nodeInfo;
}
return findParentNodeInfosByClassName(nodeInfo.getParent(), className);
}
private static final Field sSourceNodeField;
static {
Field field = null;
try {
field = AccessibilityNodeInfo.class.getDeclaredField("mSourceNodeId");
field.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
sSourceNodeField = field;
}
public static long getSourceNodeId(AccessibilityNodeInfo nodeInfo) {
if (sSourceNodeField == null) {
return -1;
}
try {
return sSourceNodeField.getLong(nodeInfo);
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
public static String getViewIdResourceName(AccessibilityNodeInfo nodeInfo) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return nodeInfo.getViewIdResourceName();
}
return null;
}
//返回HOME界面
public static void performHome(AccessibilityService service) {
if (service == null) {
return;
}
service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
}
//返回
public static void performBack(AccessibilityService service) {
if (service == null) {
return;
}
service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
}
//返回
public static void performBack() {
//默认使用MainService
if (AccessibilityHelper.mService == null) {
return;
}
AccessibilityHelper.mService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
}
/**
* 点击事件
*/
public static void performClick(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
return;
}
if (nodeInfo.isClickable()) {
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
} else {
performClick(nodeInfo.getParent());
}
}
/**
* 点击事件
*/
public static void performClick(String id) {
performClick(findNodeInfosById(id));
}
//长按事件
public static void performLongClick(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
return;
}
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
}
//move 事件
public static void performMoveDown(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
return;
}
nodeInfo.performAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN.getId());
}
//ACTION_SCROLL_FORWARD 事件
public static boolean perform_scroll_forward(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
return false;
}
return nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
}
//ACTION_SCROLL_BACKWARD 后退事件
public static boolean perform_scroll_backward(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
return false;
}
return nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
}
//粘贴
@TargetApi(18)
public static void performPaste(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo == null) {
return;
}
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PASTE);
}
//设置editview text
@TargetApi(21)
public static void performSetText(AccessibilityNodeInfo nodeInfo, String text) {
if (nodeInfo == null) {
return;
}
CharSequence className = nodeInfo.getClassName();
if ("android.widget.EditText".equals(className)) {//||"android.widget.TextView".equals(className)
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo
.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
}
}
}
依赖:
compile 'org.jdeferred:jdeferred-android-aar:1.2.4'
public class UiKit {
private static final AndroidDeferredManager gDM = new AndroidDeferredManager();
private static final Handler gUiHandler = new Handler(Looper.getMainLooper());
public static AndroidDeferredManager defer() {
return gDM;
}
public static int dpToPx(Context context, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
context.getResources().getDisplayMetrics());
}
public static void post(Runnable r) {
gUiHandler.post(r);
}
public static void postDelayed(long delay, Runnable r) {
gUiHandler.postDelayed(r, delay);
}
public static void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void sleep() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class WeChatHelper {
private WeChatHelper() {
}
private static final WeChatHelper instance = new WeChatHelper();
public static WeChatHelper init() {
return instance;
}
/**打开微信主界面*/
public static void openWechat(Context context) {
try {
Intent intent = new Intent();
ComponentName cmp = new ComponentName(WechatUI.WECHAT_PACKAGE_NAME, WechatUI.UI_LUANCHER);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(cmp);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取微信的版本
*/
public static int getWechatVersion(Context context) {
PackageInfo mWechatPackageInfo = getPackageInfo(context);
if (mWechatPackageInfo == null) {
return 0;
}
return mWechatPackageInfo.versionCode;
}
/**
* 获取微信的版本名称
*/
public static String getWechatVersionName(Context context) {
PackageInfo mWechatPackageInfo = getPackageInfo(context);
if (mWechatPackageInfo == null) {
return "";
}
return mWechatPackageInfo.versionName;
}
/**微信7.0.0以上*/
public static boolean above700() {
return getWechatVersion(LibInstance.getInstance().getTaskListener().provideContext()) >= 1380;
}
/**微信6.7.3以上*/
public static boolean above673() {
return getWechatVersion(LibInstance.getInstance().getTaskListener().provideContext()) >= 1360;
}
/**
* 更新微信包信息
*/
private static PackageInfo getPackageInfo(Context context) {
PackageInfo mWechatPackageInfo = null;
try {
mWechatPackageInfo = context.getPackageManager().getPackageInfo(WechatUI.WECHAT_PACKAGE_NAME, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return mWechatPackageInfo;
}
}