Java tutorial
/* * Copyright (C) Justson(https://github.com/Justson/DingDingHelper) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ucmap.dingdinghelper.services; import android.accessibilityservice.AccessibilityService; import android.annotation.TargetApi; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Parcelable; import android.os.PowerManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Toast; import com.ucmap.dingdinghelper.R; import com.ucmap.dingdinghelper.app.App; import com.ucmap.dingdinghelper.common.OrderThread; import com.ucmap.dingdinghelper.entity.AccountEntity; import com.ucmap.dingdinghelper.entity.MessageEvent; import com.ucmap.dingdinghelper.sphelper.SPUtils; import com.ucmap.dingdinghelper.ui.MainActivity; import com.ucmap.dingdinghelper.utils.Constants; import com.ucmap.dingdinghelper.utils.DateUtils; import com.ucmap.dingdinghelper.utils.DingHelperUtils; import com.ucmap.dingdinghelper.utils.JsonUtils; import com.ucmap.dingdinghelper.utils.ShellUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; import java.util.List; import static com.ucmap.dingdinghelper.utils.DateUtils.getHourAndMin; /** * author Just * <p> * 1.AccessibilityService oom_adj 1s1 ??adj0 * ?? ? ???service * <p> * 2.?root?root ?? * <p> * 3.?? ?10s * ??? ????????(ID???) * 4.AlarmManager ? ?1s 6AlarmManager ???note8? * ? AlarmManager Android5.0TimgService TimingService? * ??. */ public class DingDingHelperAccessibilityService extends AccessibilityService { /**/ private static final String SURE_EXCEPTION_ID = "android:id/button1"; /*ID*/ private static final String CONFIRM_QUIT_ID = "android:id/button1"; /*???*/ private static final String PHONE_ID = "com.alibaba.android.rimet:id/et_phone_input"; /*?*/ private static final String PASSWORD_ID = "com.alibaba.android.rimet:id/et_pwd_login"; /**/ private static final String BUTTON_ID = "com.alibaba.android.rimet:id/btn_next"; /*Bottom ?*/ private static final String HOME_BOTTOM_ID = "com.alibaba.android.rimet:id/bottom_tab"; /*?*/ private static final String HOME_BOTTOM_WORK_ID = "com.alibaba.android.rimet:id/home_bottom_tab_button_work"; /*??*/ private static final String TAB_COMPANY_INDEX_ID = "com.alibaba.android.rimet:id/menu_current_company"; /*?RecyclerView id*/ private static final String RECYCLERVIEW_WORK_ID = "com.alibaba.android.rimet:id/oa_fragment_gridview"; /*webView*/ private static final String CHECK_IN_PAGER_TAGET = "com.alibaba.lightapp.runtime.activity.CommonWebViewActivity"; /*?*/ private static final String SETTINGWINDOW = "com.alibaba.android.user.settings.activity.NewSettingActivity"; /**/ private volatile boolean runing_monitor = true; /*?*/ public static final String LOGINWINDOW = "com.alibaba.android.user.login.SignUpWithPwdActivity"; /*?*/ private static final String HOMEWINDOW = "com.alibaba.android.rimet.biz.home.activity.HomeActivity"; /*??*/ private static String CURRENT_WINDOW = ""; /*???*/ private static boolean isCheckIn = false; /**/ // private MonitorThread mMonitorThread; /**/ private static int STATE = 0; /*?????*/ private static final int STATE_CHECKED_IN = 1; /*????*/ private static final int STATE_UNCHECKED_IN = 0; /*???? ?*/ private static final int STATE_RELEASE = -1; /** * ID */ private static final int NOTIFICATION_ID = 0x000088; /*??*/ private static final String DING_DING_PAGKET_NAME = "com.alibaba.android.rimet"; private static final String WEBVIEW_PARENT = "com.alibaba.android.rimet:id/common_webview"; private static final String AFTER_WORK = "??"; private static final String GO_TO_WORK = "??"; private static final String ALERT_DIALOG_WINDOW = "android.app.AlertDialog"; /** * ID */ private static final String HOME_MINE_ID = "com.alibaba.android.rimet:id/home_bottom_tab_button_mine"; /*ID*/ private static final String MINE_SETTING_ID = "com.alibaba.android.rimet:id/rl_setting"; /*ID*/ private static final String SETTING_SIGN_OUT_ID = "com.alibaba.android.rimet:id/setting_sign_out"; /*?Fragment ?*/ private static String CURRENT_PAGER = "message"; private static final String MESSAGE_PAGER = "message"; private static final String DING_PAGER = "ding"; private static final String TCN_PAGER = "tcn"; private static final String CONTACT_PAGER = "contact"; private static final String MINE_PAGER = "mine"; private static final String HEADER_MINE_ID = "com.alibaba.android.rimet:id/header_mine"; private static final String HEADER_CONTACT_ID = "com.alibaba.android.rimet:id/header_contact"; private static final String HEADER_DING = "com.alibaba.android.rimet:id/header_ding"; private static final String HEADER_MESSAGE = "com.alibaba.android.rimet:id/header_message"; /*??*/ private static final String CHECK_IN_PAGER_BACK = "com.alibaba.android.rimet:id/back_layout"; /** * ??????? */ private static final int TIME_LIMIT = 12; private List<AccountEntity> mAccountEntities; /*service???*/ public static volatile boolean IS_ENABLE_DINGDINGHELPERACCESSIBILITYSERVICE = false; @Override public void onCreate() { super.onCreate(); EventBus.getDefault().register(this); IS_ENABLE_DINGDINGHELPERACCESSIBILITYSERVICE = true; } /** * TimingBroadcastReceiver ? ? * * @param messageEvent */ @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent messageEvent) { if (messageEvent.getFlag_bit() == Constants.RESET_PASSWORD) { init(); return; } if (messageEvent != null && messageEvent.getFlag_bit() == 1) { isChecking = false; } doCheckIn(); } /** * ?? */ @Override protected void onServiceConnected() { Toast.makeText(this.getApplicationContext(), "???", Toast.LENGTH_SHORT).show(); super.onServiceConnected(); init(); increasePriority(); } /*???service */ private void increasePriority() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { Notification.Builder mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.mipmap.ic_launcher); startForeground(NOTIFICATION_ID, mBuilder.build()); InnerService.startInnerService(this); } else { startForeground(NOTIFICATION_ID, new Notification()); } } /** * ? */ private int hour = 8; private int min = 30; /** * ?? */ private AccountEntity targetCheckInAcount = new AccountEntity(); /** * */ private int index = 0; private void init() { String jsonAccountList = (String) SPUtils.getString(Constants.ACCOUNT_LIST, "-1"); if (TextUtils.isEmpty(jsonAccountList) || "-1".equals(jsonAccountList)) { Toast.makeText(App.mContext, "???", Toast.LENGTH_SHORT).show(); return; } mAccountEntities = JsonUtils.listJson(jsonAccountList, AccountEntity.class); if (mAccountEntities == null || mAccountEntities.isEmpty()) { Toast.makeText(App.mContext, "???", Toast.LENGTH_SHORT).show(); return; } doScript(); } private void doScript() { if (mAccountEntities == null) return; if (index >= mAccountEntities.size()) return; targetCheckInAcount = mAccountEntities.get(index++); STATE = STATE_UNCHECKED_IN; String current = getHourAndMin(System.currentTimeMillis()); int hour = Integer.parseInt(current.split(":")[0]); String time = ""; if (hour < TIME_LIMIT) { time = (String) SPUtils.getString(Constants.MORNING_CHECK_IN_TIME, "8:45"); } else { time = (String) SPUtils.getString(Constants.AFTERNOON_CHECK_IN_TIME, "20:45"); } if (time.length() >= 4) { String[] hourAndMin = time.split(":"); this.hour = Integer.parseInt(hourAndMin[0]); this.min = Integer.parseInt(hourAndMin[1]); } } private long tag_callback_time = 0; /** * ??? */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override public void onAccessibilityEvent(AccessibilityEvent event) { tag_callback_time = System.currentTimeMillis(); int eventType = event.getEventType(); Log.i("Info", " eventType: " + eventType + " getEventTime: " + event.getEventTime() + " getAction" + event.getAction() + "getContentChangeTypes:" + event.getContentChangeTypes() + " getText :" + event.getText().toString() + "getPackageName :" + event.getPackageName() + "getRecordCount : " + event.getRecordCount() + " getClassName:" + event.getClassName() + " :" + event.getClass() + " getParcelableData:" + event.getParcelableData()); switch (eventType) { /*??*/ case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: windowContentChanged(); break; //??? case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: notificationChanged(event); break; //Activity??? case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: windowChanged(event); break; } } private void windowChanged(AccessibilityEvent event) { String className = event.getClassName() + ""; /*??*/ DingDingHelperAccessibilityService.CURRENT_WINDOW = className; if (findById(HOME_BOTTOM_WORK_ID) != null) { DingDingHelperAccessibilityService.CURRENT_WINDOW = HOMEWINDOW; } /*???*/ if (className.equals(LOGINWINDOW) && STATE == STATE_UNCHECKED_IN) { toSignIn(); } else if (HOMEWINDOW.equals(className)) { if (STATE == STATE_UNCHECKED_IN) performWaitCheckIn(); else if (STATE == STATE_UNCHECKED_IN) switchMine(); } else if (CHECK_IN_PAGER_TAGET.equals(className)) { if (STATE != STATE_CHECKED_IN) { openCheckInDialog(); } else { backHomePager(); } } else if (SETTINGWINDOW.equals(className) && STATE != STATE_UNCHECKED_IN) { inputClick(SETTING_SIGN_OUT_ID); } else if (ALERT_DIALOG_WINDOW.equals(className)) { List<AccessibilityNodeInfo> mAccessibilityNodeInfos = new ArrayList<>(); /*?,?*/ recurseFindByTextToList("", this.getRootInActiveWindow(), mAccessibilityNodeInfos); if (mAccessibilityNodeInfos != null && !mAccessibilityNodeInfos.isEmpty()) inputClick(SURE_EXCEPTION_ID); List<AccessibilityNodeInfo> mNodeQuit = new ArrayList<>(); recurseFindByTextToList("", this.getRootInActiveWindow(), mNodeQuit); if (mNodeQuit != null && !mNodeQuit.isEmpty()) doQuit(); } } private static final String DD_PROGRESS_DIALOG = "com.alibaba.android.dingtalkbase.widgets.dialog.DDProgressDialog"; private Handler mHandler = new Handler(Looper.getMainLooper()); /*????,???*/ private void handleHomeInsensitiveCallback(final long time) { mHandler.postDelayed(new Runnable() { @Override public void run() { if (DingDingHelperAccessibilityService.this == null) return; // DingDingHelperAccessibilityService.CURRENT_WINDOW.equals(DingDingHelperAccessibilityService.DD_PROGRESS_DIALOG) if (DingDingHelperAccessibilityService.this.tag_callback_time == time || DingDingHelperAccessibilityService.CURRENT_WINDOW .equals(DingDingHelperAccessibilityService.CHECK_IN_PAGER_TAGET)) ShellUtils.execCmd("input swipe 300 800 300 500", true); } }, 2000); } private void notificationChanged(AccessibilityEvent event) { try { List<CharSequence> mCharSequences = event.getText(); if (mCharSequences == null || mCharSequences.isEmpty()) return; StringBuffer sb = new StringBuffer(); for (CharSequence c : mCharSequences) { sb.append(c.toString()); } if (!sb.toString().contains("?")) return; Parcelable mParcelable = event.getParcelableData(); if (mParcelable != null && mParcelable instanceof Notification) { Notification mNotification = (Notification) mParcelable; PendingIntent mPendingIntent = mNotification.contentIntent; if (mPendingIntent == null) return; /**/ mPendingIntent.send(); } } catch (Exception e) { } } private void windowContentChanged() { switch (CURRENT_WINDOW) { case HOMEWINDOW: setCurrentPagerId(); /*????*/ if (STATE == STATE_UNCHECKED_IN) { /*???*/ boolean isCheckInPager = isCheckInPager(); if (!isCheckInPager) { performWaitCheckIn(); } else { /*????*/ openCheckInPager(); } } else if (STATE == STATE_CHECKED_IN) {//???? if (MINE_PAGER.equals(CURRENT_PAGER)) {//????? inputClick(MINE_SETTING_ID); } else { /*??*/ switchMine(); } } break; case CHECK_IN_PAGER_TAGET: try { if (STATE != STATE_CHECKED_IN) { openCheckInDialog(); } else { finishSignIn(); } } catch (Exception e) { e.printStackTrace(); } break; case SETTINGWINDOW: // doQuit(); break; case DingDingHelperAccessibilityService.LOGINWINDOW: if (STATE == STATE_UNCHECKED_IN) { toSignIn(); } break; } } private void finishSignIn() { AccessibilityNodeInfo mAccessibilityNodeInfo = this.getRootInActiveWindow(); if (mAccessibilityNodeInfo == null) { return; } AccessibilityNodeInfo mNodeInfos = recurseFindByText("?", mAccessibilityNodeInfo);//??? if (mNodeInfos == null) { backHomePager(); handleHomeInsensitiveCallback(tag_callback_time); return; } AccessibilityNodeInfo mInfo = mNodeInfos; Rect mRect = new Rect(); mInfo.getBoundsInScreen(mRect); doShellCmdInputTap(mRect.centerX(), mRect.centerY());//adb? ??root backHomePager(); } /*DingDingHelperAccessibilityService*/ private void closeHelperService() { List<String> mList = new ArrayList<>(); mList.add(Constants.POINT_SERVICES_ORDER); mList.add(Constants.DISENABLE_SERVICE_PUT); //? mList.add("am force-stop " + DING_DING_PAGKET_NAME); /*????*/ if (DingHelperUtils.isScreenLight(App.mContext)) mList.add("input keyevent 26"); // ShellUtils.execCmd(mList, true); new OrderThread(mList).start(); } /**/ private void doQuit() { AccessibilityNodeInfo mAccessibilityNodeInfo = findById(CONFIRM_QUIT_ID); if (mAccessibilityNodeInfo != null && mAccessibilityNodeInfo.isClickable()) { STATE = STATE_RELEASE; mAccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); isChecking = false; if (mAccountEntities == null) return; if (index >= mAccountEntities.size()) { String[] hm = DateUtils.getHourAndMin(System.currentTimeMillis()).split(":"); if (Integer.parseInt(hm[0]) > TIME_LIMIT) { index = 0; targetCheckInAcount = mAccountEntities.get(index++); } closeHelperService(); return; } doScript(); if (STATE == STATE_UNCHECKED_IN) { toSignIn(); } } } /*?ActivityFragment*/ private void setCurrentPagerId() { List<AccessibilityNodeInfo> listMine = null; AccessibilityNodeInfo mAccessibilityNodeInfo = getRootInActiveWindow(); if (mAccessibilityNodeInfo == null) return; listMine = mAccessibilityNodeInfo.findAccessibilityNodeInfosByViewId(HEADER_MINE_ID); if (listMine != null && !listMine.isEmpty()) { CURRENT_PAGER = MINE_PAGER; return; } List<AccessibilityNodeInfo> listConstact = mAccessibilityNodeInfo .findAccessibilityNodeInfosByViewId(HEADER_CONTACT_ID); if (listConstact != null && !listConstact.isEmpty()) { CURRENT_PAGER = CONTACT_PAGER; return; } List<AccessibilityNodeInfo> listCompany = mAccessibilityNodeInfo .findAccessibilityNodeInfosByViewId(TAB_COMPANY_INDEX_ID); if (listCompany != null && !listCompany.isEmpty()) { CURRENT_PAGER = TCN_PAGER; return; } List<AccessibilityNodeInfo> listDing = mAccessibilityNodeInfo .findAccessibilityNodeInfosByViewId(HEADER_DING); if (listDing != null && !listDing.isEmpty()) { CURRENT_PAGER = DING_PAGER; return; } List<AccessibilityNodeInfo> listMessage = mAccessibilityNodeInfo .findAccessibilityNodeInfosByViewId(HEADER_MESSAGE); if (listMessage != null && !listMessage.isEmpty()) { CURRENT_PAGER = MESSAGE_PAGER; return; } } /*? ?*/ private void switchMine() { if (STATE != STATE_CHECKED_IN) return; AccessibilityNodeInfo mAccessibilityNodeInfo = findById(HOME_MINE_ID); if (mAccessibilityNodeInfo == null) return; mAccessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); CURRENT_PAGER = MINE_PAGER; } /** * ? * ? * ?? ? ?12? * ??12 ??12 * ?? */ private void openCheckInDialog() { AccessibilityNodeInfo mAccessibilityNodeInfo = findById(WEBVIEW_PARENT); if (mAccessibilityNodeInfo == null) return; String date = getHourAndMin(System.currentTimeMillis()); String[] arrayDate = date.split(":"); int hour = Integer.parseInt(arrayDate[0]); if (hour > TIME_LIMIT) { List<AccessibilityNodeInfo> mNodeInfos = new ArrayList<>(); recurseFindByTextToList("?", this.getRootInActiveWindow(), mNodeInfos); if (mNodeInfos.size() >= 2) { STATE = STATE_CHECKED_IN; mNodeInfos.clear(); mNodeInfos = null; Toast.makeText(App.mContext, "??", Toast.LENGTH_SHORT).show(); backHomePager(); return; } AccessibilityNodeInfo mInfoAfter = recurseFindByText(AFTER_WORK, this.getRootInActiveWindow()); if (mInfoAfter == null) { return; } recycle(mAccessibilityNodeInfo, AFTER_WORK, true); } else { AccessibilityNodeInfo mInfo = recurseFindByText(AFTER_WORK, this.getRootInActiveWindow()); if (mInfo != null) { // Toast.makeText(App.mContext, "??", Toast.LENGTH_SHORT).show(); STATE = STATE_CHECKED_IN; backHomePager(); return; } AccessibilityNodeInfo mInfoGo = recurseFindByText(GO_TO_WORK, this.getRootInActiveWindow()); if (mInfoGo == null) { return; } recycle(mAccessibilityNodeInfo, GO_TO_WORK, true); } } private void backHomePager() { inputClick(CHECK_IN_PAGER_BACK); handleHomeInsensitiveCallback(tag_callback_time); } /** * AccessibilityNodeInfo,? * ? textAccessibilityNodeInfo * * @param text * @return */ private AccessibilityNodeInfo findByText(String text) { AccessibilityNodeInfo mAccessibilityNodeInfo = this.getRootInActiveWindow(); if (mAccessibilityNodeInfo == null) return null; List<AccessibilityNodeInfo> list = mAccessibilityNodeInfo.findAccessibilityNodeInfosByText(text); if (list == null || list.isEmpty()) return null; return list.get(0); } /*?---*/ private void openCheckInPager() { AccessibilityNodeInfo mAccessibilityNodeInfo = findById(RECYCLERVIEW_WORK_ID); if (mAccessibilityNodeInfo == null) return; recycle(mAccessibilityNodeInfo, "?", false); } /*??*/ private boolean isCheckInPager() { return findById(TAB_COMPANY_INDEX_ID) != null; } private AccessibilityNodeInfo findById(String id) { AccessibilityNodeInfo mAccessibilityNodeInfo = this.getRootInActiveWindow(); if (mAccessibilityNodeInfo == null) return null; List<AccessibilityNodeInfo> mNodeInfos = mAccessibilityNodeInfo.findAccessibilityNodeInfosByViewId(id); if (mNodeInfos == null || mNodeInfos.isEmpty()) return null; return mNodeInfos.get(0); } /*???*/ private void performWaitCheckIn() { AccessibilityNodeInfo mAccessibilityNodeInfo = this.getRootInActiveWindow(); if (mAccessibilityNodeInfo == null) return; List<AccessibilityNodeInfo> mNodeInfos = mAccessibilityNodeInfo .findAccessibilityNodeInfosByViewId(HOME_BOTTOM_WORK_ID); if (mNodeInfos == null || mNodeInfos.isEmpty()) return; /*?Bottom*/ AccessibilityNodeInfo mNodeInfoBottomWork = mNodeInfos.get(0); if (mNodeInfoBottomWork.isClickable()) { mNodeInfoBottomWork.performAction(AccessibilityNodeInfo.ACTION_CLICK); CURRENT_PAGER = TCN_PAGER; } } private KeyguardManager.KeyguardLock kl; private void wakeAndUnlock() { //??? PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); //?PowerManager.WakeLock???|??Tag PowerManager.WakeLock wl = pm .newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright"); //? wl.acquire(1000); //?? KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); kl = km.newKeyguardLock("unLock"); //? kl.disableKeyguard(); } /**/ private void toSignIn() { AccessibilityNodeInfo mAccessibilityNodeInfo = this.getRootInActiveWindow(); if (mAccessibilityNodeInfo == null) return; List<AccessibilityNodeInfo> mEdPhoneNodes = mAccessibilityNodeInfo .findAccessibilityNodeInfosByViewId(PHONE_ID); if (mEdPhoneNodes == null || mEdPhoneNodes.isEmpty()) return; isChecking = true; AccessibilityNodeInfo mEdPhoneNode = mEdPhoneNodes.get(0); CharSequence mCharSequence = mEdPhoneNode.getText(); if (mCharSequence != null && !mCharSequence.toString().equals(targetCheckInAcount.getAccount())) { mEdPhoneNode.performAction(AccessibilityNodeInfo.ACTION_FOCUS);//? Rect mRect = new Rect(); mEdPhoneNode.getBoundsInScreen(mRect); doShellCmdInputTap(mRect.right - 10, mRect.centerY()); setTextToView(mEdPhoneNode, ""); setTextToView(mEdPhoneNode, targetCheckInAcount.getAccount()); } List<AccessibilityNodeInfo> mEdPasswordNodes = mAccessibilityNodeInfo .findAccessibilityNodeInfosByViewId(PASSWORD_ID); if (mEdPasswordNodes == null) return; AccessibilityNodeInfo mEdPasswordNode = mEdPasswordNodes.get(0); CharSequence mCharSequencePassword = mEdPasswordNode.getText(); setTextToView(mEdPasswordNode, ""); setTextToView(mEdPasswordNode, targetCheckInAcount.getPassword()); /*?*/ inputClick(BUTTON_ID); } /** * */ private void setTextToView(AccessibilityNodeInfo node, String text) { Bundle arguments = new Bundle(); arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD); arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true); node.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments); /*?*/ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Bundle args = new Bundle(); args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text); node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args); } else { ClipData data = ClipData.newPlainText("reply", text); ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setPrimaryClip(data); node.performAction(AccessibilityNodeInfo.ACTION_FOCUS); // ? node.performAction(AccessibilityNodeInfo.ACTION_PASTE); // } } /** * ID? * * @param clickId */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void inputClick(String clickId) { AccessibilityNodeInfo nodeInfo = getRootInActiveWindow(); if (nodeInfo != null) { List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByViewId(clickId); for (AccessibilityNodeInfo item : list) { item.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } } /*??*/ private volatile boolean isCut = false; private ShellUtils.CommandResult doShellCmdInputTap(int x, int y) { List<String> mCmds = new ArrayList<>(); mCmds.add("input tap " + x + " " + y); ShellUtils.CommandResult mCommandResult = ShellUtils.execCmd(mCmds, true); return mCommandResult; } private void handleIt(AccessibilityNodeInfo info) { if (!isCut) { isCut = true; // Toast.makeText(App.mContext, "??", Toast.LENGTH_SHORT).show(); } Rect mRect = new Rect(); info.getBoundsInScreen(mRect); ShellUtils.CommandResult mCommandResult = doShellCmdInputTap(mRect.centerX(), mRect.centerY()); if (mCommandResult.result == 0) { STATE = STATE_CHECKED_IN; } } private volatile boolean isGo = true; private void handleGoToWork(AccessibilityNodeInfo info) { if (isGo) { isGo = false; // Toast.makeText(App.mContext, "???? ... ", Toast.LENGTH_SHORT).show(); Rect mRect = new Rect(); info.getBoundsInScreen(mRect); ShellUtils.CommandResult mCommandResult = doShellCmdInputTap(mRect.centerX(), mRect.centerY()); if (mCommandResult.result == 0) { STATE = STATE_CHECKED_IN; } } } /** * AccessibilityNodeInfo ?webView * List * ? ???target?? * * @param target * @param accessibilityNodeInfo * @return */ private void recurseFindByTextToList(String target, AccessibilityNodeInfo accessibilityNodeInfo, @NonNull List<AccessibilityNodeInfo> mInfos) { if (accessibilityNodeInfo != null && accessibilityNodeInfo.getChildCount() == 0) { if (((accessibilityNodeInfo.getText() != null && accessibilityNodeInfo.getText().toString().contains(target)) || (accessibilityNodeInfo.getContentDescription() != null && accessibilityNodeInfo.getContentDescription().toString().contains(target)))) { mInfos.add(accessibilityNodeInfo); return; } else return; } else { if (accessibilityNodeInfo == null) return; for (int i = 0; i < accessibilityNodeInfo.getChildCount(); i++) { AccessibilityNodeInfo child = accessibilityNodeInfo.getChild(i); recurseFindByTextToList(target, child, mInfos); } return; } } /** * AccessibilityNodeInfo ?webView * * * @param target * @param accessibilityNodeInfo * @return */ private AccessibilityNodeInfo recurseFindByText(String target, AccessibilityNodeInfo accessibilityNodeInfo) { if (accessibilityNodeInfo != null && accessibilityNodeInfo.getChildCount() == 0) { if ((target.equals(accessibilityNodeInfo.getText()) || target.equals(accessibilityNodeInfo.getContentDescription()))) return accessibilityNodeInfo; else return null; } else { if (accessibilityNodeInfo == null) return null; for (int i = 0; i < accessibilityNodeInfo.getChildCount(); i++) { AccessibilityNodeInfo child = accessibilityNodeInfo.getChild(i); AccessibilityNodeInfo isTaget = recurseFindByText(target, child); if (isTaget == null) continue; else return isTaget; } return null; } } /** * */ public void recycle(AccessibilityNodeInfo info, String target, boolean isClickSelft) { int temp = 0; if (info != null && info.getChildCount() == 0) { if (info.getContentDescription() != null && info.getContentDescription().toString().equals(target) && isClickSelft) { String content = info.getContentDescription().toString(); info.performAction(AccessibilityNodeInfo.ACTION_CLICK); if (content.equals(AFTER_WORK)) handleIt(info); else if (content.equals(GO_TO_WORK)) handleGoToWork(info); return; } if (info.getText() != null) { if (target.equals(info.getText().toString())) { if (isClickSelft) { info.performAction(AccessibilityNodeInfo.ACTION_CLICK); return; } AccessibilityNodeInfo parent = info.getParent(); while (parent != null) { if (parent.isClickable()) { parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); break; } parent = parent.getParent(); } } } } else { for (int i = 0; info != null && i < info.getChildCount(); i++) { if (info.getChild(i) != null) { temp = i; recycle(info.getChild(i), target, isClickSelft); } } } } /** * ? */ @Override public void onInterrupt() { runing_monitor = false; isChecking = false; } /** * App * * @param context * @param packageName ?? */ public static void launchApp(Context context, String packageName) { if ((packageName == null || packageName.trim().length() == 0)) return; context.startActivity(getLaunchAppIntent(context, packageName)); } /** * ?App? * * @param context * @param packageName ?? * @return intent */ public static Intent getLaunchAppIntent(Context context, String packageName) { return context.getPackageManager().getLaunchIntentForPackage(packageName); } private boolean isChecking = false; private void doCheckIn() { if (isChecking) { return; } if (mAccountEntities == null || mAccountEntities.isEmpty() || targetCheckInAcount == null) { Toast.makeText(App.mContext, "", Toast.LENGTH_SHORT).show(); return; } /*??*/ isChecking = true; STATE = STATE_UNCHECKED_IN; // runing_monitor = false; // launchApp(this, DING_DING_PAGKET_NAME); List<String> mStringList = new ArrayList<>(); /*?*/ if (!DingHelperUtils.isScreenLight(App.mContext)) { mStringList.add("input keyevent 26"); // wakeAndUnlock(); } if (DingHelperUtils.isScreenLocked(App.mContext)) { /*?*/ mStringList.add("input swipe 200 800 200 100"); } /*?*/ mStringList.add("am start -n " + DING_DING_PAGKET_NAME + "/" + LOGINWINDOW); new OrderThread(mStringList).start(); } @Override public void onDestroy() { IS_ENABLE_DINGDINGHELPERACCESSIBILITYSERVICE = false; stopForeground(true); EventBus.getDefault().unregister(this); isChecking = false; if (mHandler != null) mHandler.removeCallbacksAndMessages(null); super.onDestroy(); } private static final int NOTIFICATION_ID_PROGRESS_ID = 0x120; private void sendNotification(int hour, int min) { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); mBuilder.setSmallIcon(R.mipmap.ic_launcher); int lHour = 0; if (hour <= this.hour) { lHour = this.hour - hour; } else { lHour = 24 - hour + this.hour; } int lMin = 0; if (min <= this.min) { lMin = this.min - min; } else { if (this.hour != hour) lHour--; if (hour == this.hour) { lMin = this.min - min; } else lMin = 60 - min + this.min; } Log.i("Info", " ?:" + this.hour + ":" + this.min + " ?: " + hour + ":" + min + " " + "??: " + lHour + " ?" + lMin + " "); mBuilder.setContentText("??: " + lHour + " ?" + lMin + " ") .setContentTitle("?"); PendingIntent mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(mPendingIntent); NotificationManager mNotificationManager = (NotificationManager) this .getSystemService(NOTIFICATION_SERVICE); mNotificationManager.notify(NOTIFICATION_ID_PROGRESS_ID, mBuilder.build()); } /*???,AccessibilityService ?*/ public static class InnerService extends Service { private static final void startInnerService(Context context) { context.startService(new Intent(context, InnerService.class)); } @Override public void onCreate() { super.onCreate(); Notification.Builder mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.mipmap.ic_launcher); startForeground(NOTIFICATION_ID, mBuilder.build()); new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { stopForeground(true); NotificationManager mNotificationManager = (NotificationManager) InnerService.this .getSystemService(NOTIFICATION_SERVICE); mNotificationManager.cancel(NOTIFICATION_ID); stopSelf(); } }, 50); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); stopForeground(true); } } }