0.蚂蚁能量自动收集器
想做一个蚂蚁森林能量自动采集器,发现AccessibilityService无法识别webview内容,反正我是没招了,就看怎么实现,这里提出一个问题。
1.支付宝界面点击进入蚂蚁森林界面
public class AccessibilityServiceMonitor extends AccessibilityService {
private static final String TAG = AccessibilityServiceMonitor.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,
"onCreate");
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
int eventType = event.getEventType();
Log.i(TAG,
"toString - " + event.toString());
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
recycleInfo(getRootInActiveWindow());
String className = event.getClassName().toString();
Log.i(TAG,
"window change text:"+className);
if (
"com.eg.android.AlipayGphone.AlipayLogin".equals(className)) {
openForest();
}
else if (
"com.alipay.mobile.nebulacore.ui.H5Activity".equals(className)) {
getForestEnergy();
}
break;
private void openForest() {
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
recycle(rootNode);
}
public void recycle(AccessibilityNodeInfo info) {
if (info.getChildCount() ==
0) {
if(info.getText() !=
null){
if(
"蚂蚁森林".equals(info.getText().toString())){
Log.i(TAG,
"Click"+
",isClick:"+info.isClickable());
info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
AccessibilityNodeInfo parent = info.getParent();
while(parent !=
null){
Log.i(TAG,
"parent isClick:"+parent.isClickable());
if(parent.isClickable()){
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
break;
}
parent = parent.getParent();
}
}
}
}
else {
for (
int i =
0; i < info.getChildCount(); i++) {
if(info.getChild(i)!=
null){
recycle(info.getChild(i));
}
}
}
}
2.蚂蚁森林界面时webview,发现数据都获取不到
03-28 12
:28:04.305 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: windowId:138
03-28 12:28:04.305 18755-18755/com.fadi.forestautoget D/AccessibilityServiceMonitor: rootNode = android.view.accessibility.AccessibilityNodeInfo@800b2ce5; boundsInParent
: Rect(0, 0 - 96, 96); boundsInScreen
: Rect(616, 48 - 712, 144); packageName
: com.eg.android.AlipayGphone; className
: android.widget.TextView; text: ; error
: null; maxTextLength
: -1; contentDescription
: 更多; viewIdResName
: null; checkable
: false; checked
: false; focusable
: false; focused
: false; selected
: false; clickable
: true; longClickable
: false; contextClickable
: false; enabled
: true; password
: false; scrollable
: false; actions
: [AccessibilityAction: ACTION_SELECT - null, AccessibilityAction: ACTION_CLEAR_SELECTION - null, AccessibilityAction: ACTION_CLICK - null, AccessibilityAction: ACTION_ACCESSIBILITY_FOCUS - null, AccessibilityAction: ACTION_NEXT_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_SET_SELECTION - null, AccessibilityAction: ACTION_SHOW_ON_SCREEN - null]
03-28 12:28:04.305 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: window content text:android.webkit.WebView
03-28 12:28:04.337 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: toString - EventType: TYPE_WINDOW_CONTENT_CHANGED; EventTime
: 3591034; PackageName
: com.eg.android.AlipayGphone; MovementGranularity
: 0; Action
: 0 [ ClassName: android.webkit.WebView; Text: []; ContentDescription
: null; ItemCount
: 0; CurrentItemIndex
: 0; IsEnabled
: true; IsPassword
: false; IsChecked
: false; IsFullScreen
: false; Scrollable
: true; BeforeText
: null; FromIndex
: -1; ToIndex
: -1; ScrollX
: 0; ScrollY
: 17; MaxScrollX
: 0; MaxScrollY
: 1076; AddedCount
: -1; RemovedCount
: -1; ParcelableData
: Bundle[mParcelledData.dataSize=488] ]; recordCount
: 0
03-28 12:28:04.366 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: child widget----------------------------com.uc.webview.export.WebView
03-28 12:28:04.366 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: showDialog:false
03-28 12:28:04.366 18755-18755/com.fadi.forestautoget I/AccessibilityServiceMonitor: Text:null
3. 解决方案(繁星点点)
繁星点点的博客 https://blog.csdn.net/u012861467/article/details/81455619
4.代码优化
4.1 下载
https://github.com/sufadi/AccessibilityServiceMonitor
4.2 监听WebView的FLAG
serviceInfo
.flags = serviceInfo
.flags | AccessibilityServiceInfo
.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
4.3 跳转支付宝登陆界面
/**
* 启动支付宝界面
* adb shell am start com.eg.android.AlipayGphone/com.eg.android.AlipayGphone.AlipayLogin
*/
public static void startAlipay(Context mContext) {
Intent intent =
new Intent();
intent.setPackage(
"com.eg.android.AlipayGphone");
intent.setClassName(
"com.eg.android.AlipayGphone",
"com.eg.android.AlipayGphone.AlipayLogin");
mContext.startActivity(intent);
}
4.4 跳转蚂蚁森林界面
/**
* 自动点击进入蚂蚁森林界面
*/
public static void enterForestUI(AccessibilityNodeInfo nodeInfo) {
Log.d(Config.TAG,
"enterForestUI ");
if (nodeInfo !=
null) {
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText(
"蚂蚁森林");
if (list ==
null) {
Log.d(Config.TAG,
"enterForestUI finding no");
return;
}
else {
Log.d(Config.TAG,
"enterForestUI finding yes");
}
for (AccessibilityNodeInfo item : list) {
/**
* 蚂蚁森林本身不可点击,但是他的父控件可以点击
*/
AccessibilityNodeInfo parent = item.getParent();
if (
null != parent && parent.isClickable()) {
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
Log.d(Config.TAG,
"item = " + item.toString() +
", parent click = " + parent.toString());
break;
}
}
}
}
4.5 采集蚂蚁森林能量
好友的能量不能收取,因为支付宝在onTouch事件中return true,导致不会触发OnClick方法,但是支付宝中的蚂蚁森林可以收取自己的能量
public static void policy(AccessibilityNodeInfo nodeInfo, String packageName, String className) {
/**
* 蚂蚁森林界面
*/
if (packageName.equals(
"com.eg.android.AlipayGphone") &&
(
"com.alipay.mobile.nebulacore.ui.H5Activity".equals(className)
||
"com.uc.webkit.bf".equals(className))) {
if (nodeInfo !=
null) {
for (
int i =
0; i < nodeInfo.getChildCount(); i++) {
AccessibilityNodeInfo child = nodeInfo.getChild(i);
if (
"com.uc.webview.export.WebView".equals(child.getClassName())) {
Log.d(Config.TAG,
"找到蚂蚁森林的 webView count = " + child.getChildCount());
findEveryViewNode(child);
break;
}
}
}
else {
Log.d(Config.TAG,
"alipayPolicy = null");
}
}
}
public static void findEveryViewNode(AccessibilityNodeInfo node) {
if (
null != node && node.getChildCount() >
0) {
for (
int i =
0; i < node.getChildCount(); i++) {
AccessibilityNodeInfo child = node.getChild(i);
if (child ==
null) {
continue;
}
String className = child.getClassName().toString();
if (
"android.widget.Button".equals(className)) {
Log.d(Config.TAG,
"Button 的节点数据 text = " + child.getText() +
", descript = " + child.getContentDescription() +
", className = " + child.getClassName() +
", resId = " + child.getViewIdResourceName());
boolean isClickable = child.isClickable();
boolean isResIdNull = child.getViewIdResourceName() ==
null ?
true:
false;
/**
* 好友的能量不能收取,因为支付宝在onTouch事件中return true,导致不会触发OnClick方法
*
* 但是支付宝中的蚂蚁森林可以收取自己的能量
*/
if ( isClickable && isResIdNull) {
child.performAction(AccessibilityNodeInfo.ACTION_CLICK);
Log.d(Config.TAG,
"能量球 成功点击");
}
}
findEveryViewNode(child);
}
}
}