修复 控件相关操作报错的问题
This commit is contained in:
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
package org.autojs.autojs.autojs.api.timing
|
||||||
|
|
||||||
|
import com.stardust.autojs.execution.ExecutionConfig
|
||||||
|
import org.autojs.autojs.timing.TimedTask
|
||||||
|
import org.autojs.autojs.timing.TimedTaskManager
|
||||||
|
import org.joda.time.LocalDateTime
|
||||||
|
import org.joda.time.LocalTime
|
||||||
|
|
||||||
|
object TimedTasks {
|
||||||
|
|
||||||
|
fun daily(path: String, hour: Int, minute: Int) {
|
||||||
|
TimedTaskManager.getInstance().addTask(TimedTask.dailyTask(LocalTime(hour, minute), path, ExecutionConfig()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disposable(path: String, millis: Long) {
|
||||||
|
TimedTaskManager.getInstance().addTask(TimedTask.disposableTask(LocalDateTime(millis), path, ExecutionConfig()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun weekly(path: String, millis: Long) {
|
||||||
|
//TimedTaskManager.getInstance().addTask(TimedTask.weeklyTask(LocalDateTime(millis), path, ExecutionConfig()))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
package com.stardust.autojs.core.accessibility;
|
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityService;
|
|
||||||
import android.accessibilityservice.GestureDescription;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
|
||||||
|
|
||||||
import com.stardust.autojs.annotation.ScriptInterface;
|
|
||||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
|
||||||
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
|
|
||||||
import com.stardust.automator.GlobalActionAutomator;
|
|
||||||
import com.stardust.automator.UiObject;
|
|
||||||
import com.stardust.automator.simple_action.ActionFactory;
|
|
||||||
import com.stardust.automator.simple_action.ActionTarget;
|
|
||||||
import com.stardust.automator.simple_action.SimpleAction;
|
|
||||||
import com.stardust.util.DeveloperUtils;
|
|
||||||
import com.stardust.util.ScreenMetrics;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Stardust on 2017/4/2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class SimpleActionAutomator {
|
|
||||||
|
|
||||||
private static final String TAG = "SimpleActionAutomator";
|
|
||||||
|
|
||||||
private AccessibilityBridge mAccessibilityBridge;
|
|
||||||
private ScriptRuntime mScriptRuntime;
|
|
||||||
private GlobalActionAutomator mGlobalActionAutomator;
|
|
||||||
private ScreenMetrics mScreenMetrics;
|
|
||||||
|
|
||||||
public SimpleActionAutomator(AccessibilityBridge accessibilityBridge, ScriptRuntime scriptRuntime) {
|
|
||||||
mAccessibilityBridge = accessibilityBridge;
|
|
||||||
mScriptRuntime = scriptRuntime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public ActionTarget text(String text, int i) {
|
|
||||||
return new ActionTarget.TextActionTarget(text, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public ActionTarget bounds(int left, int top, int right, int bottom) {
|
|
||||||
return new ActionTarget.BoundsActionTarget(new Rect(left, top, right, bottom));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@ScriptInterface
|
|
||||||
public ActionTarget editable(int i) {
|
|
||||||
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
|
|
||||||
return new ActionTarget.EditableActionTarget(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public ActionTarget id(String id) {
|
|
||||||
return new ActionTarget.IdActionTarget(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean click(ActionTarget target) {
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_CLICK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean longClick(ActionTarget target) {
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_LONG_CLICK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean scrollUp(ActionTarget target) {
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean scrollDown(ActionTarget target) {
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean scrollBackward(int i) {
|
|
||||||
return performAction(ActionFactory.INSTANCE.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean scrollForward(int i) {
|
|
||||||
return performAction(ActionFactory.INSTANCE.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean scrollMaxBackward() {
|
|
||||||
return performAction(ActionFactory.INSTANCE.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean scrollMaxForward() {
|
|
||||||
return performAction(ActionFactory.INSTANCE.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean focus(ActionTarget target) {
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_FOCUS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean select(ActionTarget target) {
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
public boolean setText(ActionTarget target, String text) {
|
|
||||||
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
public boolean appendText(ActionTarget target, String text) {
|
|
||||||
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
|
|
||||||
return performAction(target.createAction(UiObject.Companion.getACTION_APPEND_TEXT(), text));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean back() {
|
|
||||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean home() {
|
|
||||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
public boolean powerDialog() {
|
|
||||||
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
|
|
||||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean notifications() {
|
|
||||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean quickSettings() {
|
|
||||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean recents() {
|
|
||||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public boolean splitScreen() {
|
|
||||||
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public boolean gesture(long start, long duration, int[]... points) {
|
|
||||||
prepareForGesture();
|
|
||||||
return mGlobalActionAutomator.gesture(start, duration, points);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public void gestureAsync(long start, long duration, int[]... points) {
|
|
||||||
prepareForGesture();
|
|
||||||
mGlobalActionAutomator.gestureAsync(start, duration, points);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public boolean gestures(Object strokes) {
|
|
||||||
prepareForGesture();
|
|
||||||
return mGlobalActionAutomator.gestures((GestureDescription.StrokeDescription[]) strokes);
|
|
||||||
}
|
|
||||||
|
|
||||||
//如果这里用GestureDescription.StrokeDescription[]为参数,安卓7.0以下会因为找不到这个类而报错
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public void gesturesAsync(Object strokes) {
|
|
||||||
prepareForGesture();
|
|
||||||
mGlobalActionAutomator.gesturesAsync((GestureDescription.StrokeDescription[]) strokes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void prepareForGesture() {
|
|
||||||
ScriptRuntime.requiresApi(24);
|
|
||||||
ensureAccessibilityServiceEnabled();
|
|
||||||
if (mGlobalActionAutomator != null)
|
|
||||||
return;
|
|
||||||
mGlobalActionAutomator = new GlobalActionAutomator(new Handler(mScriptRuntime.loopers.getServantLooper()));
|
|
||||||
mGlobalActionAutomator.setScreenMetrics(mScreenMetrics);
|
|
||||||
mGlobalActionAutomator.setService(mAccessibilityBridge.getService());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public boolean click(int x, int y) {
|
|
||||||
prepareForGesture();
|
|
||||||
return mGlobalActionAutomator.click(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public boolean press(int x, int y, int delay) {
|
|
||||||
prepareForGesture();
|
|
||||||
return mGlobalActionAutomator.press(x, y, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public boolean longClick(int x, int y) {
|
|
||||||
prepareForGesture();
|
|
||||||
return mGlobalActionAutomator.longClick(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ScriptInterface
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
||||||
public boolean swipe(int x1, int y1, int x2, int y2, int delay) {
|
|
||||||
prepareForGesture();
|
|
||||||
return mGlobalActionAutomator.swipe(x1, y1, x2, y2, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean performGlobalAction(final int action) {
|
|
||||||
ensureAccessibilityServiceEnabled();
|
|
||||||
AccessibilityService service = mAccessibilityBridge.getService();
|
|
||||||
if (service == null)
|
|
||||||
return false;
|
|
||||||
return service.performGlobalAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
|
||||||
@ScriptInterface
|
|
||||||
public boolean paste(ActionTarget target) {
|
|
||||||
ScriptRuntime.requiresApi(18);
|
|
||||||
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_PASTE));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ensureAccessibilityServiceEnabled() {
|
|
||||||
mAccessibilityBridge.ensureServiceEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private boolean performAction(SimpleAction simpleAction) {
|
|
||||||
ensureAccessibilityServiceEnabled();
|
|
||||||
if (AccessibilityConfig.isUnintendedGuardEnabled() && isRunningPackageSelf()) {
|
|
||||||
Log.d(TAG, "performAction: running package is self. return false");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
List<AccessibilityNodeInfo> roots = mAccessibilityBridge.windowRoots();
|
|
||||||
if (roots.isEmpty())
|
|
||||||
return false;
|
|
||||||
Log.v(TAG, "performAction: " + simpleAction + " windowRoots = " + roots);
|
|
||||||
boolean succeed = true;
|
|
||||||
for (AccessibilityNodeInfo root : roots) {
|
|
||||||
succeed &= simpleAction.perform(UiObject.Companion.createRoot(root));
|
|
||||||
}
|
|
||||||
return succeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isRunningPackageSelf() {
|
|
||||||
return DeveloperUtils.isSelfPackage(mAccessibilityBridge.getInfoProvider().getLatestPackage());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setScreenMetrics(ScreenMetrics metrics) {
|
|
||||||
mScreenMetrics = metrics;
|
|
||||||
if (mGlobalActionAutomator != null)
|
|
||||||
mGlobalActionAutomator.setScreenMetrics(metrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
package com.stardust.autojs.core.accessibility
|
||||||
|
|
||||||
|
import android.accessibilityservice.AccessibilityService
|
||||||
|
import android.accessibilityservice.GestureDescription
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Handler
|
||||||
|
import android.view.accessibility.AccessibilityNodeInfo
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import com.stardust.autojs.annotation.ScriptInterface
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime
|
||||||
|
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig
|
||||||
|
import com.stardust.automator.GlobalActionAutomator
|
||||||
|
import com.stardust.automator.UiObject
|
||||||
|
import com.stardust.automator.simple_action.ActionFactory
|
||||||
|
import com.stardust.automator.simple_action.ActionTarget
|
||||||
|
import com.stardust.automator.simple_action.SimpleAction
|
||||||
|
import com.stardust.util.DeveloperUtils
|
||||||
|
import com.stardust.util.ScreenMetrics
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/4/2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SimpleActionAutomator(private val mAccessibilityBridge: AccessibilityBridge, private val mScriptRuntime: ScriptRuntime) {
|
||||||
|
|
||||||
|
private lateinit var mGlobalActionAutomator: GlobalActionAutomator
|
||||||
|
|
||||||
|
private var mScreenMetrics: ScreenMetrics? = null
|
||||||
|
|
||||||
|
private val isRunningPackageSelf: Boolean
|
||||||
|
get() = DeveloperUtils.isSelfPackage(mAccessibilityBridge.infoProvider.latestPackage)
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun text(text: String, i: Int): ActionTarget {
|
||||||
|
return ActionTarget.TextActionTarget(text, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun bounds(left: Int, top: Int, right: Int, bottom: Int): ActionTarget {
|
||||||
|
return ActionTarget.BoundsActionTarget(Rect(left, top, right, bottom))
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
@ScriptInterface
|
||||||
|
fun editable(i: Int): ActionTarget {
|
||||||
|
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
return ActionTarget.EditableActionTarget(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun id(id: String): ActionTarget {
|
||||||
|
return ActionTarget.IdActionTarget(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun click(target: ActionTarget): Boolean {
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_CLICK))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun longClick(target: ActionTarget): Boolean {
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_LONG_CLICK))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun scrollUp(target: ActionTarget): Boolean {
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun scrollDown(target: ActionTarget): Boolean {
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun scrollBackward(i: Int): Boolean {
|
||||||
|
return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, i))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun scrollForward(i: Int): Boolean {
|
||||||
|
return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, i))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun scrollMaxBackward(): Boolean {
|
||||||
|
return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun scrollMaxForward(): Boolean {
|
||||||
|
return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun focus(target: ActionTarget): Boolean {
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_FOCUS))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun select(target: ActionTarget): Boolean {
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
fun setText(target: ActionTarget, text: String): Boolean {
|
||||||
|
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
fun appendText(target: ActionTarget, text: String): Boolean {
|
||||||
|
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
return performAction(target.createAction(UiObject.ACTION_APPEND_TEXT, text))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun back(): Boolean {
|
||||||
|
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun home(): Boolean {
|
||||||
|
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
fun powerDialog(): Boolean {
|
||||||
|
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun notifications(): Boolean {
|
||||||
|
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun quickSettings(): Boolean {
|
||||||
|
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
fun recents(): Boolean {
|
||||||
|
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun splitScreen(): Boolean {
|
||||||
|
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun gesture(start: Long, duration: Long, vararg points: IntArray): Boolean {
|
||||||
|
prepareForGesture()
|
||||||
|
return mGlobalActionAutomator.gesture(start, duration, *points)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun gestureAsync(start: Long, duration: Long, vararg points: IntArray) {
|
||||||
|
prepareForGesture()
|
||||||
|
mGlobalActionAutomator.gestureAsync(start, duration, *points)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun gestures(strokes: Any): Boolean {
|
||||||
|
prepareForGesture()
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return mGlobalActionAutomator.gestures(*strokes as Array<GestureDescription.StrokeDescription>)
|
||||||
|
}
|
||||||
|
|
||||||
|
//如果这里用GestureDescription.StrokeDescription[]为参数,安卓7.0以下会因为找不到这个类而报错
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun gesturesAsync(strokes: Any) {
|
||||||
|
prepareForGesture()
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
mGlobalActionAutomator.gesturesAsync(*strokes as Array<GestureDescription.StrokeDescription>)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun prepareForGesture() {
|
||||||
|
ScriptRuntime.requiresApi(24)
|
||||||
|
if (!::mGlobalActionAutomator.isInitialized) {
|
||||||
|
mGlobalActionAutomator = GlobalActionAutomator(Handler(mScriptRuntime.loopers.servantLooper)) {
|
||||||
|
ensureAccessibilityServiceEnabled()
|
||||||
|
return@GlobalActionAutomator mAccessibilityBridge.service!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mGlobalActionAutomator.setScreenMetrics(mScreenMetrics)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun click(x: Int, y: Int): Boolean {
|
||||||
|
prepareForGesture()
|
||||||
|
return mGlobalActionAutomator.click(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun press(x: Int, y: Int, delay: Int): Boolean {
|
||||||
|
prepareForGesture()
|
||||||
|
return mGlobalActionAutomator.press(x, y, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun longClick(x: Int, y: Int): Boolean {
|
||||||
|
prepareForGesture()
|
||||||
|
return mGlobalActionAutomator.longClick(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ScriptInterface
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
fun swipe(x1: Int, y1: Int, x2: Int, y2: Int, delay: Int): Boolean {
|
||||||
|
prepareForGesture()
|
||||||
|
return mGlobalActionAutomator.swipe(x1, y1, x2, y2, delay.toLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun performGlobalAction(action: Int): Boolean {
|
||||||
|
ensureAccessibilityServiceEnabled()
|
||||||
|
val service = mAccessibilityBridge.service ?: return false
|
||||||
|
return service.performGlobalAction(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
||||||
|
@ScriptInterface
|
||||||
|
fun paste(target: ActionTarget): Boolean {
|
||||||
|
ScriptRuntime.requiresApi(18)
|
||||||
|
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_PASTE))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ensureAccessibilityServiceEnabled() {
|
||||||
|
mAccessibilityBridge.ensureServiceEnabled()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun performAction(simpleAction: SimpleAction): Boolean {
|
||||||
|
ensureAccessibilityServiceEnabled()
|
||||||
|
if (AccessibilityConfig.isUnintendedGuardEnabled() && isRunningPackageSelf) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val roots = mAccessibilityBridge.windowRoots().filter { it != null }
|
||||||
|
if (roots.isEmpty())
|
||||||
|
return false
|
||||||
|
var succeed = true
|
||||||
|
for (root in roots) {
|
||||||
|
succeed = succeed and simpleAction.perform(UiObject.createRoot(root))
|
||||||
|
}
|
||||||
|
return succeed
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setScreenMetrics(metrics: ScreenMetrics) {
|
||||||
|
mScreenMetrics = metrics
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -105,6 +105,9 @@ public class UiSelector extends UiGlobalSelector {
|
|||||||
}
|
}
|
||||||
List<UiObject> result = new ArrayList<>();
|
List<UiObject> result = new ArrayList<>();
|
||||||
for (AccessibilityNodeInfo root : roots) {
|
for (AccessibilityNodeInfo root : roots) {
|
||||||
|
if (root == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (root.getPackageName() != null && mAccessibilityBridge.getConfig().whiteListContains(root.getPackageName().toString())) {
|
if (root.getPackageName() != null && mAccessibilityBridge.getConfig().whiteListContains(root.getPackageName().toString())) {
|
||||||
Log.d(TAG, "package in white list, return null");
|
Log.d(TAG, "package in white list, return null");
|
||||||
return UiObjectCollection.Companion.getEMPTY();
|
return UiObjectCollection.Companion.getEMPTY();
|
||||||
|
|||||||
@@ -17,16 +17,14 @@ import com.stardust.util.ScreenMetrics
|
|||||||
* Created by Stardust on 2017/5/16.
|
* Created by Stardust on 2017/5/16.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GlobalActionAutomator(private val mHandler: Handler?) {
|
class GlobalActionAutomator(private val mHandler: Handler?, private val serviceProvider: () -> AccessibilityService) {
|
||||||
|
|
||||||
|
private val service: AccessibilityService
|
||||||
|
get() = serviceProvider()
|
||||||
|
|
||||||
private var mService: AccessibilityService? = null
|
|
||||||
private var mScreenMetrics: ScreenMetrics? = null
|
private var mScreenMetrics: ScreenMetrics? = null
|
||||||
|
|
||||||
fun setService(service: AccessibilityService) {
|
fun setScreenMetrics(screenMetrics: ScreenMetrics?) {
|
||||||
mService = service
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setScreenMetrics(screenMetrics: ScreenMetrics) {
|
|
||||||
mScreenMetrics = screenMetrics
|
mScreenMetrics = screenMetrics
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +42,7 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun performGlobalAction(globalAction: Int): Boolean {
|
private fun performGlobalAction(globalAction: Int): Boolean {
|
||||||
return if (mService == null) false else mService!!.performGlobalAction(globalAction)
|
return service.performGlobalAction(globalAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifications(): Boolean {
|
fun notifications(): Boolean {
|
||||||
@@ -88,23 +86,22 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
|
|||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
fun gestures(vararg strokes: GestureDescription.StrokeDescription): Boolean {
|
fun gestures(vararg strokes: GestureDescription.StrokeDescription): Boolean {
|
||||||
if (mService == null)
|
|
||||||
return false
|
|
||||||
val builder = GestureDescription.Builder()
|
val builder = GestureDescription.Builder()
|
||||||
for (stroke in strokes) {
|
for (stroke in strokes) {
|
||||||
builder.addStroke(stroke)
|
builder.addStroke(stroke)
|
||||||
}
|
}
|
||||||
return if (mHandler == null) {
|
val handler = mHandler
|
||||||
|
return if (handler == null) {
|
||||||
gesturesWithoutHandler(builder.build())
|
gesturesWithoutHandler(builder.build())
|
||||||
} else {
|
} else {
|
||||||
gesturesWithHandler(builder.build())
|
gesturesWithHandler(handler, builder.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
private fun gesturesWithHandler(description: GestureDescription): Boolean {
|
private fun gesturesWithHandler(handler: Handler, description: GestureDescription): Boolean {
|
||||||
val result = VolatileDispose<Boolean>()
|
val result = VolatileDispose<Boolean>()
|
||||||
mService!!.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
|
service.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
|
||||||
override fun onCompleted(gestureDescription: GestureDescription) {
|
override fun onCompleted(gestureDescription: GestureDescription) {
|
||||||
result.setAndNotify(true)
|
result.setAndNotify(true)
|
||||||
}
|
}
|
||||||
@@ -112,7 +109,7 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
|
|||||||
override fun onCancelled(gestureDescription: GestureDescription) {
|
override fun onCancelled(gestureDescription: GestureDescription) {
|
||||||
result.setAndNotify(false)
|
result.setAndNotify(false)
|
||||||
}
|
}
|
||||||
}, mHandler)
|
}, handler)
|
||||||
return result.blockedGet()
|
return result.blockedGet()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +118,7 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
|
|||||||
prepareLooperIfNeeded()
|
prepareLooperIfNeeded()
|
||||||
val result = VolatileBox(false)
|
val result = VolatileBox(false)
|
||||||
val handler = Handler(Looper.myLooper())
|
val handler = Handler(Looper.myLooper())
|
||||||
mService!!.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
|
service.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
|
||||||
override fun onCompleted(gestureDescription: GestureDescription) {
|
override fun onCompleted(gestureDescription: GestureDescription) {
|
||||||
result.set(true)
|
result.set(true)
|
||||||
quitLoop()
|
quitLoop()
|
||||||
@@ -138,13 +135,11 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
|
|||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
fun gesturesAsync(vararg strokes: GestureDescription.StrokeDescription) {
|
fun gesturesAsync(vararg strokes: GestureDescription.StrokeDescription) {
|
||||||
if (mService == null)
|
|
||||||
return
|
|
||||||
val builder = GestureDescription.Builder()
|
val builder = GestureDescription.Builder()
|
||||||
for (stroke in strokes) {
|
for (stroke in strokes) {
|
||||||
builder.addStroke(stroke)
|
builder.addStroke(stroke)
|
||||||
}
|
}
|
||||||
mService!!.dispatchGesture(builder.build(), null, null)
|
service.dispatchGesture(builder.build(), null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun quitLoop() {
|
private fun quitLoop() {
|
||||||
@@ -174,11 +169,11 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun scaleX(x: Int): Int {
|
private fun scaleX(x: Int): Int {
|
||||||
return if (mScreenMetrics == null) x else mScreenMetrics!!.scaleX(x)
|
return mScreenMetrics?.scaleX(x) ?: x
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scaleY(y: Int): Int {
|
private fun scaleY(y: Int): Int {
|
||||||
return if (mScreenMetrics == null) y else mScreenMetrics!!.scaleY(y)
|
return mScreenMetrics?.scaleX(y) ?: y
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
|||||||
Reference in New Issue
Block a user