DingDong买菜辅助

/**
 * 叮咚买菜辅助
 */
public class DingdongService extends AccessibilityService {

    private static final String PACKAGE_NAME = "com.yaya.zone";

    private Rect payRect;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        CharSequence packageName = event.getPackageName();
        XLog.i("进入了叮咚买菜:%s", packageName);
        if (!packageName.equals(PACKAGE_NAME)) {
            return;
        }
        AccessibilityNodeInfo source = event.getSource();
        if (source == null) {
            return;
        }
        XLog.i("进入了叮咚买菜");
        clickPay(source);
        clickTime(source);
        continuePay(source);
        payConfirm(source);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void clickTime(AccessibilityNodeInfo source) {
        String viewId = "com.yaya.zone:id/cl_item_select_hour_root";
        List<AccessibilityNodeInfo> timeList = source.findAccessibilityNodeInfosByViewId(viewId);
        if (timeList == null || timeList.size() == 0) {
            onBack(source);
            return;
        }
        boolean ok = false;
        int size = timeList.size();
        for (int i = size - 1; i >= 0; i--) {
            AccessibilityNodeInfo item = timeList.get(i);
            if (item.isClickable()) {
                if (findByText(item, "已约满") == null) {
                    AccessibilityNodeInfo nodeTitle = findById(item, "com.yaya.zone:id/tv_item_select_hour_title");
                    if (nodeTitle != null) {
                        XLog.i("选中了时间,请确认付款...%s", nodeTitle.getText());
                    }
                    item.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    ok = true;
                    break;
                }
            }
        }

        if (!ok) {
            XLog.i("抢菜失败,退出继续点击支付...");
            onBack(source);
        }
    }

    private void payConfirm(AccessibilityNodeInfo source) {
        AccessibilityNodeInfo pay = findByText(source, "确认交易");
        if (pay == null) {
            return;
        }
        pay.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    }

    private void continuePay(AccessibilityNodeInfo source) {
        AccessibilityNodeInfo pay = findByText(source, "继续支付");
        if (pay == null) {
            return;
        }
        pay.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    }

    private void clickPay(AccessibilityNodeInfo source) {

        AccessibilityNodeInfo pay = findByText(source, "立即支付");
        if (pay == null) {
            return;
        }

        pay.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        payRect = new Rect();
        XLog.i("获取支付坐标....%s", payRect);
        pay.getBoundsInScreen(payRect);
    }

    private AccessibilityNodeInfo findByText(AccessibilityNodeInfo source, String text) {
        List<AccessibilityNodeInfo> pay = source.findAccessibilityNodeInfosByText(text);
        if (pay == null || pay.size() == 0) {
            return null;
        }

        for (AccessibilityNodeInfo item : pay) {
            return item;
        }
        return null;
    }

    private AccessibilityNodeInfo findById(AccessibilityNodeInfo source, String id) {
        List<AccessibilityNodeInfo> pay = source.findAccessibilityNodeInfosByViewId(id);
        if (pay == null || pay.size() == 0) {
            return null;
        }

        for (AccessibilityNodeInfo item : pay) {
            return item;
        }
        return null;
    }


    @Override
    public void onInterrupt() {

    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        XLog.i("辅助服务启动成功...");
    }

    public void onBack(AccessibilityNodeInfo source) {
        String viewId = "com.yaya.zone:id/iv_dialog_select_time_close";
        List<AccessibilityNodeInfo> timeList = source.findAccessibilityNodeInfosByViewId(viewId);
        if (timeList == null || timeList.size() == 0) {
            XLog.i("没有找到关闭按钮");
            return;
        }
        XLog.i("找到了关闭按钮:%s", timeList.size());
        for (AccessibilityNodeInfo item : timeList) {
            if (item.isClickable()) {
                item.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                XLog.i("关闭菜单");
                if (payRect != null) {
                    XLog.i("点击支付坐标....%s", payRect);
                    click(new Point(payRect.centerX(), payRect.centerY()));
                    return;
                }
            }
        }
        Point point = new Point(10, 10);
        click(point);
        XLog.i("点击失败...");
    }

    @TargetApi(24)
    public void click(Point point) {
        //只有7.0才可以用
        GestureDescription.Builder builder = new GestureDescription.Builder();
        Path path = new Path();
        path.moveTo((float) point.x, (float) point.y);
        path.lineTo((float) point.x, (float) point.y);
        /**
         * 参数path:笔画路径
         * 参数startTime:时间 (以毫秒为单位),从手势开始到开始笔划的时间,非负数
         * 参数duration:笔划经过路径的持续时间(以毫秒为单位),非负数
         */
        builder.addStroke(new GestureDescription.StrokeDescription(path, 1, 1));
        final GestureDescription build = builder.build();
        /**
         * 参数GestureDescription:翻译过来就是手势的描述,如果要实现模拟,首先要描述你的腰模拟的手势嘛
         * 参数GestureResultCallback:翻译过来就是手势的回调,手势模拟执行以后回调结果
         * 参数handler:大部分情况我们不用的话传空就可以了
         * 一般我们关注GestureDescription这个参数就够了,下边就重点介绍一下这个参数
         */
        dispatchGesture(build, new GestureResultCallback() {
            public void onCancelled(GestureDescription gestureDescription) {
                super.onCancelled(gestureDescription);
            }

            public void onCompleted(GestureDescription gestureDescription) {
                super.onCompleted(gestureDescription);
            }
        }, null);
    }

}

叮咚买菜辅助核心代码

配置文档accessibility_service_config.xml

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged|typeNotificationStateChanged"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:packageNames="com.yaya.zone"
    android:notificationTimeout="10"
    android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
    android:canRetrieveWindowContent="true"/>

AndroidManifest.xml配置服务

<service
    android:name=".maicai.DingdongService"
    android:exported="false"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>

手动授权辅助服务启动

/**
     * 该辅助功能开关是否打开了
     *
     * @param accessibilityServiceName:指定辅助服务名字
     * @param context:上下文
     * @return
     */
    private boolean isAccessibilitySettingsOn(String accessibilityServiceName, Context context) {
        int accessibilityEnable = 0;
        String serviceName = context.getPackageName() + "/" + accessibilityServiceName;
        try {
            accessibilityEnable = Settings.Secure.getInt(context.getContentResolver(),
                    Settings.Secure.ACCESSIBILITY_ENABLED, 0);
        } catch (Exception e) {
            XLog.e("get accessibility enable failed, the err:" + e.getMessage());
        }
        if (accessibilityEnable == 1) {
            TextUtils.SimpleStringSplitter mStringColonSplitter
                    = new TextUtils.SimpleStringSplitter(':');
            String settingValue = Settings.Secure.getString(context.getContentResolver(),
                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
            if (settingValue != null) {
                mStringColonSplitter.setString(settingValue);
                while (mStringColonSplitter.hasNext()) {
                    String accessibilityService = mStringColonSplitter.next();
                    if (accessibilityService.equalsIgnoreCase(serviceName)) {
                        XLog.v("We've found the correct setting - accessibility is switched on!");
                        return true;
                    }
                }
            }
        } else {
            XLog.w("Accessibility service disable");
        }
        return false;
    }

    /**
     * 跳转到系统设置页面开启辅助功能
     *
     * @param accessibilityServiceName:指定辅助服务名字
     * @param context:上下文
     */
    private void openAccessibility(String accessibilityServiceName, Context context) {
        if (!isAccessibilitySettingsOn(accessibilityServiceName, context)) {
            Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
            context.startActivity(intent);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值