Add: Volume Changing to stop scripts, Fix: Automator ANR
This commit is contained in:
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.stardust.scriptdroid"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 23
|
||||
versionCode 103
|
||||
versionName "2.0.1 Beta"
|
||||
versionCode 106
|
||||
versionName "2.0.3 Beta"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
|
||||
|
||||
@@ -26,6 +26,16 @@ launchApp("微信");
|
||||
### currentActivity()
|
||||
返回最近一次监测到的正在运行的Activity的名称,一般可以认为就是当前正在运行的Activity的名称。
|
||||
|
||||
### getPackageName(appName)
|
||||
* appName \<String\> 应用名称
|
||||
|
||||
获取应用的包名。例如getPackageName("QQ")为"com.tencent.mobileqq"。如果有相同名称的应用,只返回其中某一个的包名。如果不存在这个名称的应用,会返回空字符串。
|
||||
|
||||
### openAppSetting(packageName)
|
||||
* packageName \<String\> 应用包名
|
||||
|
||||
打开某个应用的应用详情页,也就是管理应用权限和可以停止其运行的页面。如果应用包名不存在,则返回false;否则返回true。
|
||||
|
||||
### setClip(text)
|
||||
* text \<String\> 文本
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
**自动操作的函数都需要开启"自动操作服务"才能执行,否则执行到相应函数时脚本会停止运行。**
|
||||
### auto模式
|
||||
如果代码的第一行是
|
||||
```
|
||||
"auto";
|
||||
```
|
||||
那么脚本运行前会先确保自动操作服务已开启。
|
||||
|
||||
您也可以在设置中开启"使用Root权限自动开启自动操作服务",从而在运行到相应语句时可以自动开启。
|
||||
### click(text[, i])
|
||||
|
||||
@@ -135,6 +135,14 @@ var setClip = function(text){
|
||||
droid.setClip(text);
|
||||
}
|
||||
|
||||
var getPackageName = function(appName){
|
||||
return droid.getPackageName(appName);
|
||||
}
|
||||
|
||||
var openAppSetting = function(packageName){
|
||||
return droid.openAppSetting(packageName);
|
||||
}
|
||||
|
||||
var Tap = function(x, y){
|
||||
return shell("input tap " + x + " " + y, true).code == 1;
|
||||
}
|
||||
@@ -202,7 +210,6 @@ var Text = function(text){
|
||||
return shell("input text " + text, true).code == 1;
|
||||
}
|
||||
|
||||
|
||||
var __selector__ = droid.selector();
|
||||
var __obj__ = new java.lang.Object();
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ container.addView(btnOk);
|
||||
activity.setContentView(container);
|
||||
|
||||
btnOk.setOnClickListener(function(view){
|
||||
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("mqqwpa://im/chat?chat_type=wpa&uin=" + qq.getText())));
|
||||
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("mqqwpa://im/chat?chat_type=wpa&uin=" + qq.getText()))
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
activity.finish();
|
||||
});
|
||||
@@ -5,8 +5,12 @@ importClass(com.afollestad.materialdialogs.MaterialDialog);
|
||||
new MaterialDialog.Builder(activity)
|
||||
.title("简单计算器")
|
||||
.input("请输入算式", "1+1", function(dialog, input){
|
||||
eval("var ans = (" + input + ")");
|
||||
toast(ans);
|
||||
try{
|
||||
eval("var ans = (" + input + ")");
|
||||
toast(ans);
|
||||
}catch(e){
|
||||
toast("式子错误");
|
||||
}
|
||||
})
|
||||
.positiveText("计算")
|
||||
.dismissListener(function(dialog){
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
"auto";
|
||||
launch("com.tencent.mobileqq");
|
||||
toast("请打开一个聊天窗口");
|
||||
toast("出现红包时将会自动拆开并关闭");
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
"auto";
|
||||
importClass(android.content.Intent);
|
||||
importClass(android.net.Uri);
|
||||
importClass(android.provider.Settings);
|
||||
|
||||
function 打开App设置(packageName){
|
||||
var intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
var uri = Uri.fromParts("package", packageName, null);
|
||||
intent.setData(uri);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
打开App设置("com.tencent.mobileqq");
|
||||
openAppSetting("com.tencent.mobileqq");
|
||||
while(!currentPackage().equals("com.android.settings"));
|
||||
while(!click("通知"));
|
||||
while(!click("全部阻止"));
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
"auto";
|
||||
launch("com.tencent.mm");
|
||||
while(!click("发现"));
|
||||
while(!click("扫一扫"));
|
||||
@@ -1,3 +1,4 @@
|
||||
"auto";
|
||||
|
||||
function 打开正在运行的服务(){
|
||||
launch("com.android.settings");
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
"auto";
|
||||
launchApp("支付宝");
|
||||
while(!click("扫一扫"));
|
||||
@@ -1,3 +1,5 @@
|
||||
"auto";
|
||||
|
||||
function 下滑(){
|
||||
className("AbsListView").scrollable().scrollForward();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"auto";
|
||||
|
||||
launchApp("QQ");
|
||||
toast("打开一个聊天窗口,并点击下面的图片按钮");
|
||||
for(i = 0; i < 100;i++){
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"auto";
|
||||
|
||||
while(true){
|
||||
if(id("i4").untilFindOne().parent().parent().click()){
|
||||
sleep(700);
|
||||
|
||||
15
app/src/main/assets/sample/选择器/批量取关公众号.js
Normal file
15
app/src/main/assets/sample/选择器/批量取关公众号.js
Normal file
@@ -0,0 +1,15 @@
|
||||
"auto";
|
||||
|
||||
function 取消关注(){
|
||||
id("af9").longClickable().longClick();
|
||||
click("取消关注");
|
||||
click("不再关注");
|
||||
}
|
||||
|
||||
toast("请在10秒内打开订阅号界面");
|
||||
toast("10秒后如果没有反应请稍微滑动一下页面");
|
||||
sleep(10 * 1000);
|
||||
|
||||
while(true){
|
||||
取消关注();
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
"auto";
|
||||
|
||||
launchApp("网易云音乐");
|
||||
id("kp").click();
|
||||
text("签到").className("TextView").click();
|
||||
@@ -43,6 +43,11 @@ public class Pref {
|
||||
return def().getBoolean(getString(R.string.key_use_volume_control_record), false);
|
||||
}
|
||||
|
||||
public static boolean isRunningVolumeControlEnable() {
|
||||
return def().getBoolean(getString(R.string.key_use_volume_control_running), false);
|
||||
}
|
||||
|
||||
|
||||
private static String getString(int id) {
|
||||
return App.getApp().getString(id);
|
||||
}
|
||||
@@ -58,4 +63,5 @@ public class Pref {
|
||||
public static boolean isFirstUsing() {
|
||||
return getDisposableBoolean("isFirstUsing", true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package com.stardust.scriptdroid.droid;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jraska.console.timber.ConsoleTree;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.Pref;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
|
||||
import com.stardust.scriptdroid.droid.runtime.ScriptStopException;
|
||||
import com.stardust.scriptdroid.droid.script.JavaScriptEngine;
|
||||
import com.stardust.scriptdroid.droid.script.RhinoJavaScriptEngine;
|
||||
import com.stardust.scriptdroid.droid.script.ScriptExecuteActivity;
|
||||
import com.stardust.scriptdroid.service.VolumeChangeObverseService;
|
||||
import com.stardust.scriptdroid.tool.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -32,6 +36,8 @@ public class Droid {
|
||||
|
||||
public static final String UI = "\"ui\";";
|
||||
|
||||
public static final String AUTO = "\"auto\";";
|
||||
|
||||
public interface OnRunFinishedListener extends Serializable {
|
||||
void onRunFinished(Object result);
|
||||
|
||||
@@ -63,8 +69,18 @@ public class Droid {
|
||||
}
|
||||
};
|
||||
private static Droid instance = new Droid();
|
||||
private VolumeChangeObverseService.OnVolumeChangeListener mOnVolumeChangeListener = new VolumeChangeObverseService.OnVolumeChangeListener() {
|
||||
@Override
|
||||
public void onVolumeChange() {
|
||||
if (Pref.isRunningVolumeControlEnable()) {
|
||||
stopAllAndToast();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private Droid() {
|
||||
VolumeChangeObverseService.addOnVolumeChangeListener(mOnVolumeChangeListener);
|
||||
}
|
||||
|
||||
public static Droid getInstance() {
|
||||
@@ -107,6 +123,7 @@ public class Droid {
|
||||
}
|
||||
|
||||
public void runScript(final String script, OnRunFinishedListener listener, RunningConfig config) {
|
||||
App.getApp().startService(new Intent(App.getApp(), VolumeChangeObverseService.class));
|
||||
listener = listener == null ? DEFAULT_LISTENER : listener;
|
||||
if (config.runInNewThread) {
|
||||
if (script.startsWith(UI)) {
|
||||
@@ -125,6 +142,15 @@ public class Droid {
|
||||
return JAVA_SCRIPT_ENGINE.stopAll();
|
||||
}
|
||||
|
||||
|
||||
public void stopAllAndToast() {
|
||||
int n = stopAll();
|
||||
if (n > 0)
|
||||
RUNTIME.toast(String.format(App.getResString(R.string.text_already_stop_n_scripts), n));
|
||||
else
|
||||
RUNTIME.toast(App.getResString(R.string.text_no_running_script));
|
||||
}
|
||||
|
||||
private void checkFile(File file) {
|
||||
if (file == null) {
|
||||
throw new NullPointerException("file = null");
|
||||
@@ -151,6 +177,8 @@ public class Droid {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (mScript.startsWith(AUTO))
|
||||
DroidRuntime.getRuntime().ensureAccessibilityServiceEnable();
|
||||
mOnRunFinishedListener.onRunFinished(JAVA_SCRIPT_ENGINE.execute(mScript));
|
||||
} catch (Exception e) {
|
||||
mOnRunFinishedListener.onException(e);
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.stardust.scriptdroid.accessibility.AccessibilityInfoProvider;
|
||||
import com.stardust.scriptdroid.droid.runtime.action.ActionTarget;
|
||||
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
||||
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
|
||||
import com.stardust.scriptdroid.tool.IntentTool;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.jraska.console.Console;
|
||||
import com.stardust.scriptdroid.App;
|
||||
@@ -77,28 +78,34 @@ public class DroidRuntime {
|
||||
mUIHandler = new Handler(App.getApp().getMainLooper());
|
||||
}
|
||||
|
||||
public void launchPackage(String packageName) {
|
||||
PackageManager packageManager = App.getApp().getPackageManager();
|
||||
App.getApp().startActivity(packageManager.getLaunchIntentForPackage(packageName));
|
||||
public boolean launchPackage(String packageName) {
|
||||
try {
|
||||
PackageManager packageManager = App.getApp().getPackageManager();
|
||||
App.getApp().startActivity(packageManager.getLaunchIntentForPackage(packageName));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void launch(String packageName, String className) {
|
||||
App.getApp().startActivity(new Intent().setClassName(packageName, className).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
public boolean launchApp(String appName) {
|
||||
return launchPackage(getPackageName(appName));
|
||||
}
|
||||
|
||||
public void launchApp(String appName) {
|
||||
public String getPackageName(String appName) {
|
||||
PackageManager packageManager = App.getApp().getPackageManager();
|
||||
List<ApplicationInfo> installedApplications = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
|
||||
for (ApplicationInfo applicationInfo : installedApplications) {
|
||||
if (packageManager.getApplicationLabel(applicationInfo).toString().equals(appName)) {
|
||||
launchPackage(applicationInfo.packageName);
|
||||
break;
|
||||
return applicationInfo.processName;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String[] getPackageName(String appName) {
|
||||
return new String[0];
|
||||
public boolean openAppSetting(String packageName){
|
||||
return IntentTool.goToAppSetting(App.getApp(), packageName);
|
||||
}
|
||||
|
||||
public ActionTarget text(String text, int i) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
public abstract class Action {
|
||||
|
||||
private boolean mPerformUtilSucceed = false;
|
||||
private Object mResult;
|
||||
private volatile Object mResult = false;
|
||||
|
||||
public Action(boolean performUtilSucceed) {
|
||||
mPerformUtilSucceed = performUtilSucceed;
|
||||
|
||||
@@ -12,6 +12,9 @@ import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
|
||||
import com.stardust.view.accessibility.AccessibilityDelegate;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/21.
|
||||
@@ -27,12 +30,14 @@ public class ActionPerformAccessibilityDelegate implements AccessibilityDelegate
|
||||
|
||||
private static Action action;
|
||||
|
||||
private Executor mExecutor = Executors.newFixedThreadPool(5);
|
||||
|
||||
public static void setAction(Action action) {
|
||||
synchronized (ACTION_LOCK) {
|
||||
ActionPerformAccessibilityDelegate.action = action;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event) {
|
||||
synchronized (ACTION_LOCK) {
|
||||
@@ -43,18 +48,27 @@ public class ActionPerformAccessibilityDelegate implements AccessibilityDelegate
|
||||
Log.v(TAG, "root = null");
|
||||
return false;
|
||||
}
|
||||
Log.i(TAG, "perform action:" + action);
|
||||
if (action.perform(root)) {
|
||||
action.setResult(true);
|
||||
onActionPerformed();
|
||||
} else if (!action.performUtilSucceed()) {
|
||||
action.setResult(false);
|
||||
onActionPerformed();
|
||||
}
|
||||
performAction(root, action);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void performAction(final AccessibilityNodeInfo root, final Action action) {
|
||||
mExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "perform action:" + action);
|
||||
if (action.perform(root)) {
|
||||
action.setResult(true);
|
||||
onActionPerformed();
|
||||
} else if (!action.performUtilSucceed()) {
|
||||
action.setResult(false);
|
||||
onActionPerformed();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void onActionPerformed() {
|
||||
synchronized (ACTION_LOCK) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.view.View;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.layout_inspector.view.LayoutInspectView;
|
||||
import com.stardust.scriptdroid.tool.IntentTool;
|
||||
import com.stardust.view.Floaty;
|
||||
import com.stardust.view.ResizableFloaty;
|
||||
|
||||
@@ -30,16 +31,17 @@ public class FloatingWindowManger {
|
||||
|
||||
public static void goToFloatingWindowPermissionSetting() {
|
||||
String packageName = App.getApp().getPackageName();
|
||||
Intent intent;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
Uri.parse("package:" + packageName))
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
App.getApp().startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
Uri.parse("package:" + packageName))
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
} catch (Exception e) {
|
||||
IntentTool.goToAppSetting(App.getApp());
|
||||
}
|
||||
} else {
|
||||
intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + packageName))
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
IntentTool.goToAppSetting(App.getApp());
|
||||
}
|
||||
App.getApp().startActivity(intent);
|
||||
}
|
||||
|
||||
private static boolean hasFloatingWindowPermission() {
|
||||
@@ -56,6 +58,6 @@ public class FloatingWindowManger {
|
||||
|
||||
public static void hideFloatingWindow() {
|
||||
if (HoverMenuService.isServiceRunning())
|
||||
HoverMenuService.stopService();
|
||||
App.getApp().stopService(new Intent(App.getApp(), HoverMenuService.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ public class HoverMenuService extends Service {
|
||||
public static final String MESSAGE_MENU_EXPANDING = "MESSAGE_MENU_EXPANDING";
|
||||
public static final String MESSAGE_MENU_EXIT = "MESSAGE_MENU_EXIT";
|
||||
|
||||
private static HoverMenuService service = null;
|
||||
private static boolean sIsRunning;
|
||||
|
||||
public static void startService(Context context) {
|
||||
@@ -66,13 +65,6 @@ public class HoverMenuService extends Service {
|
||||
return sIsRunning;
|
||||
}
|
||||
|
||||
public static void stopService() {
|
||||
if (isServiceRunning() && service != null) {
|
||||
service.stopSelf();
|
||||
setIsRunning(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setIsRunning(boolean isRunning) {
|
||||
sIsRunning = isRunning;
|
||||
EventBus.getDefault().post(new ServiceStateChangedEvent(sIsRunning));
|
||||
@@ -105,20 +97,18 @@ public class HoverMenuService extends Service {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
if (service != null) {
|
||||
stopSelf();
|
||||
return;
|
||||
}
|
||||
service = this;
|
||||
EventBus.getDefault().register(this);
|
||||
mPrefs = getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
|
||||
tryInitViews();
|
||||
}
|
||||
|
||||
private void tryInitViews() {
|
||||
try {
|
||||
initViews();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show();
|
||||
FloatingWindowManger.goToFloatingWindowPermissionSetting();
|
||||
stopService();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +161,8 @@ public class HoverMenuService extends Service {
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (mWindowHoverMenu == null)
|
||||
tryInitViews();
|
||||
if (mWindowHoverMenu != null)
|
||||
mWindowHoverMenu.show();
|
||||
return START_STICKY;
|
||||
@@ -183,8 +175,6 @@ public class HoverMenuService extends Service {
|
||||
if (EventBus.getDefault().isRegistered(this))
|
||||
EventBus.getDefault().unregister(this);
|
||||
setIsRunning(false);
|
||||
if (service == this)
|
||||
service = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -78,11 +78,7 @@ public class MainMenuNavigatorContent implements NavigatorContent {
|
||||
|
||||
@ViewBinding.Click(R.id.stop_all_running_scripts)
|
||||
private void stopAllRunningScripts() {
|
||||
int n = Droid.getInstance().stopAll();
|
||||
if (n > 0)
|
||||
Toast.makeText(mView.getContext(), String.format(mView.getContext().getString(R.string.text_already_stop_n_scripts), n), Toast.LENGTH_SHORT).show();
|
||||
else
|
||||
Toast.makeText(mView.getContext(), R.string.text_no_running_script, Toast.LENGTH_SHORT).show();
|
||||
Droid.getInstance().stopAllAndToast();
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.open_launcher)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.stardust.scriptdroid.external.floating_window.content;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.view.View;
|
||||
@@ -8,6 +9,8 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.Pref;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.accessibility.AccessibilityEventHelper;
|
||||
import com.stardust.scriptdroid.external.floating_window.HoverMenuService;
|
||||
@@ -15,6 +18,7 @@ import com.stardust.scriptdroid.record.Recorder;
|
||||
import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder;
|
||||
import com.stardust.scriptdroid.record.inputevent.InputEventConverter;
|
||||
import com.stardust.scriptdroid.record.inputevent.TouchRecorder;
|
||||
import com.stardust.scriptdroid.service.VolumeChangeObverseService;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
import com.stardust.util.MessageEvent;
|
||||
import com.stardust.view.ViewBinder;
|
||||
@@ -53,10 +57,26 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
|
||||
private Recorder mRecorder;
|
||||
private Context mContext;
|
||||
|
||||
private VolumeChangeObverseService.OnVolumeChangeListener mOnVolumeChangeListener = new VolumeChangeObverseService.OnVolumeChangeListener() {
|
||||
@Override
|
||||
public void onVolumeChange() {
|
||||
if (Pref.isRecordVolumeControlEnable()) {
|
||||
if (mRecorder == null) {
|
||||
startRecord();
|
||||
} else if (mRecorder.getState() == Recorder.STATE_RECORDING) {
|
||||
stopRecord();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public RecordNavigatorContent(Context context) {
|
||||
mContext = context;
|
||||
mView = View.inflate(context, R.layout.floating_window_record, null);
|
||||
ViewBinder.bind(this);
|
||||
EventBus.getDefault().register(this);
|
||||
App.getApp().startService(new Intent(App.getApp(), VolumeChangeObverseService.class));
|
||||
VolumeChangeObverseService.addOnVolumeChangeListener(mOnVolumeChangeListener);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -67,16 +87,12 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
|
||||
|
||||
@Override
|
||||
public void onShown(@NonNull Navigator navigator) {
|
||||
if (!EventBus.getDefault().isRegistered(this)) {
|
||||
EventBus.getDefault().register(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHidden() {
|
||||
if (EventBus.getDefault().isRegistered(this)) {
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.sw_root_container)
|
||||
@@ -145,6 +161,9 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
|
||||
public void onMessageEvent(MessageEvent event) {
|
||||
if (event.message.equals(HoverMenuService.MESSAGE_MENU_EXPANDING)) {
|
||||
pauseRecord();
|
||||
} else if (event.message.equals(HoverMenuService.MESSAGE_MENU_EXIT)) {
|
||||
EventBus.getDefault().unregister(this);
|
||||
VolumeChangeObverseService.removeOnVolumeChangeListener(mOnVolumeChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ public class AccessibilityActionRecordNotification {
|
||||
case ACTION_DELETE:
|
||||
AccessibilityActionRecordNotification.cancelNotification();
|
||||
stopRecordIfNeeded(context);
|
||||
VolumeChangeObverseService.stopServiceIfNeeded();
|
||||
break;
|
||||
case ACTION_REDO:
|
||||
redoRecord(context);
|
||||
@@ -93,7 +92,7 @@ public class AccessibilityActionRecordNotification {
|
||||
.setCustomContentView(AccessibilityActionRecordSwitchView.getInstance());
|
||||
}
|
||||
showNotification(builder.build());
|
||||
VolumeChangeObverseService.startServiceIfNeeded(App.getApp());
|
||||
App.getApp().startService(new Intent(App.getApp(), VolumeChangeObverseService.class));
|
||||
}
|
||||
|
||||
private static void showNotification(Notification notification) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -50,8 +51,11 @@ public class LayoutHierarchyView extends MultiLevelListView {
|
||||
private Paint mPaint;
|
||||
private int mStatusBarHeight;
|
||||
private NodeInfo mClickedNodeInfo;
|
||||
private View mClickedView;
|
||||
private Drawable mOriginalBackground;
|
||||
|
||||
private boolean mShowClickedNodeBounds;
|
||||
private int mClickedColor = 0x77c4c4c4;
|
||||
|
||||
public LayoutHierarchyView(Context context) {
|
||||
super(context);
|
||||
@@ -72,6 +76,11 @@ public class LayoutHierarchyView extends MultiLevelListView {
|
||||
mShowClickedNodeBounds = showClickedNodeBounds;
|
||||
}
|
||||
|
||||
public void setClickedColor(int clickedColor) {
|
||||
mClickedColor = clickedColor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void init() {
|
||||
mAdapter = new Adapter();
|
||||
@@ -83,18 +92,28 @@ public class LayoutHierarchyView extends MultiLevelListView {
|
||||
setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClicked(MultiLevelListView parent, View view, Object item, ItemInfo itemInfo) {
|
||||
mClickedNodeInfo = (NodeInfo) item;
|
||||
invalidate();
|
||||
setClickedItem(view, (NodeInfo) item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGroupItemClicked(MultiLevelListView parent, View view, Object item, ItemInfo itemInfo) {
|
||||
mClickedNodeInfo = (NodeInfo) item;
|
||||
invalidate();
|
||||
setClickedItem(view, (NodeInfo) item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setClickedItem(View view, NodeInfo item) {
|
||||
mClickedNodeInfo = item;
|
||||
if (mClickedView == null) {
|
||||
mOriginalBackground = view.getBackground();
|
||||
} else {
|
||||
mClickedView.setBackground(mOriginalBackground);
|
||||
}
|
||||
view.setBackgroundColor(mClickedColor);
|
||||
mClickedView = view;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void initPaint() {
|
||||
mPaint = new Paint();
|
||||
mPaint.setColor(Color.DKGRAY);
|
||||
|
||||
@@ -14,6 +14,8 @@ import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder
|
||||
import com.stardust.scriptdroid.Pref;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
@@ -22,32 +24,27 @@ import java.lang.ref.WeakReference;
|
||||
|
||||
public class VolumeChangeObverseService extends Service {
|
||||
|
||||
public interface OnVolumeChangeListener {
|
||||
|
||||
void onVolumeChange();
|
||||
}
|
||||
|
||||
private static final String ACTION_VOLUME_CHANGE = "android.media.VOLUME_CHANGED_ACTION";
|
||||
private static List<OnVolumeChangeListener> mOnVolumeChangeListenerList = new ArrayList<>();
|
||||
|
||||
public static void addOnVolumeChangeListener(OnVolumeChangeListener listener) {
|
||||
mOnVolumeChangeListenerList.add(listener);
|
||||
}
|
||||
|
||||
public static void removeOnVolumeChangeListener(OnVolumeChangeListener listener) {
|
||||
mOnVolumeChangeListenerList.remove(listener);
|
||||
}
|
||||
|
||||
private VolumeChangeReceiver mVolumeChangeReceiver;
|
||||
private static VolumeChangeObverseService instance;
|
||||
|
||||
public static void stopServiceIfNeeded() {
|
||||
if (instance != null) {
|
||||
instance.stopSelf();
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void startServiceIfNeeded(Context context) {
|
||||
if (Pref.isRecordVolumeControlEnable() && instance == null) {
|
||||
context.startService(new Intent(context, VolumeChangeObverseService.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
if (instance != null) {
|
||||
instance.stopSelf();
|
||||
}
|
||||
instance = this;
|
||||
mVolumeChangeReceiver = new VolumeChangeReceiver();
|
||||
registerReceiver(mVolumeChangeReceiver, new IntentFilter(ACTION_VOLUME_CHANGE));
|
||||
}
|
||||
@@ -61,7 +58,6 @@ public class VolumeChangeObverseService extends Service {
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
instance = null;
|
||||
unregisterReceiver(mVolumeChangeReceiver);
|
||||
}
|
||||
|
||||
@@ -76,10 +72,8 @@ public class VolumeChangeObverseService extends Service {
|
||||
return;
|
||||
}
|
||||
mLastChangeMillis = System.currentTimeMillis();
|
||||
if (AccessibilityActionRecorder.getInstance().getState() == Recorder.STATE_STOPPED) {
|
||||
AccessibilityActionRecordNotification.startRecord(VolumeChangeObverseService.this);
|
||||
} else {
|
||||
AccessibilityActionRecordNotification.stopRecord(VolumeChangeObverseService.this);
|
||||
for (OnVolumeChangeListener listener : mOnVolumeChangeListenerList) {
|
||||
listener.onVolumeChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.stardust.scriptdroid.tool;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -32,7 +33,11 @@ public class AccessibilityServiceTool {
|
||||
if (Pref.isFirstGoToAccessibilitySetting()) {
|
||||
Toast.makeText(context, context.getString(R.string.text_please_choose) + context.getString(R.string._app_name), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
AccessibilityServiceUtils.goToAccessibilitySetting(context);
|
||||
try {
|
||||
AccessibilityServiceUtils.goToAccessibilitySetting(context);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(context, context.getString(R.string.go_to_accessibility_settings) + context.getString(R.string._app_name), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean enableAccessibilityServiceByRootAndWaitFor(Class<AccessibilityWatchDogService> accessibilityService, int timeout) {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.stardust.scriptdroid.tool;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
|
||||
/**
|
||||
@@ -70,4 +72,20 @@ public class IntentTool {
|
||||
.setType("text/plain"));
|
||||
}
|
||||
|
||||
public static boolean goToAppSetting(Context context, String packageName) {
|
||||
try {
|
||||
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
i.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
i.setData(Uri.parse("package:" + packageName));
|
||||
context.startActivity(i);
|
||||
return true;
|
||||
} catch (ActivityNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean goToAppSetting(Context context) {
|
||||
return goToAppSetting(context, context.getPackageName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,4 +333,13 @@ public class EditActivity extends Editor920Activity {
|
||||
unregisterReceiver(mOnRunFinishedReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
try{
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
}catch (RuntimeException e){
|
||||
// FIXME: 2017/3/20
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,12 +50,14 @@ public class EditSideMenuFragment extends Fragment {
|
||||
return inflater.inflate(R.layout.fragment_edit_side_menu, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterCreateView() {
|
||||
setUpUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
if (mFloatingWindowSwitch == null) {
|
||||
setUpUI();
|
||||
}
|
||||
syncSwitchState();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class IssueReportActivity extends IssueReporterActivity {
|
||||
|
||||
|
||||
private boolean mCrash = false;
|
||||
private Method mReportIssue, mValidateInput;
|
||||
private boolean mReportFailed = false;
|
||||
|
||||
@@ -371,7 +371,8 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public void OnAppBarClick(View view) {
|
||||
@ViewBinding.Click(R.id.toolbar)
|
||||
public void OnToolbarClick() {
|
||||
new ImageSelector(this, mActivityResultIntermediary, new ImageSelector.ImageSelectorCallback() {
|
||||
@Override
|
||||
public void onImageSelected(ImageSelector selector, String path) {
|
||||
|
||||
@@ -52,13 +52,15 @@ public class SlideMenuFragment extends Fragment {
|
||||
return inflater.inflate(R.layout.fragment_slide_menu, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterCreateView() {
|
||||
setUpSwitchCompat();
|
||||
ViewBinder.bind(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
if (mAutoOperateServiceSwitch == null) {
|
||||
setUpSwitchCompat();
|
||||
ViewBinder.bind(this);
|
||||
}
|
||||
syncSwitchState();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,16 +43,7 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setUpScriptList();
|
||||
}
|
||||
|
||||
private void setUpScriptList() {
|
||||
protected void afterCreateView() {
|
||||
mScriptListRecyclerView = $(R.id.script_list);
|
||||
mScriptFileList = ScriptFileList.getImpl();
|
||||
mNoScriptHint = $(R.id.hint_no_script);
|
||||
@@ -69,6 +60,14 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler
|
||||
mScriptListRecyclerView.setScriptFileList(mScriptFileList);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setUpScriptList();
|
||||
}
|
||||
|
||||
private void setUpScriptList() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
|
||||
@@ -8,6 +8,8 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.widget.Toast;
|
||||
|
||||
import static com.stardust.scriptdroid.tool.IntentTool.goToAppSetting;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/10.
|
||||
*/
|
||||
@@ -17,23 +19,12 @@ public class FloatingWindowUtils {
|
||||
public static boolean checkFloatingWindowPermission(Context context, int messageResId) {
|
||||
if (!isFloatingWindowPermitted(context)) {
|
||||
Toast.makeText(context, messageResId, Toast.LENGTH_SHORT).show();
|
||||
goToAppSetting(context);
|
||||
goToAppSetting(context, context.getPackageName());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void goToAppSetting(Context context) {
|
||||
try {
|
||||
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
i.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
i.setData(Uri.parse("package:" + context.getPackageName()));
|
||||
context.startActivity(i);
|
||||
} catch (ActivityNotFoundException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFloatingWindowPermitted(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
return pm.checkPermission(Manifest.permission.SYSTEM_ALERT_WINDOW, context.getPackageName())
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:onClick="OnAppBarClick"
|
||||
android:title="@string/_app_name"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||
|
||||
|
||||
182
app/src/main/res/values-en/strings.xml
Normal file
182
app/src/main/res/values-en/strings.xml
Normal file
@@ -0,0 +1,182 @@
|
||||
<resources>
|
||||
<string name="_app_name">UiAutomator</string>
|
||||
<string name="action_settings">设置</string>
|
||||
<string name="action_disable_service">关闭服务</string>
|
||||
<string name="text_accessibility_service_description">使脚本自动操作(点击、长按、滑动等)所需,若关闭则只能执行不涉及自动操作的脚本。</string>
|
||||
<string name="text_new_file">新建文件</string>
|
||||
<string name="text_import_from_file">从文件导入</string>
|
||||
<string name="action_exit">退出</string>
|
||||
<string name="text_service_disabled">服务已关闭</string>
|
||||
<string name="text_file_manager_not_found">找不到文件管理器T.T</string>
|
||||
<string name="text_file_create_fail">文件创建失败</string>
|
||||
<string name="text_please_input_name">请输入名称</string>
|
||||
<string name="text_name">名称</string>
|
||||
<string name="text_go_to_setting">去设置</string>
|
||||
<string name="explain_accessibility_permission">软件需要打开\"自动操作服务\"才能运行,请在随后的设置中选择\"免Root脚本精灵\"并开启服务。\n您也可以稍后在侧拉菜单中设置。</string>
|
||||
<string name="text_cancel">取消</string>
|
||||
<string name="text_path_is_empty">路径为空</string>
|
||||
<string name="text_file_not_exists">文件不存在</string>
|
||||
<string name="text_no_file_rw_permission">无文件读写权限</string>
|
||||
<string name="action_test">内嵌920测试</string>
|
||||
<string name="text_no_accessibility_permission">自动操作服务未启动,脚本已停止运行</string>
|
||||
<string name="text_drawer_close">关闭侧拉菜单</string>
|
||||
<string name="text_drawer_open">打开侧拉菜单</string>
|
||||
<string name="text_undo">撤销</string>
|
||||
<string name="text_redo">重做</string>
|
||||
<string name="text_save">保存</string>
|
||||
<string name="text_run">运行</string>
|
||||
<string name="text_alert">提示</string>
|
||||
<string name="edit_exit_without_save_warn">内容尚未保存,您确定要退出吗?</string>
|
||||
<string name="text_save_and_exit">保存并退出</string>
|
||||
<string name="text_exit_directly">直接退出</string>
|
||||
<string name="text_setting">设置</string>
|
||||
<string name="text_exit">退出</string>
|
||||
<string name="text_auto_operate_service">自动操作服务</string>
|
||||
<string name="text_syntax_and_api">帮助</string>
|
||||
<string name="text_close_all_running_scripts">关闭所有正在运行的脚本</string>
|
||||
<string name="text_about">关于</string>
|
||||
<string name="text_licenses">开放源代码许可</string>
|
||||
<string name="text_do_not_remind_again">不再提示</string>
|
||||
<string name="text_sample_alipay_scan">支付宝扫一扫</string>
|
||||
<string name="text_sample_open_running_services">示例:打开正在运行的服务(安卓6.0+)</string>
|
||||
<string name="text_sample_simple_calculator">示例:简单计算器</string>
|
||||
<string name="copyright">Copyright©2016 All right reserves.</string>
|
||||
<string name="developer">星尘幻影</string>
|
||||
<string name="qq">946994919</string>
|
||||
<string name="email">hybbbb1996@gmail.com</string>
|
||||
<string name="github">软件源代码</string>
|
||||
<string name="text_already_copy_to_clip">已复制到剪贴板</string>
|
||||
<string name="donate_developer">打赏作者</string>
|
||||
<string name="text_email">邮箱</string>
|
||||
<string name="my_github">https://github.com/hyb1996/NoRootScriptDroid</string>
|
||||
<string name="share_app">[免Root脚本精灵]下载地址:http://www.coolapk.com/apk/com.stardust.scriptdroid </string>
|
||||
<string name="text_floating_window">悬浮窗</string>
|
||||
<string name="text_assist_service_notification">通知栏点击区域辅助开关</string>
|
||||
<string name="text_others">其他</string>
|
||||
<string name="text_assist_mode_enabled">点击区域辅助服务已开启(点击关闭)</string>
|
||||
<string name="text_assist_mode_disabled">点击区域辅助服务已关闭(点击开启)</string>
|
||||
<string name="text_error_report">错误报告</string>
|
||||
<string name="text_sample_qq_hongbao">示例:QQ自动抢红包</string>
|
||||
<string name="text_press_again_to_exit">再按一次退出程序</string>
|
||||
<string name="text_common_function">常用函数</string>
|
||||
<string name="sorry_for_crash">很抱歉(ಥ _ ಥ)程序遇到未知错误,即将停止运行\n错误代码:</string>
|
||||
<string name="text_no_running_script">没有正在运行的脚本</string>
|
||||
<string name="text_already_stop_n_scripts">已停止%d个正在运行的脚本</string>
|
||||
<string name="text_start_running">开始运行</string>
|
||||
<string name="text_open_by_other_apps">用其他应用打开</string>
|
||||
<string name="text_rename">重命名</string>
|
||||
<string name="text_rename_file_meanwhile">同时重命名原文件</string>
|
||||
<string name="text_please_input_new_name">请输入新名称</string>
|
||||
<string name="text_send_shortcut">创建桌面快捷方式</string>
|
||||
<string name="text_already_create">已创建</string>
|
||||
<string name="text_delete">删除</string>
|
||||
<string name="text_delete_absolutly">彻底删除</string>
|
||||
<string name="text_already_delete">已删除</string>
|
||||
<string name="text_delete_failed">文件删除失败</string>
|
||||
<string name="text_choose_file">选择一个文件</string>
|
||||
<string name="folder_name">/脚本/</string>
|
||||
<string name="text_error">错误</string>
|
||||
<string name="text_load_failed">还没有文档/(ㄒoㄒ)/~~</string>
|
||||
<string name="text_copy_debug_info">复制调试信息</string>
|
||||
<string name="text_it_is_the_developer_of_app">这是软件开发者(。・・)ノ</string>
|
||||
<string name="text_lll">略略略</string>
|
||||
<string name="text_choose_email_app">请选择邮件应用</string>
|
||||
<string name="text_assist_clip">点击定位剪贴板</string>
|
||||
<string name="text_script_stopped">脚本已停止</string>
|
||||
<string name="assist_mode_notice">\"点击区域辅助服务\"是在要点击的区域不是文本时使用的,参见\"帮助\"。\"点击区域辅助服务\"只有在\"自动操作服务\"开启时才有效。</string>
|
||||
<string name="text_please_choose">请选择</string>
|
||||
<string name="text_crash">崩溃了o(≧口≦)o</string>
|
||||
<string name="crash_feedback">点击\"退出\"退出程序(ಥ _ ಥ)或者提交错误报告或者复制调试信息反馈给开发者(≧∇≦)ノ</string>
|
||||
<string name="text_cannot_create_dialog_when_app_invisible">无法在后台显示弹框,脚本已停止运行</string>
|
||||
<string name="text_sample_for_qq_chat">示例:QQ强制聊天</string>
|
||||
<string name="text_re_import_samples">重新导入示例脚本文件</string>
|
||||
<string name="text_re_import_succeed">导入成功</string>
|
||||
<string name="text_fail">失败</string>
|
||||
<string name="text_clear">清空</string>
|
||||
<string name="text_console">控制台</string>
|
||||
<string name="text_sample_wechat_scan">微信扫一扫</string>
|
||||
<string name="text_report_bug">提交错误报告</string>
|
||||
<string name="text_bug_report">Bug Report</string>
|
||||
<string name="text_report_fail">提交失败</string>
|
||||
<string name="text_report_succeed">提交成功</string>
|
||||
<string name="edit_and_run_handle_intent_error">无法处理文件</string>
|
||||
<string name="text_crash_en">Crash</string>
|
||||
<string name="text_issue_report">问题反馈</string>
|
||||
<string name="text_script_record">录制脚本</string>
|
||||
<string name="hint_start_record">在通知栏中开始录制</string>
|
||||
<string name="text_start_record">开始录制</string>
|
||||
<string name="text_stop_record">停止录制</string>
|
||||
<string name="text_not_recording">录制未开始</string>
|
||||
<string name="text_pause_record">暂停录制</string>
|
||||
<string name="text_resume_record">继续录制</string>
|
||||
<string name="text_recorded">录制结束</string>
|
||||
<string name="text_copy_to_clip">复制到剪贴板</string>
|
||||
<string name="text_file_write_fail">文件写入失败</string>
|
||||
<string name="text_need_enable_accessibility_service">需要打开\"自动操作服务“才能录制脚本</string>
|
||||
<string name="text_join_qq_group">加入QQ交流群</string>
|
||||
<string name="text_copied">已复制到剪贴板</string>
|
||||
<string name="text_close">关闭</string>
|
||||
<string name="text_re_record">重新录制</string>
|
||||
<string name="text_use_volume_control_record">使用音量键控制</string>
|
||||
<string name="summary_use_volume_control_record">开启后每次音量变化会开始或停止脚本录制</string>
|
||||
<string name="key_use_volume_control_record">key_use_volume_control_record</string>
|
||||
<string name="text_mobile_qq_not_installed">未安装手机QQ</string>
|
||||
<string name="text_edit">编辑</string>
|
||||
<string name="key_max_length_for_code_completion">key_max_length_for_code_completion</string>
|
||||
<string name="text_max_length_for_code_completion">代码补全最大文件长度</string>
|
||||
<string name="text_file_exists">文件已存在</string>
|
||||
<string name="text_accessibility_service">无障碍服务</string>
|
||||
<string name="text_enable_accessibility_service_by_root">通过Root权限自动启用服务</string>
|
||||
<string name="text_auto_operate_service_enabled_but_not_running">自动操作服务已启用但并未运行,这可能是安卓的BUG,您可能需要重启手机</string>
|
||||
<string name="key_enable_accessibility_service_by_root">key_enable_accessibility_service_by_root</string>
|
||||
<string name="text_enable_accessibility_service_by_root_timeout">使用Root权限启动自动操作服务超时</string>
|
||||
<string name="summary_enable_accessibility_service_by_root">开启后运行脚本会使用Root权限自动开启自动操作服务</string>
|
||||
<string name="text_appearance">外观</string>
|
||||
<string name="text_theme_color">主题色</string>
|
||||
<string name="text_select_image">选择图片</string>
|
||||
<string name="text_help">帮助</string>
|
||||
<string name="text_root_script_record">录制脚本(root)</string>
|
||||
<string name="hint_start_root_record">使用音量上键,音量下键结束录制</string>
|
||||
<string name="text_no_floating_window_permission">没有悬浮窗权限</string>
|
||||
<string name="text_node_info">节点信息</string>
|
||||
<string name="text_layout_hierarchy">布局层次分析</string>
|
||||
<string name="text_layout_bounds">布局范围查看</string>
|
||||
<string name="text_no_accessibility_permission_to_capture">无障碍服务未启动</string>
|
||||
<string name="text_sample_script">示例脚本</string>
|
||||
<string name="text_my_script">我的脚本</string>
|
||||
<string name="hint_no_script">点击右上角新建第一个脚本吧~(。・・)ノ</string>
|
||||
<string name="text_reset_background">重置背景图片设置</string>
|
||||
<string name="text_restart_app_to_apply">重启软件生效</string>
|
||||
<string name="text_record_with_root">使用root权限录制</string>
|
||||
<string name="text_record_msg">录制提示</string>
|
||||
<string name="text_text_changed">文字改变</string>
|
||||
<string name="text_scrolled">滑动</string>
|
||||
<string name="text_long_clicked">长按</string>
|
||||
<string name="text_clicked">点击</string>
|
||||
<string name="text_open_launcher">打开主界面</string>
|
||||
<string name="text_copy_to_my_scripts">导入到我的脚本</string>
|
||||
<string name="text_import_succeed">导入成功</string>
|
||||
<string name="text_no_root_script_record">免Root脚本录制</string>
|
||||
<string name="text_script_record_with_root">Root脚本录制</string>
|
||||
<string name="text_use_key_to_start_record">开始录制按键</string>
|
||||
<string name="text_use_key_to_stop_record">结束录制按键</string>
|
||||
<string name="text_none">NONE</string>
|
||||
<string name="key_start_record_trigger">key_start_record_trigger</string>
|
||||
<string name="key_stop_record_trigger">key_stop_record_trigger</string>
|
||||
<string name="text_current_activity">当前活动:</string>
|
||||
<string name="text_current_package">当前应用包名:</string>
|
||||
|
||||
<string-array name="record_control_keys">
|
||||
<item>无</item>
|
||||
<item>音量上键</item>
|
||||
<item>音量下键</item>
|
||||
<item>照相键</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="record_control_values">
|
||||
<item>NONE</item>
|
||||
<item>KEY_VOLUMEUP</item>
|
||||
<item>KEY_VOLUMEDOWN</item>
|
||||
<item>KEY_CAMERA</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -165,6 +165,10 @@
|
||||
<string name="key_stop_record_trigger">key_stop_record_trigger</string>
|
||||
<string name="text_current_activity">当前活动:</string>
|
||||
<string name="text_current_package">当前应用包名:</string>
|
||||
<string name="go_to_accessibility_settings"><![CDATA[请打开设置->无障碍服务->免Root脚本精灵并开启]]></string>
|
||||
<string name="text_script_running">脚本运行</string>
|
||||
<string name="key_use_volume_control_running">key_use_volume_control_running</string>
|
||||
<string name="text_use_volume_to_stop_running">每次音量键变化停止所有脚本</string>
|
||||
|
||||
<string-array name="record_control_keys">
|
||||
<item>无</item>
|
||||
|
||||
@@ -14,21 +14,29 @@
|
||||
<com.stardust.theme.preference.ThemeColorPreferenceCategory android:title="@string/text_script_record_with_root">
|
||||
|
||||
<com.afollestad.materialdialogs.prefs.MaterialListPreference
|
||||
android:key="@string/key_start_record_trigger"
|
||||
android:defaultValue="@string/text_none"
|
||||
android:entries="@array/record_control_keys"
|
||||
android:entryValues="@array/record_control_values"
|
||||
android:key="@string/key_start_record_trigger"
|
||||
android:title="@string/text_use_key_to_start_record"
|
||||
/>
|
||||
<com.afollestad.materialdialogs.prefs.MaterialListPreference
|
||||
android:key="@string/key_stop_record_trigger"
|
||||
android:defaultValue="@string/text_none"
|
||||
android:entries="@array/record_control_keys"
|
||||
android:entryValues="@array/record_control_values"
|
||||
android:key="@string/key_stop_record_trigger"
|
||||
android:title="@string/text_use_key_to_stop_record"
|
||||
/>
|
||||
</com.stardust.theme.preference.ThemeColorPreferenceCategory>
|
||||
|
||||
<com.stardust.theme.preference.ThemeColorPreferenceCategory android:title="@string/text_script_running">
|
||||
|
||||
<com.stardust.theme.preference.ThemeColorSwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_use_volume_control_running"
|
||||
android:title="@string/text_use_volume_to_stop_running"/>
|
||||
</com.stardust.theme.preference.ThemeColorPreferenceCategory>
|
||||
|
||||
<com.stardust.theme.preference.ThemeColorPreferenceCategory android:title="@string/text_edit">
|
||||
|
||||
<com.afollestad.materialdialogs.prefs.MaterialEditTextPreference
|
||||
|
||||
@@ -11,6 +11,8 @@ import org.mozilla.javascript.ImporterTopLevel;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
@@ -18,10 +20,14 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
// TODO: 2017/3/3 自定义函数
|
||||
// TODO: 2017/3/19 翻译
|
||||
// FIXME: 2017/3/19 开始运行的提示覆盖问题
|
||||
// TODO: 2017/3/19
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertEquals(1, 1);
|
||||
Context context = Context.enter();
|
||||
context.setOptimizationLevel(-1);
|
||||
context.setLanguageVersion(Context.VERSION_1_7);
|
||||
|
||||
Reference in New Issue
Block a user