| | |
| | | import android.os.Handler; |
| | | import android.os.Message; |
| | | import android.text.TextUtils; |
| | | import android.util.Log; |
| | | import android.util.Pair; |
| | | import android.view.accessibility.AccessibilityEvent; |
| | | import android.view.accessibility.AccessibilityNodeInfo; |
| | |
| | | import com.apkfuns.logutils.LogUtils; |
| | | import com.taoke.autopay.android.App; |
| | | import com.taoke.autopay.android.Constant; |
| | | import com.taoke.autopay.android.RxBus; |
| | | import com.taoke.autopay.android.data.local.LocalStore; |
| | | import com.taoke.autopay.android.data.local.entity.TaskQueueInfo; |
| | | import com.taoke.autopay.android.data.network.RestAPI; |
| | |
| | | import com.taoke.autopay.android.utils.accessibility.TextContainsNodeFilter; |
| | | import com.taoke.autopay.android.utils.accessibility.TextNodeFilter; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.regex.Matcher; |
| | |
| | | |
| | | private final Subject<Pair<AccessibilityService, AccessibilityEvent>> subject = PublishSubject.create(); |
| | | |
| | | private Disposable mDisposableTimeout; |
| | | private Disposable mDisposable; |
| | | private Disposable mDisposableClipboardTimeout; |
| | | |
| | | private List<Disposable> mDisposableList; |
| | | |
| | | public ZfbJob(Order order) { |
| | | mDisposableList = new ArrayList<>(); |
| | | this.order = order; |
| | | this.payTimes = LocalStore.getInstance().getPayTimes(); |
| | | this.payedTimes = LocalStore.getInstance().getPayedTimes(); |
| | |
| | | } |
| | | |
| | | extraState = 0; |
| | | mDisposableTimeout = Single |
| | | mDisposableList.add(Single |
| | | .just(true) |
| | | .delay(40, TimeUnit.SECONDS) |
| | | .subscribe(aBoolean -> notifyCancel()); // 一分钟超时,自动取消。 |
| | | mDisposableClipboardTimeout = Single |
| | | .subscribe(aBoolean -> notifyCancel())); // 一分钟超时,自动取消。 |
| | | mDisposableList.add(Single |
| | | .just(true) |
| | | .delay(15, TimeUnit.SECONDS) |
| | | .subscribe(aBoolean -> { |
| | |
| | | LogUtils.tag(TAG).w("支付宝粘贴板弹出超时"); |
| | | notifyCancel(); |
| | | } |
| | | });// 任务启动到支付宝粘贴板推荐弹出超时时间 |
| | | mDisposable = subject |
| | | }));// 任务启动到支付宝粘贴板推荐弹出超时时间 |
| | | Disposable mDisposable = subject |
| | | .debounce(2, TimeUnit.SECONDS) |
| | | .observeOn(AndroidSchedulers.mainThread()) |
| | | .subscribe(pair -> { |
| | |
| | | btnPay.performAction(AccessibilityNodeInfoCompat.ACTION_CLICK); |
| | | } |
| | | } else { |
| | | Disposable mDisposable = RestAPI.getInstance().apiService() |
| | | Disposable mDisposable1 = RestAPI.getInstance().apiService() |
| | | .setOrderNo( |
| | | String.valueOf(LocalStore.getInstance().getUser().id), |
| | | order.id, |
| | |
| | | extraState = 2; |
| | | btnPay.performAction(AccessibilityNodeInfoCompat.ACTION_CLICK); |
| | | // 防止弹出不是好友 |
| | | Single |
| | | mDisposableList.add(Single |
| | | .just(true) |
| | | .delay(5, TimeUnit.SECONDS) |
| | | .subscribe(aBoolean -> { |
| | | if(extraState==2){ |
| | | if (extraState == 2) { |
| | | AccessibilityNodeInfoUtils |
| | | .getSelfOrMatchingAncestor( |
| | | service, |
| | |
| | | AccessibilityNodeInfoUtils.FILTER_CLICKABLE) |
| | | .performAction(AccessibilityNodeInfoCompat.ACTION_CLICK); |
| | | } |
| | | });// 任务启动到支付宝粘贴板推荐弹出超时时间 |
| | | }));// 任务启动到支付宝粘贴板推荐弹出超时时间 |
| | | |
| | | } |
| | | } else { |
| | |
| | | notifyCancel(); |
| | | Toast.makeText(service.getApplicationContext(), throwable.getMessage(), Toast.LENGTH_SHORT).show(); |
| | | }); |
| | | mDisposableList.add(mDisposable1); |
| | | } |
| | | }); |
| | | mDisposableList.add(mDisposable); |
| | | |
| | | // 下面代码避免内存泄漏和设置自动运行结果 |
| | | addJobListener(new JobListener() { |
| | |
| | | // 100表示任务终止 |
| | | extraState = 100; |
| | | sendUIMsg(new TaskQueueInfo(TaskQueueInfo.STATE_JOB_FINISH)); |
| | | mDisposableTimeout.dispose(); |
| | | mDisposableClipboardTimeout.dispose(); |
| | | mDisposable.dispose(); |
| | | for (Disposable d : mDisposableList) { |
| | | try { |
| | | if (d != null) { |
| | | d.dispose(); |
| | | } |
| | | } catch (Exception ignored) { |
| | | } |
| | | } |
| | | |
| | | removeJobListener(this); |
| | | // 调用设置结果接口 |
| | | RestAPI.getInstance().apiService() |
| | |
| | | public void onFinished() { |
| | | extraState = 100; |
| | | sendUIMsg(new TaskQueueInfo(TaskQueueInfo.STATE_JOB_FINISH)); |
| | | mDisposableTimeout.dispose(); |
| | | mDisposableClipboardTimeout.dispose(); |
| | | mDisposable.dispose(); |
| | | for (Disposable d : mDisposableList) { |
| | | try { |
| | | if (d != null) { |
| | | d.dispose(); |
| | | } |
| | | } catch (Exception ignored) { |
| | | } |
| | | } |
| | | removeJobListener(this); |
| | | // 调用设置结果接口 |
| | | RestAPI.getInstance().apiService() |
| | |
| | | @Override |
| | | public void onPayCountLimit() { |
| | | extraState = 100; |
| | | mDisposableTimeout.dispose(); |
| | | mDisposableClipboardTimeout.dispose(); |
| | | mDisposable.dispose(); |
| | | for (Disposable d : mDisposableList) { |
| | | try { |
| | | if (d != null) { |
| | | d.dispose(); |
| | | } |
| | | } catch (Exception ignored) { |
| | | } |
| | | } |
| | | removeJobListener(this); |
| | | // 通知页面弹出更改支付宝 |
| | | sendUIMsg(new TaskQueueInfo(TaskQueueInfo.STATE_PAY_COUNT_LIMIT)); |
| | |
| | | |
| | | /** |
| | | * 获取字母输入键盘(简版) |
| | | * |
| | | * @param service |
| | | * @param rootNodeInfoCompat |
| | | * @return |
| | |
| | | |
| | | /** |
| | | * 获取字母输入键盘 |
| | | * |
| | | * @param service |
| | | * @param rootNodeInfoCompat |
| | | * @return |
| | |
| | | for (int i = 1; i < count; i++) { |
| | | AccessibilityNodeInfoCompat info = keyboardNode.getChild(i); |
| | | if (letters.length() > i) { |
| | | lettersMap.put(String.valueOf(letters.charAt(i-1)), info); |
| | | lettersMap.put(String.valueOf(letters.charAt(i - 1)), info); |
| | | } |
| | | } |
| | | return lettersMap; |
| | |
| | | } else if (extraState == 2 && TextUtils.equals("com.alipay.android.msp.ui.views.MspContainerActivity", className)) {//eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED |
| | | extraState = 3; |
| | | LogUtils.tag(TAG).i("支付页面弹出"); |
| | | } else if (extraState == 3) { |
| | | //判断是否长久没进入下一步 |
| | | mDisposableList.add(Single |
| | | .just(true) |
| | | .delay(4, TimeUnit.SECONDS) |
| | | .subscribe(aBoolean -> { |
| | | if (extraState == 3) { |
| | | LogUtils.tag(TAG).i("长时间没检测到键盘"); |
| | | // 支付被手机安全保护,无法获取到节点,需要回到支付宝界面才能重新开启节点 |
| | | sendUIMsg(new TaskQueueInfo(TaskQueueInfo.STATE_PAY_SAFE_LIMIT)); |
| | | } |
| | | })); |
| | | } else if (extraState == 3 || extraState == 31) { |
| | | extraState = 31; |
| | | AccessibilityNodeInfoCompat btnConfirm = AccessibilityNodeInfoUtils |
| | | .getSelfOrMatchingAncestor( |
| | | service, |
| | |
| | | try { |
| | | for (int i = 0; i < businessPayPwd.length(); i++) { |
| | | String k = businessPayPwd.charAt(i) + ""; |
| | | if(letterMap.get(k)==null){ |
| | | if (letterMap.get(k) == null) { |
| | | throw new Exception("密码对应的键盘字母没找到"); |
| | | } |
| | | } |
| | |
| | | } catch (Exception e) { |
| | | LogUtils.tag(TAG).e("企业支付宝密码输入出错:" + e.getMessage()); |
| | | // 重新查找支付宝键盘 |
| | | Map<String, AccessibilityNodeInfoCompat> allLettersMap = getLetterKeyboard(service, rootNodeInfoCompat); |
| | | if(allLettersMap!=null&&allLettersMap.size() >= 26){ |
| | | LogUtils.tag(TAG).i("找到键盘26个字母组合:"+allLettersMap.size()); |
| | | Map<String, AccessibilityNodeInfoCompat> allLettersMap = getLetterKeyboard(service, rootNodeInfoCompat); |
| | | if (allLettersMap != null && allLettersMap.size() >= 26) { |
| | | LogUtils.tag(TAG).i("找到键盘26个字母组合:" + allLettersMap.size()); |
| | | try { |
| | | // 超过26个字母 |
| | | for (int i = 0; i < businessPayPwd.length(); i++) { |
| | | letterMap.get(businessPayPwd.charAt(i) + "").performAction(AccessibilityNodeInfo.ACTION_CLICK); |
| | | } |
| | | LogUtils.tag(TAG).e("企业支付宝全键盘密码输入完成"); |
| | | }catch(Exception ee){ |
| | | } catch (Exception ee) { |
| | | LogUtils.tag(TAG).e("企业支付宝全键盘密码输入出错:" + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | extraState = 4; |
| | | LogUtils.tag(TAG).i("企业支付宝密码输入成功"); |
| | | Single |
| | | mDisposableList.add(Single |
| | | .just(true) |
| | | .delay(5, TimeUnit.SECONDS) |
| | | .subscribe(aBoolean -> { |
| | |
| | | surePayBtn.performAction(AccessibilityNodeInfo.ACTION_CLICK); |
| | | extraState = 5; |
| | | } |
| | | });// 任务启动到支付宝粘贴板推荐弹出超时时间 |
| | | }));// 任务启动到支付宝粘贴板推荐弹出超时时间 |
| | | // 获取确认按钮 |
| | | } |
| | | } else { |