diff --git a/app-release-1.17.0213.apk b/app-release-1.17.0215.apk
similarity index 66%
rename from app-release-1.17.0213.apk
rename to app-release-1.17.0215.apk
index 7859212d..2b1b9040 100644
Binary files a/app-release-1.17.0213.apk and b/app-release-1.17.0215.apk differ
diff --git a/app/build.gradle b/app/build.gradle
index 6682df18..e8379456 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "com.stardust.scriptdroid"
minSdkVersion 19
targetSdkVersion 23
- versionCode 22
- versionName "1.17.0213"
+ versionCode 25
+ versionName "1.17.0215"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -25,6 +25,10 @@ android {
dataBinding {
enabled = true
}
+ lintOptions {
+ disable 'MissingTranslation'
+ disable 'ExtraTranslation'
+ }
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def file = output.outputFile
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index db448335..8303add1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,8 +17,9 @@
android:theme="@style/AppTheme"
tools:replace="android:label">
@@ -28,7 +29,7 @@
@@ -38,7 +39,7 @@
@@ -73,21 +74,22 @@
android:resource="@xml/provider_paths"/>
-
-
-
-
-
-
+
+
+
+
+
+
-
+
+
@@ -126,7 +128,7 @@
diff --git a/app/src/main/assets/javasccript_engine_init.js b/app/src/main/assets/javasccript_engine_init.js
index af750f8a..f9a0efc4 100644
--- a/app/src/main/assets/javasccript_engine_init.js
+++ b/app/src/main/assets/javasccript_engine_init.js
@@ -120,4 +120,8 @@ var clearConsole = function(){
var shell = function(cmd, root){
root = root ? 1 : 0;
droid.shell(cmd, root);
+}
+
+var getTexts = function(){
+ return droid.getTexts();
}
\ No newline at end of file
diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java
index c2d80eb7..5b6a1e61 100644
--- a/app/src/main/java/com/stardust/scriptdroid/App.java
+++ b/app/src/main/java/com/stardust/scriptdroid/App.java
@@ -5,21 +5,27 @@ import android.app.Application;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
+import com.stardust.scriptdroid.record.AccessibilityRecorderDelegate;
+import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
+import com.stardust.scriptdroid.ui.error.ErrorReportActivity;
import com.stardust.util.CrashHandler;
import com.stardust.util.StateObserver;
+import java.lang.ref.WeakReference;
+
/**
* Created by Stardust on 2017/1/27.
*/
public class App extends Application {
- private static App instance;
+ private static WeakReference instance;
private static StateObserver stateObserver;
- private static Activity currentActivity;
+ private static WeakReference currentActivity;
public static App getApp() {
- return instance;
+ return instance.get();
}
public static StateObserver getStateObserver() {
@@ -29,13 +35,24 @@ public class App extends Application {
public void onCreate() {
super.onCreate();
- Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class));
- instance = this;
+ if (!BuildConfig.DEBUG)
+ Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class));
+ instance = new WeakReference<>(this);
stateObserver = new StateObserver(PreferenceManager.getDefaultSharedPreferences(this));
+ registerActivityLifecycleCallback();
+ initAccessibilityServiceDelegates();
+ }
+
+ private void initAccessibilityServiceDelegates() {
+ AccessibilityWatchDogService.addDelegateIfNeeded(100, ActionPerformAccessibilityDelegate.class);
+ AccessibilityWatchDogService.addDelegateIfNeeded(200, AccessibilityRecorderDelegate.getInstance());
+ }
+
+ private void registerActivityLifecycleCallback() {
registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
- currentActivity = activity;
+ currentActivity = new WeakReference<>(activity);
}
@@ -46,14 +63,14 @@ public class App extends Application {
@Override
public void onActivityResumed(Activity activity) {
- currentActivity = activity;
+ currentActivity = new WeakReference<>(activity);
}
});
}
public static Activity currentActivity() {
- return currentActivity;
+ return currentActivity.get();
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/IssueReportActivity.java b/app/src/main/java/com/stardust/scriptdroid/IssueReportActivity.java
deleted file mode 100644
index dc1fd959..00000000
--- a/app/src/main/java/com/stardust/scriptdroid/IssueReportActivity.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.stardust.scriptdroid;
-
-import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
-import android.view.View;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import com.heinrichreimersoftware.androidissuereporter.IssueReporterActivity;
-import com.heinrichreimersoftware.androidissuereporter.model.github.GithubTarget;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Created by Stardust on 2017/2/13.
- */
-
-public class IssueReportActivity extends IssueReporterActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- handleIntent();
- findViewById(com.heinrichreimersoftware.androidissuereporter.R.id.air_optionAnonymous).performClick();
- ((EditText) findViewById(R.id.air_inputTitle)).setText(R.string.text_bug_report);
- getSupportActionBar().setTitle(R.string.text_report_bug);
- FloatingActionButton send = (FloatingActionButton) this.findViewById(com.heinrichreimersoftware.androidissuereporter.R.id.air_buttonSend);
- try {
- final Method reportIssue = IssueReporterActivity.class.getDeclaredMethod("reportIssue");
- reportIssue.setAccessible(true);
- send.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- try {
- reportIssue.invoke(IssueReportActivity.this);
- Toast.makeText(IssueReportActivity.this, R.string.text_report_succeed, Toast.LENGTH_SHORT).show();
- } catch (IllegalAccessException | InvocationTargetException e) {
- e.printStackTrace();
- Toast.makeText(IssueReportActivity.this, R.string.text_report_fail, Toast.LENGTH_SHORT).show();
- }
- exit();
- }
- });
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- }
-
-
- }
-
- private void handleIntent() {
- final String errorDetail = getIntent().getStringExtra("error");
- ((EditText) findViewById(R.id.air_inputDescription)).setText(errorDetail);
- }
-
- private void exit() {
- finishAffinity();
- }
-
- @Override
- protected GithubTarget getTarget() {
- return new GithubTarget("hyb1996", "NoRootScriptDroid");
- }
-
- @Override
- protected String getGuestToken() {
- return "cd403d68a9f3a3590a14408d055c55180e7af7d3";
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/assist/BoundsAssistClipList.java b/app/src/main/java/com/stardust/scriptdroid/bounds_assist/BoundsAssistClipList.java
similarity index 88%
rename from app/src/main/java/com/stardust/scriptdroid/droid/assist/BoundsAssistClipList.java
rename to app/src/main/java/com/stardust/scriptdroid/bounds_assist/BoundsAssistClipList.java
index 0e123a71..b4ebd98f 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/assist/BoundsAssistClipList.java
+++ b/app/src/main/java/com/stardust/scriptdroid/bounds_assist/BoundsAssistClipList.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.droid.assist;
+package com.stardust.scriptdroid.bounds_assist;
/**
* Created by Stardust on 2017/2/4.
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/assist/BoundsAssistant.java b/app/src/main/java/com/stardust/scriptdroid/bounds_assist/BoundsAssistant.java
similarity index 80%
rename from app/src/main/java/com/stardust/scriptdroid/droid/assist/BoundsAssistant.java
rename to app/src/main/java/com/stardust/scriptdroid/bounds_assist/BoundsAssistant.java
index 27a14e6d..6cc26512 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/assist/BoundsAssistant.java
+++ b/app/src/main/java/com/stardust/scriptdroid/bounds_assist/BoundsAssistant.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.droid.assist;
+package com.stardust.scriptdroid.bounds_assist;
import android.graphics.Rect;
import android.preference.PreferenceManager;
@@ -17,7 +17,7 @@ import com.stardust.scriptdroid.R;
*/
public class BoundsAssistant {
- public static final String KEY_ASSIST_MODE_ENABLE = "ASSIST_MODE_ENABLE";
+ public static final String KEY_BOUNDS_ASSIST_ENABLE = "ASSIST_MODE_ENABLE";
private static boolean assistModeEnable;
@@ -32,7 +32,7 @@ public class BoundsAssistant {
showAssistModeInfoDialog();
}
BoundsAssistant.assistModeEnable = assistModeEnable;
- App.getStateObserver().setState(KEY_ASSIST_MODE_ENABLE, assistModeEnable);
+ App.getStateObserver().setState(KEY_BOUNDS_ASSIST_ENABLE, assistModeEnable);
}
private static void showAssistModeInfoDialog() {
@@ -59,21 +59,25 @@ public class BoundsAssistant {
}
}
- private static Rect getBoundsInScreen(AccessibilityNodeInfo nodeInfo) {
+ public static Rect getBoundsInScreen(AccessibilityNodeInfo nodeInfo) {
Rect rect = new Rect();
nodeInfo.getBoundsInScreen(rect);
return rect;
}
private static void saveAndAlertBounds(Rect rect) {
- String str = rect.toString().replace('-', ',').replace(" ", "").substring(4);
+ String str = boundsToString(rect);
boundsAssistClipList.add(str);
Toast.makeText(App.getApp(), str, Toast.LENGTH_SHORT).show();
}
+ public static String boundsToString(Rect rect) {
+ return rect.toString().replace('-', ',').replace(" ", "").substring(4);
+ }
+
static {
- assistModeEnable = PreferenceManager.getDefaultSharedPreferences(App.getApp()).getBoolean(KEY_ASSIST_MODE_ENABLE, false);
+ assistModeEnable = PreferenceManager.getDefaultSharedPreferences(App.getApp()).getBoolean(KEY_BOUNDS_ASSIST_ENABLE, false);
}
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/assist/SharedPrefBoundsAssistClipList.java b/app/src/main/java/com/stardust/scriptdroid/bounds_assist/SharedPrefBoundsAssistClipList.java
similarity index 98%
rename from app/src/main/java/com/stardust/scriptdroid/droid/assist/SharedPrefBoundsAssistClipList.java
rename to app/src/main/java/com/stardust/scriptdroid/bounds_assist/SharedPrefBoundsAssistClipList.java
index 8715c6b0..3a4bc1a8 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/assist/SharedPrefBoundsAssistClipList.java
+++ b/app/src/main/java/com/stardust/scriptdroid/bounds_assist/SharedPrefBoundsAssistClipList.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.droid.assist;
+package com.stardust.scriptdroid.bounds_assist;
import android.content.Context;
import android.content.SharedPreferences;
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/DroidRuntime.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/DroidRuntime.java
index 70e4c1f2..e881d2ef 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/DroidRuntime.java
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/DroidRuntime.java
@@ -13,14 +13,17 @@ import com.afollestad.materialdialogs.MaterialDialog;
import com.jraska.console.Console;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.droid.ConsoleActivity;
+import com.stardust.scriptdroid.ui.console.ConsoleActivity;
import com.stardust.scriptdroid.droid.runtime.action.Action;
import com.stardust.scriptdroid.droid.runtime.action.ActionFactory;
-import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
+import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
import com.stardust.scriptdroid.droid.runtime.action.ActionTarget;
+import com.stardust.scriptdroid.droid.runtime.action.GetTextAction;
import com.stardust.scriptdroid.droid.runtime.api.IDroidRuntime;
+import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.tool.Shell;
+import java.util.Collections;
import java.util.List;
import timber.log.Timber;
@@ -166,22 +169,40 @@ public class DroidRuntime implements IDroidRuntime {
}
private boolean performAction(Action action) {
- if (ActionPerformService.getInstance() == null) {
+ if (AccessibilityWatchDogService.getInstance() == null) {
toast(App.getApp().getString(R.string.text_no_accessibility_permission));
throw new ScriptStopException(App.getApp().getString(R.string.text_no_accessibility_permission));
}
- ActionPerformService.setAction(action);
+ ActionPerformAccessibilityDelegate.setAction(action);
synchronized (mActionPerformLock) {
try {
mActionPerformLock.wait();
} catch (InterruptedException e) {
- ActionPerformService.setActions(ActionPerformService.NO_ACTION);
+ ActionPerformAccessibilityDelegate.setAction(ActionPerformAccessibilityDelegate.NO_ACTION);
throw new ScriptStopException(App.getApp().getString(R.string.text_script_stopped), e);
}
}
return mActionPerformResult;
}
+ public List getTexts() {
+ if (AccessibilityWatchDogService.getInstance() == null) {
+ toast(App.getApp().getString(R.string.text_no_accessibility_permission));
+ throw new ScriptStopException(App.getApp().getString(R.string.text_no_accessibility_permission));
+ }
+ GetTextAction.result = Collections.EMPTY_LIST;
+ ActionPerformAccessibilityDelegate.setAction(new GetTextAction());
+ synchronized (mActionPerformLock) {
+ try {
+ mActionPerformLock.wait();
+ return GetTextAction.result;
+ } catch (InterruptedException e) {
+ ActionPerformAccessibilityDelegate.setAction(ActionPerformAccessibilityDelegate.NO_ACTION);
+ throw new ScriptStopException(App.getApp().getString(R.string.text_script_stopped), e);
+ }
+ }
+ }
+
@Override
public void toast(final String text) {
mUIHandler.post(new Runnable() {
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformAccessibilityDelegate.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformAccessibilityDelegate.java
new file mode 100644
index 00000000..93bdbf20
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformAccessibilityDelegate.java
@@ -0,0 +1,55 @@
+package com.stardust.scriptdroid.droid.runtime.action;
+
+import android.accessibilityservice.AccessibilityService;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
+import com.stardust.scriptdroid.service.AccessibilityDelegate;
+
+
+/**
+ * Created by Stardust on 2017/1/21.
+ */
+
+public class ActionPerformAccessibilityDelegate implements AccessibilityDelegate {
+
+ private static final String TAG = "ActionPerformDelegate";
+
+ public static final Action NO_ACTION = null;
+
+ private static Action action;
+
+ public static void setAction(Action action) {
+ synchronized (ActionPerformAccessibilityDelegate.class) {
+ ActionPerformAccessibilityDelegate.action = action;
+ }
+ }
+
+ @Override
+ public boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event) {
+ if (action == NO_ACTION)
+ return false;
+ AccessibilityNodeInfo root = service.getRootInActiveWindow();
+ if (root == null) {
+ Log.v(TAG, "root = null");
+ }
+ Log.i(TAG, "perform action:" + action);
+ if (action.perform(root)) {
+ onActionPerformed(true);
+ } else if (!action.performUtilSucceed()) {
+ onActionPerformed(false);
+ }
+ return false;
+ }
+
+
+ private void onActionPerformed(boolean succeed) {
+ synchronized (ActionPerformAccessibilityDelegate.class) {
+ action = NO_ACTION;
+ DroidRuntime.getRuntime().notifyActionPerformed(succeed);
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformService.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformService.java
deleted file mode 100644
index af75677c..00000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformService.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.accessibilityservice.AccessibilityService;
-import android.os.Build;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.droid.assist.BoundsAssistant;
-import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
-import com.stardust.view.accessibility.AccessibilityServiceUtils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * Created by Stardust on 2017/1/21.
- */
-
-public class ActionPerformService extends AccessibilityService {
-
- private static final String TAG = "ActionPerformService";
- private static volatile ActionPerformService instance;
-
- @SuppressWarnings("unchecked")
- public static final List NO_ACTION = Collections.EMPTY_LIST;
- public static final int STATE_INACTIVE = -1;
- public static final int STATE_PERFORM = 0;
-
- public static final List actions = new ArrayList<>();
- private static int state = STATE_INACTIVE;
-
- public static void setActions(Collection collection) {
- synchronized (actions) {
- actions.clear();
- actions.addAll(collection);
- state = actions.size() > 0 ? STATE_PERFORM : STATE_INACTIVE;
- }
- }
-
- public static void setAction(Action action) {
- setActions(Collections.singletonList(action));
- }
-
- public static ActionPerformService getInstance() {
- return instance;
- }
-
- @Override
- public void onAccessibilityEvent(AccessibilityEvent event) {
- Log.v(TAG, "onAccessibilityEvent: state=" + state + " event=" + event);
- BoundsAssistant.performAssistance(event);
- if (state == STATE_INACTIVE)
- return;
- AccessibilityNodeInfo root = getRootInActiveWindow();
- if (root == null) {
- Log.v(TAG, "root = null");
- }
- Action action = nextAction();
- if (action == null) {
- onActionPerformed(true);
- } else {
- Log.i(TAG, "perform action:" + action);
- if (action.perform(root)) {
- state++;
- } else if (!action.performUtilSucceed()) {
- onActionPerformed(false);
- }
- }
-
- }
-
- private void onActionPerformed(boolean succeed) {
- state = STATE_INACTIVE;
- synchronized (actions) {
- actions.clear();
- }
- DroidRuntime.getRuntime().notifyActionPerformed(succeed);
- }
-
- private Action nextAction() {
- synchronized (actions) {
- if (state >= actions.size()) {
- return null;
- }
- return actions.get(state);
- }
- }
-
- @Override
- public void onInterrupt() {
-
- }
-
- @Override
- public void onServiceConnected() {
- // FIXME: 2017/2/12 有时在无障碍中开启服务后这里不会调用服务也不会运行,安卓的BUG???
- Log.v(TAG, "onServiceConnected");
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- Log.v(TAG, "onCreate");
- instance = this;
- }
-
- public static void disable() {
- if (instance != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- instance.disableSelf();
- } else {
- AccessibilityServiceUtils.goToAccessibilitySetting(App.getApp());
- }
- }
-
- public static boolean isEnable() {
- return AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), ActionPerformService.class);
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/GetTextAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/GetTextAction.java
new file mode 100644
index 00000000..26fc858e
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/GetTextAction.java
@@ -0,0 +1,37 @@
+package com.stardust.scriptdroid.droid.runtime.action;
+
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Stardust on 2017/2/14.
+ */
+
+public class GetTextAction extends Action {
+
+ public static List result;
+
+ @Override
+ public boolean perform(AccessibilityNodeInfo root) {
+ List texts = new ArrayList<>();
+ getText(root, texts);
+ result = texts;
+ return true;
+ }
+
+ private void getText(AccessibilityNodeInfo nodeInfo, List texts) {
+ CharSequence text = nodeInfo.getText();
+ if (text != null && text.length() != 0) {
+ texts.add(text.toString());
+ }
+ for (int i = 0; i < nodeInfo.getChildCount(); i++) {
+ AccessibilityNodeInfo child = nodeInfo.getChild(i);
+ if (child != null) {
+ getText(child, texts);
+ child.recycle();
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/script/DuktapeJavaScriptEngine.java b/app/src/main/java/com/stardust/scriptdroid/droid/script/DuktapeJavaScriptEngine.java
index b4ce7dc6..f3d63058 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/script/DuktapeJavaScriptEngine.java
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/script/DuktapeJavaScriptEngine.java
@@ -11,6 +11,8 @@ import java.io.StringReader;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
/**
* Created by Stardust on 2017/1/27.
@@ -70,7 +72,7 @@ public class DuktapeJavaScriptEngine implements JavaScriptEngine {
public void removeAndStop(Thread thread) {
synchronized (mThreadDuktapeEngineMap) {
DuktapeEngine engine = mThreadDuktapeEngineMap.remove(thread);
- stop(engine, thread);
+ forceStop(engine, thread);
}
}
@@ -84,14 +86,21 @@ public class DuktapeJavaScriptEngine implements JavaScriptEngine {
}
}
- private void stop(DuktapeEngine engine, Thread thread) {
- if (engine != null)
- engine.destory();
+
+ private void forceStop(final DuktapeEngine engine, Thread thread) {
try {
thread.interrupt();
} catch (Exception e) {
e.printStackTrace();
}
+ if (engine != null) {
+ new Timer().schedule(new TimerTask() {
+ @Override
+ public void run() {
+ engine.destory();
+ }
+ }, 1000);
+ }
}
private void add(DuktapeEngine duktapeEngine, Thread thread) {
@@ -110,7 +119,7 @@ public class DuktapeJavaScriptEngine implements JavaScriptEngine {
int n;
synchronized (mThreadDuktapeEngineMap) {
for (Map.Entry entry : mThreadDuktapeEngineMap.entrySet()) {
- stop(entry.getValue(), entry.getKey());
+ forceStop(entry.getValue(), entry.getKey());
}
n = mThreadDuktapeEngineMap.size();
mThreadDuktapeEngineMap.clear();
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/AssistModeSwitchNotification.java b/app/src/main/java/com/stardust/scriptdroid/external/notification/bounds_assist/BoundsAssistSwitchNotification.java
similarity index 63%
rename from app/src/main/java/com/stardust/scriptdroid/ui/AssistModeSwitchNotification.java
rename to app/src/main/java/com/stardust/scriptdroid/external/notification/bounds_assist/BoundsAssistSwitchNotification.java
index 4e4cd4e0..1248d000 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/AssistModeSwitchNotification.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/notification/bounds_assist/BoundsAssistSwitchNotification.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.external.notification.bounds_assist;
import android.app.Notification;
import android.app.NotificationManager;
@@ -7,9 +7,8 @@ import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.AssistModeSwitchService;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.droid.assist.BoundsAssistant;
+import com.stardust.scriptdroid.bounds_assist.BoundsAssistant;
import com.stardust.util.StateObserver;
@@ -17,36 +16,35 @@ import com.stardust.util.StateObserver;
* Created by Stardust on 2017/2/2.
*/
-public class AssistModeSwitchNotification {
+public class BoundsAssistSwitchNotification {
private static final int NOTIFY_ID = 11126;
- public static final String KEY_ASSIST_MODE_NOTIFICATION = "KEY_ASSIST_MODE_NOTIFICATION";
+ public static final String KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE = "KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE";
private static boolean enable = false;
- private static Notification notification;
public static boolean isEnable() {
return enable;
}
static {
- App.getStateObserver().register(KEY_ASSIST_MODE_NOTIFICATION, new StateObserver.OnBooleanStateChangedListener() {
+ App.getStateObserver().register(KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE, new StateObserver.OnStateChangedListener() {
@Override
- public void onStateChanged(Boolean newState) {
+ public void onStateChanged(boolean newState) {
setEnable(newState);
}
@Override
- public void initState(Boolean state) {
+ public void initState(boolean state) {
enable = state;
if (enable) {
showNotification();
}
}
});
- App.getStateObserver().register(BoundsAssistant.KEY_ASSIST_MODE_ENABLE, new StateObserver.OnBooleanStateChangedListener() {
+ App.getStateObserver().register(BoundsAssistant.KEY_BOUNDS_ASSIST_ENABLE, new StateObserver.OnStateChangedListener() {
@Override
- public void onStateChanged(Boolean newState) {
+ public void onStateChanged(boolean newState) {
if (enable) {
setEnable(false);
setEnable(true);
@@ -54,17 +52,17 @@ public class AssistModeSwitchNotification {
}
@Override
- public void initState(Boolean state) {
+ public void initState(boolean state) {
}
});
}
public static void setEnable(boolean enable) {
- if (AssistModeSwitchNotification.enable == enable)
+ if (BoundsAssistSwitchNotification.enable == enable)
return;
- AssistModeSwitchNotification.enable = enable;
- PreferenceManager.getDefaultSharedPreferences(App.getApp()).edit().putBoolean(KEY_ASSIST_MODE_NOTIFICATION, enable).apply();
+ BoundsAssistSwitchNotification.enable = enable;
+ PreferenceManager.getDefaultSharedPreferences(App.getApp()).edit().putBoolean(KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE, enable).apply();
if (enable) {
showNotification();
} else {
@@ -74,14 +72,14 @@ public class AssistModeSwitchNotification {
private static void showNotification() {
- notification = new NotificationCompat.Builder(App.getApp())
+ Notification notification = new NotificationCompat.Builder(App.getApp())
.setAutoCancel(false)
.setSmallIcon(R.drawable.ic_robot_head)
- .setDeleteIntent(AssistModeSwitchService.getDeletePendingIntent())
+ .setDeleteIntent(BoundsAssistSwitchNotificationHandleService.getDeletePendingIntent())
.setContentText(BoundsAssistant.isAssistModeEnable() ?
App.getApp().getString(R.string.text_assist_mode_enabled) :
App.getApp().getString(R.string.text_assist_mode_disabled))
- .setContentIntent(AssistModeSwitchService.getStartIntent())
+ .setContentIntent(BoundsAssistSwitchNotificationHandleService.getStartIntent())
.build();
showNotification(notification);
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/AssistModeSwitchService.java b/app/src/main/java/com/stardust/scriptdroid/external/notification/bounds_assist/BoundsAssistSwitchNotificationHandleService.java
similarity index 65%
rename from app/src/main/java/com/stardust/scriptdroid/AssistModeSwitchService.java
rename to app/src/main/java/com/stardust/scriptdroid/external/notification/bounds_assist/BoundsAssistSwitchNotificationHandleService.java
index 8d0fbdc2..d3c081c3 100644
--- a/app/src/main/java/com/stardust/scriptdroid/AssistModeSwitchService.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/notification/bounds_assist/BoundsAssistSwitchNotificationHandleService.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.external.notification.bounds_assist;
import android.app.PendingIntent;
import android.app.Service;
@@ -6,17 +6,18 @@ import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
-import com.stardust.scriptdroid.droid.assist.BoundsAssistant;
+import com.stardust.scriptdroid.App;
+import com.stardust.scriptdroid.bounds_assist.BoundsAssistant;
-import static com.stardust.scriptdroid.ui.AssistModeSwitchNotification.KEY_ASSIST_MODE_NOTIFICATION;
+import static com.stardust.scriptdroid.external.notification.bounds_assist.BoundsAssistSwitchNotification.KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE;
/**
* Created by Stardust on 2017/2/2.
*/
-public class AssistModeSwitchService extends Service {
+public class BoundsAssistSwitchNotificationHandleService extends Service {
- private static final String EXTRA_INTENT_VALID = "intentValid";
+ private static final String EXTRA_INTENT_VALID = "BoundsAssistSwitchNotificationHandleService.intentValid";
private static final String EXTRA_ACTION = "action";
private static final int ACTION_TOGGLE_ASSIST_MODE = 1;
@@ -24,7 +25,7 @@ public class AssistModeSwitchService extends Service {
public static PendingIntent getStartIntent() {
- Intent intent = new Intent(App.getApp(), AssistModeSwitchService.class)
+ Intent intent = new Intent(App.getApp(), BoundsAssistSwitchNotificationHandleService.class)
.putExtra(EXTRA_INTENT_VALID, true)
.putExtra(EXTRA_ACTION, ACTION_TOGGLE_ASSIST_MODE);
return PendingIntent.getService(App.getApp(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
@@ -32,7 +33,7 @@ public class AssistModeSwitchService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- boolean intentValid = intent.getBooleanExtra("intentValid", false);
+ boolean intentValid = intent.getBooleanExtra(EXTRA_INTENT_VALID, false);
if (intentValid) {
performAction(intent.getIntExtra(EXTRA_ACTION, 0));
}
@@ -46,7 +47,7 @@ public class AssistModeSwitchService extends Service {
BoundsAssistant.setAssistModeEnable(!BoundsAssistant.isAssistModeEnable());
break;
case ACTION_CANCEL_ASSIST_MODE_NOTIFICATION:
- App.getStateObserver().setState(KEY_ASSIST_MODE_NOTIFICATION, false);
+ App.getStateObserver().setState(KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE, false);
break;
}
}
@@ -58,7 +59,7 @@ public class AssistModeSwitchService extends Service {
}
public static PendingIntent getDeletePendingIntent() {
- Intent deleteIntent = new Intent(App.getApp(), AssistModeSwitchService.class)
+ Intent deleteIntent = new Intent(App.getApp(), BoundsAssistSwitchNotificationHandleService.class)
.putExtra(EXTRA_INTENT_VALID, true)
.putExtra(EXTRA_ACTION, ACTION_CANCEL_ASSIST_MODE_NOTIFICATION);
return PendingIntent.getService(App.getApp(), 0, deleteIntent, PendingIntent.FLAG_ONE_SHOT);
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordNotificationHandleService.java b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordNotificationHandleService.java
new file mode 100644
index 00000000..15d8089e
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordNotificationHandleService.java
@@ -0,0 +1,123 @@
+package com.stardust.scriptdroid.external.notification.record;
+
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.support.annotation.Nullable;
+import android.widget.Toast;
+
+import com.stardust.scriptdroid.App;
+import com.stardust.scriptdroid.R;
+import com.stardust.scriptdroid.record.AccessibilityRecorderDelegate;
+import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
+import com.stardust.scriptdroid.ui.main.MainActivity;
+
+import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.PAUSED;
+import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.RECORDING;
+import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.STOPPED;
+
+/**
+ * Created by Stardust on 2017/2/15.
+ */
+
+public class ActionRecordNotificationHandleService extends Service {
+
+
+ private static final String EXTRA_INTENT_VALID = "ActionRecordNotificationHandleService.intentValid";
+ private static final String EXTRA_ACTION = "action";
+ private static final int ACTION_STOP = 17771;
+ private static final int ACTION_START_OR_PAUSE = 17772;
+ private static final int ACTION_DELETE = 17773;
+
+ public static PendingIntent getStartOrPauseIntent() {
+ Intent intent = new Intent(App.getApp(), ActionRecordNotificationHandleService.class)
+ .putExtra(EXTRA_INTENT_VALID, true)
+ .putExtra(EXTRA_ACTION, ACTION_START_OR_PAUSE);
+ return PendingIntent.getService(App.getApp(), ACTION_START_OR_PAUSE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ public static PendingIntent getStopIntent() {
+ Intent intent = new Intent(App.getApp(), ActionRecordNotificationHandleService.class)
+ .putExtra(EXTRA_INTENT_VALID, true)
+ .putExtra(EXTRA_ACTION, ACTION_STOP);
+ return PendingIntent.getService(App.getApp(), ACTION_STOP, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ public static PendingIntent getDeleteIntent() {
+ Intent intent = new Intent(App.getApp(), ActionRecordNotificationHandleService.class)
+ .putExtra(EXTRA_INTENT_VALID, true)
+ .putExtra(EXTRA_ACTION, ACTION_DELETE);
+ return PendingIntent.getService(App.getApp(), ACTION_DELETE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ boolean intentValid = intent.getBooleanExtra(EXTRA_INTENT_VALID, false);
+ if (intentValid) {
+ performAction(intent.getIntExtra(EXTRA_ACTION, 0));
+ }
+ stopSelf();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ private void performAction(int action) {
+ switch (action) {
+ case ACTION_STOP:
+ stopRecord();
+ break;
+ case ACTION_START_OR_PAUSE:
+ startOrPauseRecord();
+ break;
+ case ACTION_DELETE:
+ stopRecordIfNeeded();
+ }
+ collapseNotificationBar();
+ }
+
+ private void collapseNotificationBar() {
+ sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ }
+
+ private void stopRecordIfNeeded() {
+ if (AccessibilityRecorderDelegate.getInstance().getState() != STOPPED) {
+ stopRecord();
+ }
+ }
+
+ private void startOrPauseRecord() {
+ int state = AccessibilityRecorderDelegate.getInstance().getState();
+ if (state == PAUSED) {
+ AccessibilityRecorderDelegate.getInstance().resumeRecord();
+ ActionRecordSwitchView.getInstance().setState(RECORDING);
+ } else if (state == RECORDING) {
+ AccessibilityRecorderDelegate.getInstance().pauseRecord();
+ ActionRecordSwitchView.getInstance().setState(PAUSED);
+ } else {
+ //state == STOPPED
+ if (AccessibilityWatchDogService.getInstance() == null) {
+ Toast.makeText(this, R.string.text_need_enable_accessibility_service, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ AccessibilityRecorderDelegate.getInstance().startRecord();
+ ActionRecordSwitchView.getInstance().setState(RECORDING);
+ Toast.makeText(this, R.string.text_start_record, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void stopRecord() {
+ if (AccessibilityRecorderDelegate.getInstance().getState() != STOPPED) {
+ String script = AccessibilityRecorderDelegate.getInstance().stopRecord();
+ ActionRecordSwitchView.getInstance().setState(STOPPED);
+ MainActivity.onActionRecordStopped(this, script);
+ } else {
+ Toast.makeText(App.getApp(), R.string.text_not_recording, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordSwitchNotification.java b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordSwitchNotification.java
new file mode 100644
index 00000000..6cf13fd0
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordSwitchNotification.java
@@ -0,0 +1,36 @@
+package com.stardust.scriptdroid.external.notification.record;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.support.v4.app.NotificationCompat;
+
+import com.stardust.scriptdroid.App;
+import com.stardust.scriptdroid.R;
+
+/**
+ * Created by Stardust on 2017/2/14.
+ */
+
+public class ActionRecordSwitchNotification {
+
+ private static final int NOTIFY_ID = 22236;
+ private static NotificationCompat.Builder builder;
+
+
+ public static void showOrUpdateNotification() {
+ if (builder == null) {
+ builder = new NotificationCompat.Builder(App.getApp())
+ .setAutoCancel(false)
+ .setSmallIcon(R.drawable.ic_robot_head)
+ .setDeleteIntent(ActionRecordNotificationHandleService.getDeleteIntent())
+ .setCustomContentView(ActionRecordSwitchView.getInstance());
+ }
+ showNotification(builder.build());
+ }
+
+ private static void showNotification(Notification notification) {
+ NotificationManager notificationManager = (NotificationManager) App.getApp().getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.notify(NOTIFY_ID, notification);
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordSwitchView.java b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordSwitchView.java
new file mode 100644
index 00000000..f59a1a0e
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/ActionRecordSwitchView.java
@@ -0,0 +1,54 @@
+package com.stardust.scriptdroid.external.notification.record;
+
+import android.widget.RemoteViews;
+
+import com.stardust.scriptdroid.App;
+import com.stardust.scriptdroid.R;
+
+/**
+ * Created by Stardust on 2017/2/14.
+ */
+
+public class ActionRecordSwitchView extends RemoteViews {
+
+ private static ActionRecordSwitchView instance;
+
+ public static final int STOPPED = 0;
+ public static final int PAUSED = 1;
+ public static final int RECORDING = 2;
+
+ public static ActionRecordSwitchView getInstance() {
+ if (instance == null) {
+ instance = new ActionRecordSwitchView();
+ }
+ return instance;
+ }
+
+ private ActionRecordSwitchView() {
+ super(App.getApp().getPackageName(), R.layout.remote_views_record_switch);
+ setUpOnClick();
+ }
+
+ public void setState(int state) {
+ switch (state) {
+ case STOPPED:
+ setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_play_arrow_grey600_48dp);
+ setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_start_record));
+ break;
+ case RECORDING:
+ setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_pause_grey600_48dp);
+ setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_pause_record));
+ break;
+ case PAUSED:
+ setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_play_arrow_grey600_48dp);
+ setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_resume_record));
+ break;
+ }
+ ActionRecordSwitchNotification.showOrUpdateNotification();
+ }
+
+ private void setUpOnClick() {
+ setOnClickPendingIntent(R.id.stop, ActionRecordNotificationHandleService.getStopIntent());
+ setOnClickPendingIntent(R.id.start_or_pause, ActionRecordNotificationHandleService.getStartOrPauseIntent());
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/shortcut/Shortcut.java b/app/src/main/java/com/stardust/scriptdroid/external/shortcut/Shortcut.java
similarity index 98%
rename from app/src/main/java/com/stardust/scriptdroid/shortcut/Shortcut.java
rename to app/src/main/java/com/stardust/scriptdroid/external/shortcut/Shortcut.java
index 937cab59..b82d7eca 100644
--- a/app/src/main/java/com/stardust/scriptdroid/shortcut/Shortcut.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/shortcut/Shortcut.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.shortcut;
+package com.stardust.scriptdroid.external.shortcut;
import android.content.Context;
import android.content.Intent;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ShortcutActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/shortcut/ShortcutActivity.java
similarity index 96%
rename from app/src/main/java/com/stardust/scriptdroid/ShortcutActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/external/shortcut/ShortcutActivity.java
index e97e3b4f..ad651dc7 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ShortcutActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/shortcut/ShortcutActivity.java
@@ -1,18 +1,17 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.external.shortcut;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;
+import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.Droid;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
-import java.util.function.BooleanSupplier;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
diff --git a/app/src/main/java/com/stardust/scriptdroid/tile/BoundsAssistEnableTileService.java b/app/src/main/java/com/stardust/scriptdroid/external/tile/BoundsAssistEnableTileService.java
similarity index 86%
rename from app/src/main/java/com/stardust/scriptdroid/tile/BoundsAssistEnableTileService.java
rename to app/src/main/java/com/stardust/scriptdroid/external/tile/BoundsAssistEnableTileService.java
index e176a18c..6c1f2104 100644
--- a/app/src/main/java/com/stardust/scriptdroid/tile/BoundsAssistEnableTileService.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/tile/BoundsAssistEnableTileService.java
@@ -1,11 +1,11 @@
-package com.stardust.scriptdroid.tile;
+package com.stardust.scriptdroid.external.tile;
import android.os.Build;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import android.support.annotation.RequiresApi;
-import com.stardust.scriptdroid.droid.assist.BoundsAssistant;
+import com.stardust.scriptdroid.bounds_assist.BoundsAssistant;
/**
* Created by Stardust on 2017/1/26.
diff --git a/app/src/main/java/com/stardust/scriptdroid/file/FileChooser.java b/app/src/main/java/com/stardust/scriptdroid/file/FileChooser.java
deleted file mode 100644
index d10d0989..00000000
--- a/app/src/main/java/com/stardust/scriptdroid/file/FileChooser.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.stardust.scriptdroid.file;
-
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.net.Uri;
-
-import com.stardust.scriptdroid.R;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-
-import static android.app.Activity.RESULT_OK;
-
-/**
- * Created by Stardust on 2017/1/23.
- */
-
-public class FileChooser {
-
- public interface FileManagerNotFoundHandler {
- void handle(ActivityNotFoundException e, String mimeType);
- }
-
- public interface OnFileChoseListener {
- void onFileChose(InputStream inputStream);
- }
-
- private static final int FILE_CHOOSE = 1209;
- private Activity mActivity;
-
- private OnFileChoseListener mOnFileChoseListener;
-
- public FileChooser(Activity activity) {
- mActivity = activity;
- }
-
- public void setOnFileChoseListener(OnFileChoseListener onFileChoseListener) {
- mOnFileChoseListener = onFileChoseListener;
- }
-
-
- public void startFileManagerToChoose(String mimeType, FileManagerNotFoundHandler handler) {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType(mimeType);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- try {
- mActivity.startActivityForResult(Intent.createChooser(intent, mActivity.getString(R.string.text_choose_file)), FILE_CHOOSE);
- } catch (ActivityNotFoundException ex) {
- handler.handle(ex, mimeType);
- }
- }
-
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == FILE_CHOOSE && resultCode == RESULT_OK) {
- Uri uri = data.getData();
- ContentResolver cr = mActivity.getContentResolver();
- try {
- InputStream inputStream = cr.openInputStream(uri);
- mOnFileChoseListener.onFileChose(inputStream);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/file/FileUtils.java b/app/src/main/java/com/stardust/scriptdroid/file/FileUtils.java
index 9b0c5f7c..a6aea5e2 100644
--- a/app/src/main/java/com/stardust/scriptdroid/file/FileUtils.java
+++ b/app/src/main/java/com/stardust/scriptdroid/file/FileUtils.java
@@ -176,4 +176,26 @@ public class FileUtils {
}
+ public static boolean writeString(String path, String text) {
+ return writeString(new File(path), text);
+ }
+
+ public static boolean writeString(File file, String text) {
+ try {
+ return writeString(new FileOutputStream(file), text);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public static boolean writeString(OutputStream outputStream, String text) {
+ try {
+ outputStream.write(text.getBytes());
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/stardust/scriptdroid/file/SampleFileTool.java b/app/src/main/java/com/stardust/scriptdroid/file/SampleFileManager.java
similarity index 93%
rename from app/src/main/java/com/stardust/scriptdroid/file/SampleFileTool.java
rename to app/src/main/java/com/stardust/scriptdroid/file/SampleFileManager.java
index c6ff9157..de7b97ba 100644
--- a/app/src/main/java/com/stardust/scriptdroid/file/SampleFileTool.java
+++ b/app/src/main/java/com/stardust/scriptdroid/file/SampleFileManager.java
@@ -16,7 +16,7 @@ import java.util.Map;
/**
* Created by Stardust on 2017/1/30.
*/
-public class SampleFileTool {
+public class SampleFileManager {
private static final Map SAMPLES = new MapEntries<>(new LinkedHashMap())
.entry("sample_open_running_services.js", R.string.text_sample_open_running_services)
@@ -27,9 +27,9 @@ public class SampleFileTool {
.entry("sample_alipay_scan.js", R.string.text_sample_alipay_scan)
.map();
- private static SampleFileTool instance = new SampleFileTool();
+ private static SampleFileManager instance = new SampleFileManager();
- public static SampleFileTool getInstance() {
+ public static SampleFileManager getInstance() {
return instance;
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/record/AccessibilityRecorderDelegate.java b/app/src/main/java/com/stardust/scriptdroid/record/AccessibilityRecorderDelegate.java
new file mode 100644
index 00000000..94031788
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/record/AccessibilityRecorderDelegate.java
@@ -0,0 +1,95 @@
+package com.stardust.scriptdroid.record;
+
+import android.accessibilityservice.AccessibilityService;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.stardust.scriptdroid.service.AccessibilityDelegate;
+
+import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.PAUSED;
+import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.RECORDING;
+import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.STOPPED;
+
+/**
+ * Created by Stardust on 2017/2/14.
+ */
+
+public class AccessibilityRecorderDelegate implements AccessibilityDelegate {
+
+ private static final int PRIORITY = 200;
+ private static final long RECORD_TIME_OUT = 10 * 60 * 1000;
+
+ private static AccessibilityRecorderDelegate instance;
+ private int mState = STOPPED;
+
+ public static AccessibilityRecorderDelegate getInstance() {
+ if (instance == null) {
+ instance = new AccessibilityRecorderDelegate();
+ }
+ return instance;
+ }
+
+ private ActionRecorder mRecorder = new ActionRecorder();
+ private long mRecordStartMillis;
+
+ public void startRecord() {
+ if (mState != STOPPED) {
+ throw new IllegalStateException("Recording");
+ }
+ mState = RECORDING;
+ mRecorder = new ActionRecorder();
+ mRecordStartMillis = System.currentTimeMillis();
+ }
+
+
+ public String stopRecord() {
+ if (mState == STOPPED) {
+ throw new IllegalStateException("Not recording");
+ }
+ mState = STOPPED;
+ String script = mRecorder.getScript();
+ mRecorder = null;
+ return script;
+ }
+
+
+ public void pauseRecord() {
+ if (mState != RECORDING) {
+ throw new IllegalStateException("Not recording");
+ }
+ mState = PAUSED;
+ }
+
+ public void resumeRecord() {
+ if (mState != PAUSED) {
+ throw new IllegalStateException("Not paused");
+ }
+ mRecorder.onResume();
+ mState = RECORDING;
+ }
+
+ public void stopRecordIfNeeded() {
+ if (mRecorder != null) {
+ mRecorder = null;
+ }
+ }
+
+ public int getState() {
+ return mState;
+ }
+
+ @Override
+ public boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event) {
+ if (mState == RECORDING) {
+ mRecorder.record(event);
+ checkTimeOut();
+ }
+ return false;
+ }
+
+ private void checkTimeOut() {
+ if (System.currentTimeMillis() - mRecordStartMillis > RECORD_TIME_OUT) {
+ stopRecord();
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/record/ActionRecorder.java b/app/src/main/java/com/stardust/scriptdroid/record/ActionRecorder.java
new file mode 100644
index 00000000..218106b5
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/record/ActionRecorder.java
@@ -0,0 +1,102 @@
+package com.stardust.scriptdroid.record;
+
+import android.os.Build;
+import android.util.SparseArray;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.stardust.util.SparseArrayEntries;
+
+import static com.stardust.scriptdroid.bounds_assist.BoundsAssistant.boundsToString;
+import static com.stardust.scriptdroid.bounds_assist.BoundsAssistant.getBoundsInScreen;
+
+
+/**
+ * Created by Stardust on 2017/2/14.
+ */
+
+public class ActionRecorder {
+
+ private static final SparseArray CONVERTER_MAP = new SparseArrayEntries()
+ .entry(AccessibilityEvent.TYPE_VIEW_CLICKED, new DoUtilSucceedConverter("click"))
+ .entry(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED, new DoUtilSucceedConverter("longClick"))
+ .entry(AccessibilityEvent.TYPE_VIEW_SCROLLED, new DoOnceConverter("//scroll???"))
+ .sparseArray();
+
+ static {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ CONVERTER_MAP.put(AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED, new DoOnceConverter("contextClick"));
+ }
+ }
+
+ private StringBuilder mScript = new StringBuilder();
+ private boolean mFirstAction = true;
+
+ public void record(AccessibilityEvent event) {
+ EventToScriptConverter converter = CONVERTER_MAP.get(event.getEventType());
+ if (converter != null) {
+ if (mFirstAction) {
+ mFirstAction = false;
+ return;
+ }
+ converter.onAccessibilityEvent(event, mScript);
+ mScript.append("\n");
+ }
+ }
+
+ public String getScript() {
+ return mScript.toString();
+ }
+
+ public void onResume() {
+ mFirstAction = true;
+ }
+
+ interface EventToScriptConverter {
+
+ void onAccessibilityEvent(AccessibilityEvent event, StringBuilder sb);
+ }
+
+ private static abstract class BoundsEventConverter implements EventToScriptConverter {
+
+ @Override
+ public void onAccessibilityEvent(AccessibilityEvent event, StringBuilder sb) {
+ AccessibilityNodeInfo source = event.getSource();
+ String bounds = boundsToString(getBoundsInScreen(source));
+ source.recycle();
+ onAccessibilityEvent(event, bounds, sb);
+ }
+
+ protected abstract void onAccessibilityEvent(AccessibilityEvent event, String bounds, StringBuilder sb);
+
+ }
+
+ private static class DoOnceConverter extends BoundsEventConverter {
+
+ private String mActionFunction;
+
+ DoOnceConverter(String actionFunction) {
+ mActionFunction = actionFunction;
+ }
+
+ @Override
+ protected void onAccessibilityEvent(AccessibilityEvent event, String bounds, StringBuilder sb) {
+ sb.append(mActionFunction).append(bounds).append(";");
+ }
+ }
+
+ private static class DoUtilSucceedConverter extends BoundsEventConverter {
+
+ private String mActionFunction;
+
+ DoUtilSucceedConverter(String actionFunction) {
+ mActionFunction = actionFunction;
+ }
+
+ @Override
+ protected void onAccessibilityEvent(AccessibilityEvent event, String bounds, StringBuilder sb) {
+ sb.append("while(!").append(mActionFunction).append(bounds).append(");");
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityDelegate.java b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityDelegate.java
new file mode 100644
index 00000000..cc26462f
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityDelegate.java
@@ -0,0 +1,14 @@
+package com.stardust.scriptdroid.service;
+
+import android.accessibilityservice.AccessibilityService;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Created by Stardust on 2017/2/14.
+ */
+
+public interface AccessibilityDelegate {
+
+ boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event);
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java
new file mode 100644
index 00000000..ce68959b
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/service/AccessibilityWatchDogService.java
@@ -0,0 +1,99 @@
+package com.stardust.scriptdroid.service;
+
+import android.accessibilityservice.AccessibilityService;
+import android.os.Build;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.stardust.scriptdroid.App;
+import com.stardust.view.accessibility.AccessibilityServiceUtils;
+
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Created by Stardust on 2017/2/14.
+ */
+
+public class AccessibilityWatchDogService extends AccessibilityService {
+
+ private static final String TAG = "AccessibilityWatchDog";
+
+ private static final SortedMap mDelegates = new TreeMap<>();
+ private static AccessibilityWatchDogService instance;
+
+ public static void addDelegate(AccessibilityDelegate delegate, int uniquePriority) {
+ synchronized (mDelegates) {
+ mDelegates.put(uniquePriority, delegate);
+ }
+ }
+
+ public static boolean containsPriority(int priority) {
+ synchronized (mDelegates) {
+ return mDelegates.containsKey(priority);
+ }
+ }
+
+ public static AccessibilityDelegate getDelegate(int priority) {
+ synchronized (mDelegates) {
+ return mDelegates.get(priority);
+ }
+ }
+
+ public static void addDelegateIfNeeded(int priority, Class extends AccessibilityDelegate> delegateClass) {
+ try {
+ addDelegateIfNeeded(priority, delegateClass.newInstance());
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void addDelegateIfNeeded(int priority, AccessibilityDelegate delegate) {
+ synchronized (mDelegates) {
+ if (!mDelegates.containsKey(priority)) {
+ mDelegates.put(priority, delegate);
+ }
+ }
+ }
+
+ public static boolean isEnable() {
+ return AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), AccessibilityWatchDogService.class);
+ }
+
+ public static AccessibilityWatchDogService getInstance() {
+ return instance;
+ }
+
+ @Override
+ public synchronized void onAccessibilityEvent(AccessibilityEvent event) {
+ Log.v(TAG, "onAccessibilityEvent: " + event);
+ synchronized (mDelegates) {
+ for (Map.Entry entry : mDelegates.entrySet()) {
+ if (entry.getValue().onAccessibilityEvent(this, event))
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onInterrupt() {
+ }
+
+ @Override
+ protected void onServiceConnected() {
+ super.onServiceConnected();
+ // FIXME: 2017/2/12 有时在无障碍中开启服务后这里不会调用服务也不会运行,安卓的BUG???
+ Log.v(TAG, "onServiceConnected");
+ instance = this;
+ }
+
+ public static void disable() {
+ if (instance != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ instance.disableSelf();
+ } else {
+ AccessibilityServiceUtils.goToAccessibilitySetting(App.getApp());
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java b/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java
index ca466657..0e23a223 100644
--- a/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java
+++ b/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java
@@ -47,4 +47,5 @@ public class IntentTool {
.putExtra(Intent.EXTRA_TEXT, text)
.setType("text/plain"));
}
+
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/BaseActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java
similarity index 97%
rename from app/src/main/java/com/stardust/scriptdroid/BaseActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java
index 392966aa..ddd5a6dd 100644
--- a/app/src/main/java/com/stardust/scriptdroid/BaseActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui;
import android.os.Build;
import android.os.Bundle;
@@ -9,6 +9,8 @@ import android.support.v7.widget.Toolbar;
import android.view.View;
+import com.stardust.scriptdroid.R;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/ConsoleActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleActivity.java
similarity index 95%
rename from app/src/main/java/com/stardust/scriptdroid/droid/ConsoleActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleActivity.java
index 91ac6910..37be7626 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/ConsoleActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/console/ConsoleActivity.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.droid;
+package com.stardust.scriptdroid.ui.console;
import android.content.Context;
import android.graphics.Color;
@@ -10,7 +10,7 @@ import android.view.MenuItem;
import android.widget.TextView;
import com.jraska.console.Console;
-import com.stardust.scriptdroid.BaseActivity;
+import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.R;
/**
diff --git a/app/src/main/java/com/stardust/scriptdroid/EditActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java
similarity index 95%
rename from app/src/main/java/com/stardust/scriptdroid/EditActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java
index 162c835e..b02cb855 100644
--- a/app/src/main/java/com/stardust/scriptdroid/EditActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.edit;
import android.content.Context;
import android.content.Intent;
@@ -18,12 +18,14 @@ import com.jecelyin.editor.v2.common.SaveListener;
import com.jecelyin.editor.v2.ui.EditorDelegate;
import com.jecelyin.editor.v2.view.EditorView;
import com.jecelyin.editor.v2.view.menu.MenuDef;
+import com.stardust.scriptdroid.Pref;
+import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.Droid;
-import com.stardust.scriptdroid.editor920.Editor920Activity;
-import com.stardust.scriptdroid.ui.AssistClipListRecyclerView;
-import com.stardust.scriptdroid.ui.EditSideMenuFragment;
-import com.stardust.scriptdroid.ui.FunctionListRecyclerView;
-import com.stardust.scriptdroid.widget.ToolbarMenuItem;
+import com.stardust.scriptdroid.ui.edit.sidemenu.AssistClipListRecyclerView;
+import com.stardust.scriptdroid.ui.edit.sidemenu.EditSideMenuFragment;
+import com.stardust.scriptdroid.ui.edit.sidemenu.FunctionListRecyclerView;
+import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity;
+import com.stardust.widget.ToolbarMenuItem;
import com.stardust.util.SparseArrayEntries;
import com.stardust.view.ViewBinder;
import com.stardust.view.ViewBinding;
diff --git a/app/src/main/java/com/stardust/scriptdroid/EditAndRunIntentActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditAndRunIntentActivity.java
similarity index 61%
rename from app/src/main/java/com/stardust/scriptdroid/EditAndRunIntentActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/edit/EditAndRunIntentActivity.java
index 87ab924c..9c786e44 100644
--- a/app/src/main/java/com/stardust/scriptdroid/EditAndRunIntentActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditAndRunIntentActivity.java
@@ -1,12 +1,13 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.edit;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
+import android.widget.Toast;
-import com.stardust.scriptdroid.BaseActivity;
-import com.stardust.scriptdroid.EditActivity;
+import com.stardust.scriptdroid.ui.BaseActivity;
+import com.stardust.scriptdroid.R;
/**
* Created by Stardust on 2017/2/2.
@@ -17,7 +18,12 @@ public class EditAndRunIntentActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- handleIntent();
+ try {
+ handleIntent();
+ } catch (Exception e) {
+ e.printStackTrace();
+ Toast.makeText(this, R.string.edit_and_run_handle_intent_error, Toast.LENGTH_LONG).show();
+ }
}
private void handleIntent() {
diff --git a/app/src/main/java/com/stardust/scriptdroid/ImportIntentActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/ImportIntentActivity.java
similarity index 90%
rename from app/src/main/java/com/stardust/scriptdroid/ImportIntentActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/edit/ImportIntentActivity.java
index 40d85391..e9efc9de 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ImportIntentActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/ImportIntentActivity.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.edit;
import android.content.Intent;
import android.os.Bundle;
@@ -7,8 +7,11 @@ import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.afollestad.materialdialogs.MaterialDialog;
+import com.stardust.scriptdroid.ui.BaseActivity;
+import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
+import com.stardust.scriptdroid.ui.main.MainActivity;
import java.io.File;
diff --git a/app/src/main/java/com/stardust/scriptdroid/editor920/Editor920Activity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor920/Editor920Activity.java
similarity index 96%
rename from app/src/main/java/com/stardust/scriptdroid/editor920/Editor920Activity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/edit/editor920/Editor920Activity.java
index 6cb40c7e..c8e464ab 100644
--- a/app/src/main/java/com/stardust/scriptdroid/editor920/Editor920Activity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor920/Editor920Activity.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.editor920;
+package com.stardust.scriptdroid.ui.edit.editor920;
import android.support.annotation.NonNull;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/AssistClipListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/AssistClipListRecyclerView.java
similarity index 94%
rename from app/src/main/java/com/stardust/scriptdroid/ui/AssistClipListRecyclerView.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/AssistClipListRecyclerView.java
index d353d9b4..25a60c2c 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/AssistClipListRecyclerView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/AssistClipListRecyclerView.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.ui.edit.sidemenu;
import android.bug.WrapContentLinearLayoutManager;
import android.content.Context;
@@ -11,9 +11,9 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.droid.assist.BoundsAssistClipList;
-import com.stardust.scriptdroid.droid.assist.SharedPrefBoundsAssistClipList;
-import com.stardust.scriptdroid.widget.ExpandableRecyclerView;
+import com.stardust.scriptdroid.bounds_assist.BoundsAssistClipList;
+import com.stardust.scriptdroid.bounds_assist.SharedPrefBoundsAssistClipList;
+import com.stardust.widget.ExpandableRecyclerView;
/**
* Created by Stardust on 2017/2/4.
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/EditSideMenuFragment.java
similarity index 81%
rename from app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/EditSideMenuFragment.java
index 53de771e..58b8a9ab 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/EditSideMenuFragment.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.ui.edit.sidemenu;
import android.content.Intent;
import android.os.Bundle;
@@ -10,14 +10,15 @@ import android.view.View;
import android.view.ViewGroup;
import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.DocumentActivity;
+import com.stardust.scriptdroid.ui.help.DocumentActivity;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.droid.ConsoleActivity;
-import com.stardust.scriptdroid.droid.assist.BoundsAssistant;
+import com.stardust.scriptdroid.ui.console.ConsoleActivity;
+import com.stardust.scriptdroid.bounds_assist.BoundsAssistant;
+import com.stardust.scriptdroid.external.notification.bounds_assist.BoundsAssistSwitchNotification;
import com.stardust.view.ViewBinder;
import com.stardust.view.ViewBinding;
-import static com.stardust.scriptdroid.ui.AssistModeSwitchNotification.KEY_ASSIST_MODE_NOTIFICATION;
+import static com.stardust.scriptdroid.external.notification.bounds_assist.BoundsAssistSwitchNotification.KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE;
/**
* Created by Stardust on 2017/2/4.
@@ -72,14 +73,14 @@ public class EditSideMenuFragment extends com.stardust.app.Fragment {
private void syncSwitchState() {
mAssistServiceSwitch.setChecked(BoundsAssistant.isAssistModeEnable());
- mAssistServiceNotificationSwitch.setChecked(AssistModeSwitchNotification.isEnable());
+ mAssistServiceNotificationSwitch.setChecked(BoundsAssistSwitchNotification.isEnable());
}
private void setUpSwitchCompat() {
mAssistServiceSwitch = $(R.id.sw_assist_service);
mAssistServiceNotificationSwitch = $(R.id.sw_assist_service_notification);
- App.getStateObserver().register(BoundsAssistant.KEY_ASSIST_MODE_ENABLE, mAssistServiceSwitch);
- App.getStateObserver().register(KEY_ASSIST_MODE_NOTIFICATION, mAssistServiceNotificationSwitch);
+ App.getStateObserver().register(BoundsAssistant.KEY_BOUNDS_ASSIST_ENABLE, mAssistServiceSwitch);
+ App.getStateObserver().register(KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE, mAssistServiceNotificationSwitch);
}
@ViewBinding.Click(R.id.syntax_and_api)
@@ -104,7 +105,7 @@ public class EditSideMenuFragment extends com.stardust.app.Fragment {
@ViewBinding.Check(R.id.sw_assist_service_notification)
private void setAssistServiceNotificationEnable(boolean enable) {
- AssistModeSwitchNotification.setEnable(enable);
+ BoundsAssistSwitchNotification.setEnable(enable);
}
@ViewBinding.Click(R.id.assist_service_notification)
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/FunctionListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/FunctionListRecyclerView.java
similarity index 97%
rename from app/src/main/java/com/stardust/scriptdroid/ui/FunctionListRecyclerView.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/FunctionListRecyclerView.java
index d205dadd..b54d1828 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/FunctionListRecyclerView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/FunctionListRecyclerView.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.ui.edit.sidemenu;
import android.bug.WrapContentLinearLayoutManager;
import android.content.Context;
@@ -13,7 +13,7 @@ import android.widget.TextView;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.file.FileUtils;
-import com.stardust.scriptdroid.widget.ExpandableRecyclerView;
+import com.stardust.widget.ExpandableRecyclerView;
import java.text.Collator;
import java.util.ArrayList;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ErrorReportActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/error/ErrorReportActivity.java
similarity index 97%
rename from app/src/main/java/com/stardust/scriptdroid/ErrorReportActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/error/ErrorReportActivity.java
index f2344df9..ef011c8b 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ErrorReportActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/error/ErrorReportActivity.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.error;
import android.content.ClipData;
import android.content.ClipboardManager;
@@ -13,6 +13,8 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
+import com.stardust.scriptdroid.ui.BaseActivity;
+import com.stardust.scriptdroid.R;
import java.util.Timer;
import java.util.TimerTask;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/error/IssueReportActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/error/IssueReportActivity.java
new file mode 100644
index 00000000..f7c90523
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/error/IssueReportActivity.java
@@ -0,0 +1,131 @@
+package com.stardust.scriptdroid.ui.error;
+
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.heinrichreimersoftware.androidissuereporter.IssueReporterActivity;
+import com.heinrichreimersoftware.androidissuereporter.model.github.GithubTarget;
+import com.stardust.scriptdroid.R;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Created by Stardust on 2017/2/13.
+ */
+
+public class IssueReportActivity extends IssueReporterActivity {
+
+
+ private boolean mCrash = false;
+ private Method mReportIssue, mValidateInput;
+ private boolean mReportFailed = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ handleIntent();
+ setUpToobar();
+ hookSendClick();
+ }
+
+ private void hookSendClick() {
+ FloatingActionButton send = (FloatingActionButton) this.findViewById(com.heinrichreimersoftware.androidissuereporter.R.id.air_buttonSend);
+ send.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ try {
+ reportIssue();
+ } catch (Exception e) {
+ mReportFailed = true;
+ e.printStackTrace();
+ finish();
+ }
+ }
+ });
+ }
+
+ private void setUpToobar() {
+ getSupportActionBar().setTitle(R.string.text_issue_report);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.air_toolbar);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+ }
+
+ private void handleIntent() {
+ final String errorDetail = getIntent().getStringExtra("error");
+ if (errorDetail != null) {
+ ((EditText) findViewById(R.id.air_inputDescription)).setText(errorDetail);
+ ((EditText) findViewById(R.id.air_inputTitle)).setText(R.string.text_crash_en);
+ mCrash = true;
+ }
+ }
+
+ private boolean validateInput() {
+ if (mValidateInput == null) {
+ try {
+ mValidateInput = IssueReporterActivity.class.getDeclaredMethod("validateInput");
+ mValidateInput.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ return mValidateInput != null && (Boolean) mValidateInput.invoke(this);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ private void reportIssue() {
+ if (mReportIssue == null) {
+ try {
+ mReportIssue = IssueReporterActivity.class.getDeclaredMethod("reportIssue");
+ mReportIssue.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ mReportIssue.invoke(this);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void finish() {
+ if (mCrash) {
+ if (!mReportFailed) {
+ Toast.makeText(IssueReportActivity.this, R.string.text_report_succeed, Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(IssueReportActivity.this, R.string.text_report_fail, Toast.LENGTH_SHORT).show();
+ }
+ finishAffinity();
+
+ } else {
+ super.finish();
+ }
+ }
+
+ @Override
+ protected GithubTarget getTarget() {
+ return new GithubTarget("hyb1996", "NoRootScriptDroid");
+ }
+
+ @Override
+ protected String getGuestToken() {
+ return "f32d789662645640ff22e240b80f5d76117181a1";
+ }
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/DocumentActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/help/DocumentActivity.java
similarity index 88%
rename from app/src/main/java/com/stardust/scriptdroid/DocumentActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/help/DocumentActivity.java
index 11162c53..d8ce9ad2 100644
--- a/app/src/main/java/com/stardust/scriptdroid/DocumentActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/help/DocumentActivity.java
@@ -1,11 +1,13 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.help;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.View;
+import com.stardust.scriptdroid.ui.BaseActivity;
+import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.file.FileUtils;
-import com.stardust.view.MarkdownView;
+import com.stardust.widget.MarkdownView;
/**
* Created by Stardust on 2017/2/1.
diff --git a/app/src/main/java/com/stardust/scriptdroid/MainActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java
similarity index 68%
rename from app/src/main/java/com/stardust/scriptdroid/MainActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java
index 5e763ef2..439d7cbf 100644
--- a/app/src/main/java/com/stardust/scriptdroid/MainActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java
@@ -1,8 +1,10 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.main;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
+import android.content.ClipData;
+import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -16,32 +18,41 @@ import android.support.v7.widget.Toolbar;
import android.text.InputType;
import android.view.View;
import android.widget.TextView;
+import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.folderselector.FileChooserDialog;
import com.stardust.app.NotRemindAgainDialog;
-import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
+import com.stardust.scriptdroid.BuildConfig;
+import com.stardust.scriptdroid.R;
+import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
+import com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchNotification;
import com.stardust.scriptdroid.file.FileUtils;
-import com.stardust.scriptdroid.file.SampleFileTool;
+import com.stardust.scriptdroid.file.SampleFileManager;
+import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.tool.BackPressedHandler;
-import com.stardust.scriptdroid.ui.ScriptFileOperation;
-import com.stardust.scriptdroid.ui.ScriptListRecyclerView;
-import com.stardust.scriptdroid.ui.SlideMenuFragment;
-import com.stardust.scriptdroid.ui.SlidingUpPanel;
+import com.stardust.scriptdroid.ui.BaseActivity;
+import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
+import com.stardust.scriptdroid.ui.settings.SettingsActivity;
import com.stardust.view.ViewBinder;
import com.stardust.view.ViewBinding;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
+import com.stardust.widget.SlidingUpPanel;
import java.io.File;
public class MainActivity extends BaseActivity implements FileChooserDialog.FileCallback {
+ private static final String EXTRA_ACTION = "EXTRA_ACTION";
+
public static final String ACTION_NOTIFY_SCRIPT_LIST_CHANGE = "ACTION_NOTIFY_SCRIPT_LIST_CHANGE";
+ private static final String ACTION_ON_ACTION_RECORD_STOPPED = "ACTION_ON_ACTION_RECORD_STOPPED";
+ private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT";
private SlidingUpPanel mAddFilePanel;
private ScriptListRecyclerView mScriptListRecyclerView;
@@ -55,6 +66,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
setUpUI();
checkPermissions();
registerReceivers();
+ handleIntent(getIntent());
}
private void registerReceivers() {
@@ -68,7 +80,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
}
private void goToAccessibilityPermissionSettingIfDisabled() {
- if (!AccessibilityServiceUtils.isAccessibilityServiceEnabled(this, ActionPerformService.class)) {
+ if (!AccessibilityServiceUtils.isAccessibilityServiceEnabled(this, ActionPerformAccessibilityDelegate.class)) {
new NotRemindAgainDialog.Builder(this, "goToAccessibilityPermissionSettingIfDisabled")
.title(R.string.text_alert)
.content(R.string.explain_accessibility_permission)
@@ -142,19 +154,29 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
@ViewBinding.Click(R.id.create_new_file)
private void createScriptFile() {
+ createScriptFileForScript(null);
+ }
+
+
+ private void createScriptFileForScript(final String script) {
new MaterialDialog.Builder(this).title(R.string.text_name)
.inputType(InputType.TYPE_CLASS_TEXT)
.input(getString(R.string.text_please_input_name), "", new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
String path = ScriptFile.DEFAULT_FOLDER + input + ".js";
- MainActivity.this.createScriptFile(input.toString(), path);
+ MainActivity.this.createScriptFile(input.toString(), path, script);
}
}).show();
}
- private void createScriptFile(String name, String path) {
+ private void createScriptFile(String name, String path, String script) {
if (FileUtils.createFileIfNotExists(path)) {
+ if (script != null) {
+ if (!FileUtils.writeString(path, script)) {
+ Snackbar.make(mDrawerLayout, R.string.text_file_write_fail, Snackbar.LENGTH_LONG).show();
+ }
+ }
addScriptFile(name, path);
new ScriptFileOperation.Edit().operate(mScriptListRecyclerView, mScriptFileList, mScriptFileList.size() - 1);
} else {
@@ -170,6 +192,16 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
.show();
}
+ @ViewBinding.Click(R.id.record)
+ private void startScriptRecord() {
+ if (AccessibilityWatchDogService.getInstance() == null) {
+ Snackbar.make(mDrawerLayout, R.string.text_need_enable_accessibility_service, Snackbar.LENGTH_SHORT).show();
+ return;
+ }
+ ActionRecordSwitchNotification.showOrUpdateNotification();
+ Snackbar.make(mDrawerLayout, R.string.hint_start_record, Snackbar.LENGTH_SHORT).show();
+ }
+
@ViewBinding.Click(R.id.setting)
private void startSettingActivity() {
startActivity(new Intent(this, SettingsActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
@@ -184,7 +216,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- SampleFileTool.getInstance().copySampleScriptFileIfNeeded();
+ SampleFileManager.getInstance().copySampleScriptFileIfNeeded();
mScriptListRecyclerView.getAdapter().notifyDataSetChanged();
}
}
@@ -194,6 +226,42 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
addScriptFile(file.getPath());
}
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ handleIntent(intent);
+ }
+
+ private void handleIntent(Intent intent) {
+ String action = intent.getStringExtra(EXTRA_ACTION);
+ if (action == null)
+ return;
+ switch (action) {
+ case ACTION_ON_ACTION_RECORD_STOPPED:
+ handleRecordedScript(intent.getStringExtra(ARGUMENT_SCRIPT));
+ break;
+ }
+ }
+
+ private void handleRecordedScript(final String script) {
+ new MaterialDialog.Builder(this)
+ .title(R.string.text_recorded)
+ .items(getString(R.string.text_new_file), getString(R.string.text_copy_to_clip))
+ .itemsCallback(new MaterialDialog.ListCallback() {
+ @Override
+ public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
+ if (position == 0) {
+ createScriptFileForScript(script);
+ } else {
+ ((ClipboardManager) getSystemService(CLIPBOARD_SERVICE))
+ .setPrimaryClip(ClipData.newPlainText("script", script));
+ Toast.makeText(MainActivity.this, R.string.text_already_copy_to_clip, Toast.LENGTH_SHORT).show();
+ }
+ }
+ })
+ .show();
+
+ }
private BackPressedHandler mBackPressedHandler = new BackPressedHandler.DoublePressExit(this);
@@ -214,6 +282,14 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
unregisterReceiver(mReceiver);
}
+ public static void onActionRecordStopped(Context context, String script) {
+ Intent intent = new Intent(context, MainActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
+ .putExtra(EXTRA_ACTION, ACTION_ON_ACTION_RECORD_STOPPED)
+ .putExtra(ARGUMENT_SCRIPT, script);
+ context.startActivity(intent);
+ }
+
private class Receiver extends BroadcastReceiver {
@Override
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/ScriptListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/ScriptListRecyclerView.java
similarity index 95%
rename from app/src/main/java/com/stardust/scriptdroid/ui/ScriptListRecyclerView.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/main/ScriptListRecyclerView.java
index 1be60a6e..160c68b4 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/ScriptListRecyclerView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/ScriptListRecyclerView.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.ui.main;
import android.content.Context;
import android.os.Environment;
@@ -16,11 +16,13 @@ import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
+import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
+import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperationPopupMenu;
import com.stardust.scriptdroid.tool.ClassTool;
import static com.stardust.scriptdroid.tool.ViewTool.$;
-import static com.stardust.scriptdroid.ui.ScriptFileOperation.*;
+import static com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation.*;
/**
* Created by Stardust on 2017/1/23.
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java
similarity index 77%
rename from app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java
index 59a7ae86..f3a5a1cd 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.ui.main;
import android.content.Intent;
import android.os.Bundle;
@@ -12,17 +12,18 @@ import android.view.ViewGroup;
import com.stardust.app.Fragment;
import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.DocumentActivity;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.droid.ConsoleActivity;
+import com.stardust.scriptdroid.bounds_assist.BoundsAssistant;
import com.stardust.scriptdroid.droid.Droid;
-import com.stardust.scriptdroid.droid.assist.BoundsAssistant;
-import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
+import com.stardust.scriptdroid.external.notification.bounds_assist.BoundsAssistSwitchNotification;
+import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
+import com.stardust.scriptdroid.ui.console.ConsoleActivity;
+import com.stardust.scriptdroid.ui.help.DocumentActivity;
import com.stardust.view.ViewBinder;
import com.stardust.view.ViewBinding;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
-import static com.stardust.scriptdroid.ui.AssistModeSwitchNotification.KEY_ASSIST_MODE_NOTIFICATION;
+import static com.stardust.scriptdroid.external.notification.bounds_assist.BoundsAssistSwitchNotification.KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE;
/**
* Created by Stardust on 2017/1/30.
@@ -59,19 +60,19 @@ public class SlideMenuFragment extends Fragment {
mAutoOperateServiceSwitch.postDelayed(new Runnable() {
@Override
public void run() {
- mAutoOperateServiceSwitch.setChecked(ActionPerformService.isEnable());
+ mAutoOperateServiceSwitch.setChecked(AccessibilityWatchDogService.isEnable());
}
}, 450);
mAssistServiceSwitch.setChecked(BoundsAssistant.isAssistModeEnable());
- mAssistServiceNotificationSwitch.setChecked(AssistModeSwitchNotification.isEnable());
+ mAssistServiceNotificationSwitch.setChecked(BoundsAssistSwitchNotification.isEnable());
}
private void setUpSwitchCompat() {
mAutoOperateServiceSwitch = $(R.id.sw_auto_operate_service);
mAssistServiceSwitch = $(R.id.sw_assist_service);
mAssistServiceNotificationSwitch = $(R.id.sw_assist_service_notification);
- App.getStateObserver().register(BoundsAssistant.KEY_ASSIST_MODE_ENABLE, mAssistServiceSwitch);
- App.getStateObserver().register(KEY_ASSIST_MODE_NOTIFICATION, mAssistServiceNotificationSwitch);
+ App.getStateObserver().register(BoundsAssistant.KEY_BOUNDS_ASSIST_ENABLE, mAssistServiceSwitch);
+ App.getStateObserver().register(KEY_BOUNDS_ASSIST_SWITCH_NOTIFICATION_ENABLE, mAssistServiceNotificationSwitch);
}
@@ -92,10 +93,10 @@ public class SlideMenuFragment extends Fragment {
@ViewBinding.Check(R.id.sw_auto_operate_service)
private void setAutoOperateServiceEnable(boolean enable) {
- if (enable && !ActionPerformService.isEnable()) {
+ if (enable && !AccessibilityWatchDogService.isEnable()) {
AccessibilityServiceUtils.goToAccessibilitySetting(getContext());
- } else if (!enable && ActionPerformService.isEnable()) {
- ActionPerformService.disable();
+ } else if (!enable && AccessibilityWatchDogService.isEnable()) {
+ AccessibilityWatchDogService.disable();
}
}
@@ -111,7 +112,7 @@ public class SlideMenuFragment extends Fragment {
@ViewBinding.Check(R.id.sw_assist_service_notification)
private void setAssistServiceNotificationEnable(boolean enable) {
- AssistModeSwitchNotification.setEnable(enable);
+ BoundsAssistSwitchNotification.setEnable(enable);
}
@ViewBinding.Click(R.id.assist_service_notification)
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/ScriptFileOperation.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java
similarity index 95%
rename from app/src/main/java/com/stardust/scriptdroid/ui/ScriptFileOperation.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java
index 6b8aa56d..906e64ed 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/ScriptFileOperation.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.ui.main.operation;
import android.content.Context;
import android.content.Intent;
@@ -8,12 +8,13 @@ import android.support.design.widget.Snackbar;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.App;
-import com.stardust.scriptdroid.EditActivity;
+import com.stardust.scriptdroid.ui.edit.EditActivity;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.ShortcutActivity;
+import com.stardust.scriptdroid.external.shortcut.ShortcutActivity;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
-import com.stardust.scriptdroid.shortcut.Shortcut;
+import com.stardust.scriptdroid.external.shortcut.Shortcut;
+import com.stardust.scriptdroid.ui.main.ScriptListRecyclerView;
import java.util.ArrayList;
import java.util.List;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/ScriptFileOperationPopupMenu.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperationPopupMenu.java
similarity index 98%
rename from app/src/main/java/com/stardust/scriptdroid/ui/ScriptFileOperationPopupMenu.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperationPopupMenu.java
index 5a180705..95d8ec53 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/ScriptFileOperationPopupMenu.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperationPopupMenu.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.scriptdroid.ui.main.operation;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
diff --git a/app/src/main/java/com/stardust/scriptdroid/AboutActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/settings/AboutActivity.java
similarity index 79%
rename from app/src/main/java/com/stardust/scriptdroid/AboutActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/settings/AboutActivity.java
index b689292f..abee66e3 100644
--- a/app/src/main/java/com/stardust/scriptdroid/AboutActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/settings/AboutActivity.java
@@ -1,16 +1,21 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.settings;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
+import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
+import com.stardust.scriptdroid.ui.BaseActivity;
+import com.stardust.scriptdroid.BuildConfig;
+import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.tool.IntentTool;
import com.stardust.view.ViewBinder;
import com.stardust.view.ViewBinding;
@@ -23,6 +28,8 @@ import moe.feng.alipay.zerosdk.AlipayZeroSdk;
public class AboutActivity extends BaseActivity {
+ private int mLolClickCount = 0;
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -61,6 +68,7 @@ public class AboutActivity extends BaseActivity {
@ViewBinding.Click(R.id.qq)
private void openQQToChatWithMe() {
+ Toast.makeText(this, R.string.text_qq_group_id_copied, Toast.LENGTH_SHORT).show();
String qq = getString(R.string.qq);
IntentTool.goToQQ(this, qq);
}
@@ -99,7 +107,19 @@ public class AboutActivity extends BaseActivity {
@ViewBinding.Click(R.id.icon)
private void lol() {
+ mLolClickCount++;
Toast.makeText(this, R.string.text_lll, Toast.LENGTH_LONG).show();
+ if (mLolClickCount >= 5) {
+ new MaterialDialog.Builder(this)
+ .title("Crash Test")
+ .positiveText("Crash")
+ .onPositive(new MaterialDialog.SingleButtonCallback() {
+ @Override
+ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
+ throw new RuntimeException("Crash Test");
+ }
+ }).show();
+ }
}
@ViewBinding.Click(R.id.developer)
diff --git a/app/src/main/java/com/stardust/scriptdroid/SettingsActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/settings/SettingsActivity.java
similarity index 74%
rename from app/src/main/java/com/stardust/scriptdroid/SettingsActivity.java
rename to app/src/main/java/com/stardust/scriptdroid/ui/settings/SettingsActivity.java
index 9ed0a72a..6d48b335 100644
--- a/app/src/main/java/com/stardust/scriptdroid/SettingsActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/settings/SettingsActivity.java
@@ -1,5 +1,7 @@
-package com.stardust.scriptdroid;
+package com.stardust.scriptdroid.ui.settings;
+import android.content.ClipData;
+import android.content.ClipboardManager;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
@@ -9,7 +11,11 @@ import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;
-import com.stardust.scriptdroid.file.SampleFileTool;
+import com.stardust.scriptdroid.R;
+import com.stardust.scriptdroid.file.SampleFileManager;
+import com.stardust.scriptdroid.ui.BaseActivity;
+import com.stardust.scriptdroid.ui.error.IssueReportActivity;
+import com.stardust.scriptdroid.ui.main.MainActivity;
import com.stardust.util.MapEntries;
import java.util.Map;
@@ -66,7 +72,7 @@ public class SettingsActivity extends BaseActivity {
.entry(getString(R.string.text_re_import_samples), new Runnable() {
@Override
public void run() {
- int failCount = SampleFileTool.getInstance().copySampleScriptFile();
+ int failCount = SampleFileManager.getInstance().copySampleScriptFile();
if (failCount <= 0) {
Toast.makeText(getActivity(), R.string.text_re_import_succeed, Toast.LENGTH_SHORT).show();
notifyScriptListChanged();
@@ -74,6 +80,19 @@ public class SettingsActivity extends BaseActivity {
Toast.makeText(getActivity(), R.string.text_fail, Toast.LENGTH_SHORT).show();
}
})
+ .entry(getString(R.string.text_issue_report), new Runnable() {
+ @Override
+ public void run() {
+ startActivity(new Intent(getActivity(), IssueReportActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
+ })
+ .entry(getString(R.string.text_join_qq_group), new Runnable() {
+ @Override
+ public void run() {
+ ((ClipboardManager) getActivity().getSystemService(CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("qq", "556928653"));
+ Toast.makeText(getActivity(), R.string.text_qq_group_id_copied, Toast.LENGTH_SHORT).show();
+ }
+ })
.entry(getString(R.string.text_about), new Runnable() {
@Override
public void run() {
diff --git a/app/src/main/java/com/stardust/util/StateObserver.java b/app/src/main/java/com/stardust/util/StateObserver.java
index eb60f56b..35aa469a 100644
--- a/app/src/main/java/com/stardust/util/StateObserver.java
+++ b/app/src/main/java/com/stardust/util/StateObserver.java
@@ -15,30 +15,18 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class StateObserver {
- public interface OnStateChangedListener {
+ public interface OnStateChangedListener {
- void onStateChanged(T newState);
+ void onStateChanged(boolean newState);
- void initState(T state);
+ void initState(boolean state);
}
- public static abstract class SimpleOnStateChangedListener implements OnStateChangedListener {
+ public static abstract class SimpleOnStateChangedListener implements OnStateChangedListener {
@Override
- public void initState(T state) {
- onStateChanged(state);
- }
- }
-
- public interface OnBooleanStateChangedListener extends OnStateChangedListener {
-
- }
-
- public static abstract class SimpleOnBooleanStateChangedListener implements OnBooleanStateChangedListener {
-
- @Override
- public void initState(Boolean state) {
+ public void initState(boolean state) {
onStateChanged(state);
}
}
@@ -53,9 +41,9 @@ public class StateObserver {
public void register(final String key, SwitchCompat switchCompat) {
final WeakReference switchCompatWeakReference = new WeakReference<>(switchCompat);
- register(key, new SimpleOnBooleanStateChangedListener() {
+ register(key, new SimpleOnStateChangedListener() {
@Override
- public void onStateChanged(Boolean newState) {
+ public void onStateChanged(boolean newState) {
if (switchCompatWeakReference.get() != null) {
switchCompatWeakReference.get().setChecked(newState);
} else {
@@ -65,10 +53,8 @@ public class StateObserver {
});
}
- public void register(String key, OnStateChangedListener listener) {
- T initialState = readState(key, listener);
- if (initialState != null)
- listener.initState(initialState);
+ public void register(String key, OnStateChangedListener listener) {
+ initState(key, listener);
synchronized (mKeyStateListenersMap) {
List listeners = getListenerListOrCreateIfNotExists(key);
listeners.add(listener);
@@ -76,7 +62,7 @@ public class StateObserver {
}
- private void unregister(String key, OnStateChangedListener stateChangedListener) {
+ private void unregister(String key, OnStateChangedListener stateChangedListener) {
synchronized (mKeyStateListenersMap) {
List listeners = mKeyStateListenersMap.get(key);
if (listeners == null) {
@@ -86,15 +72,13 @@ public class StateObserver {
}
}
- public void setState(String key, T state) {
+ public void setState(String key, boolean state) {
synchronized (mKeyStateListenersMap) {
List listeners = mKeyStateListenersMap.get(key);
if (listeners == null || listeners.isEmpty())
return;
- if (listeners.get(0) instanceof OnBooleanStateChangedListener) {
- mSharedPreferences.edit().putBoolean(key, (Boolean) state).apply();
- notifyBooleanStateChanged(listeners, (Boolean) state);
- }
+ mSharedPreferences.edit().putBoolean(key, state).apply();
+ notifyBooleanStateChanged(listeners, state);
}
}
@@ -104,12 +88,10 @@ public class StateObserver {
}
}
- @SuppressWarnings("unchecked")
- protected T readState(String key, OnStateChangedListener listener) {
- if (listener instanceof OnBooleanStateChangedListener) {
- return mSharedPreferences.contains(key) ? (T) Boolean.valueOf(mSharedPreferences.getBoolean(key, false)) : null;
+ private void initState(String key, OnStateChangedListener listener) {
+ if (mSharedPreferences.contains(key)) {
+ listener.initState(mSharedPreferences.getBoolean(key, false));
}
- return null;
}
private List getListenerListOrCreateIfNotExists(String key) {
diff --git a/app/src/main/java/com/stardust/util/function/ArrayOptional.java b/app/src/main/java/com/stardust/util/function/ArrayOptional.java
deleted file mode 100644
index f0d74de6..00000000
--- a/app/src/main/java/com/stardust/util/function/ArrayOptional.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.stardust.util.function;
-
-/**
- * Created by Stardust on 2017/1/24.
- */
-
-public class ArrayOptional {
-}
diff --git a/app/src/main/java/com/stardust/util/function/Domino.java b/app/src/main/java/com/stardust/util/function/Domino.java
deleted file mode 100644
index a19c0c16..00000000
--- a/app/src/main/java/com/stardust/util/function/Domino.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.stardust.util.function;
-
-/**
- * Created by Stardust on 2017/1/26.
- */
-
-public class Domino {
-}
diff --git a/app/src/main/java/com/stardust/util/function/FunctionTool.java b/app/src/main/java/com/stardust/util/function/FunctionTool.java
deleted file mode 100644
index 914f3002..00000000
--- a/app/src/main/java/com/stardust/util/function/FunctionTool.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.stardust.util.function;
-
-import android.support.annotation.RequiresApi;
-
-import java.util.Optional;
-import java.util.function.Consumer;
-
-/**
- * Created by Stardust on 2017/1/24.
- */
-
-public class FunctionTool {
-
-
-}
diff --git a/app/src/main/java/com/stardust/util/function/ListTool.java b/app/src/main/java/com/stardust/util/function/ListTool.java
deleted file mode 100644
index 6e311d04..00000000
--- a/app/src/main/java/com/stardust/util/function/ListTool.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.stardust.util.function;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by Stardust on 2017/1/26.
- */
-
-public class ListTool {
-
- @FunctionalInterface
- public interface ChildSupplier {
- T getChild(int i);
- }
-
- public static List toList(ChildSupplier supplier, int size) {
- ArrayList arrayList = new ArrayList(size);
- for (int i = 0; i < size - 1; i++) {
- arrayList.add(supplier.getChild(i));
- }
- return arrayList;
- }
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/widget/ExpandableRecyclerView.java b/app/src/main/java/com/stardust/widget/ExpandableRecyclerView.java
similarity index 99%
rename from app/src/main/java/com/stardust/scriptdroid/widget/ExpandableRecyclerView.java
rename to app/src/main/java/com/stardust/widget/ExpandableRecyclerView.java
index a2c5bcac..b8c130cc 100644
--- a/app/src/main/java/com/stardust/scriptdroid/widget/ExpandableRecyclerView.java
+++ b/app/src/main/java/com/stardust/widget/ExpandableRecyclerView.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.widget;
+package com.stardust.widget;
import android.content.Context;
import android.support.annotation.Nullable;
diff --git a/app/src/main/java/com/stardust/view/MarkdownView.java b/app/src/main/java/com/stardust/widget/MarkdownView.java
similarity index 98%
rename from app/src/main/java/com/stardust/view/MarkdownView.java
rename to app/src/main/java/com/stardust/widget/MarkdownView.java
index bb94c9e0..83ab3222 100644
--- a/app/src/main/java/com/stardust/view/MarkdownView.java
+++ b/app/src/main/java/com/stardust/widget/MarkdownView.java
@@ -1,4 +1,4 @@
-package com.stardust.view;
+package com.stardust.widget;
import android.content.Context;
import android.os.Build;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/SlidingUpPanel.java b/app/src/main/java/com/stardust/widget/SlidingUpPanel.java
similarity index 98%
rename from app/src/main/java/com/stardust/scriptdroid/ui/SlidingUpPanel.java
rename to app/src/main/java/com/stardust/widget/SlidingUpPanel.java
index 60cb63e0..366efac0 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/SlidingUpPanel.java
+++ b/app/src/main/java/com/stardust/widget/SlidingUpPanel.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.ui;
+package com.stardust.widget;
import android.annotation.TargetApi;
import android.content.Context;
diff --git a/app/src/main/java/com/stardust/scriptdroid/widget/ToolbarMenuItem.java b/app/src/main/java/com/stardust/widget/ToolbarMenuItem.java
similarity index 98%
rename from app/src/main/java/com/stardust/scriptdroid/widget/ToolbarMenuItem.java
rename to app/src/main/java/com/stardust/widget/ToolbarMenuItem.java
index d4cee21b..526d3c4a 100644
--- a/app/src/main/java/com/stardust/scriptdroid/widget/ToolbarMenuItem.java
+++ b/app/src/main/java/com/stardust/widget/ToolbarMenuItem.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.widget;
+package com.stardust.widget;
import android.annotation.TargetApi;
import android.content.Context;
diff --git a/app/src/main/res/drawable/btn_selector.xml b/app/src/main/res/drawable/btn_selector.xml
new file mode 100644
index 00000000..4522c99d
--- /dev/null
+++ b/app/src/main/res/drawable/btn_selector.xml
@@ -0,0 +1,11 @@
+
+
+
+ -
+
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_pause_gray_48dp.png b/app/src/main/res/drawable/ic_pause_gray_48dp.png
new file mode 100644
index 00000000..f4511e63
Binary files /dev/null and b/app/src/main/res/drawable/ic_pause_gray_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_pause_grey600_48dp.png b/app/src/main/res/drawable/ic_pause_grey600_48dp.png
new file mode 100644
index 00000000..dc9d1740
Binary files /dev/null and b/app/src/main/res/drawable/ic_pause_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_play_arrow_black_48dp.png b/app/src/main/res/drawable/ic_play_arrow_black_48dp.png
new file mode 100644
index 00000000..f208795f
Binary files /dev/null and b/app/src/main/res/drawable/ic_play_arrow_black_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_play_arrow_gray_48dp.png b/app/src/main/res/drawable/ic_play_arrow_gray_48dp.png
new file mode 100644
index 00000000..308ef810
Binary files /dev/null and b/app/src/main/res/drawable/ic_play_arrow_gray_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_play_arrow_grey600_48dp.png b/app/src/main/res/drawable/ic_play_arrow_grey600_48dp.png
new file mode 100644
index 00000000..bcffe663
Binary files /dev/null and b/app/src/main/res/drawable/ic_play_arrow_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_stop_black_36dp.png b/app/src/main/res/drawable/ic_stop_black_36dp.png
new file mode 100644
index 00000000..75f47c1b
Binary files /dev/null and b/app/src/main/res/drawable/ic_stop_black_36dp.png differ
diff --git a/app/src/main/res/drawable/ic_stop_grey600_48dp.png b/app/src/main/res/drawable/ic_stop_grey600_48dp.png
new file mode 100644
index 00000000..e65afc8b
Binary files /dev/null and b/app/src/main/res/drawable/ic_stop_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_stop_white_36pt.png b/app/src/main/res/drawable/ic_stop_white_36pt.png
new file mode 100644
index 00000000..dfff26ce
Binary files /dev/null and b/app/src/main/res/drawable/ic_stop_white_36pt.png differ
diff --git a/app/src/main/res/drawable/ic_video_record.png b/app/src/main/res/drawable/ic_video_record.png
new file mode 100644
index 00000000..7fa29e20
Binary files /dev/null and b/app/src/main/res/drawable/ic_video_record.png differ
diff --git a/app/src/main/res/layout/activity_console.xml b/app/src/main/res/layout/activity_console.xml
index 63f49626..ec382631 100644
--- a/app/src/main/res/layout/activity_console.xml
+++ b/app/src/main/res/layout/activity_console.xml
@@ -22,7 +22,7 @@
diff --git a/app/src/main/res/layout/activity_document.xml b/app/src/main/res/layout/activity_document.xml
index d3588f4c..b7dd0018 100644
--- a/app/src/main/res/layout/activity_document.xml
+++ b/app/src/main/res/layout/activity_document.xml
@@ -26,7 +26,7 @@
-
+ tools:context=".ui.edit.EditActivity">
-
-
-
-
+ tools:context=".ui.main.MainActivity">
-
@@ -107,9 +107,35 @@
+
+
+
+
+
+
+
+
+
-
+
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml
index f7053878..b0b2123e 100644
--- a/app/src/main/res/layout/content_main.xml
+++ b/app/src/main/res/layout/content_main.xml
@@ -7,11 +7,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
- tools:context="com.stardust.scriptdroid.MainActivity"
+ tools:context=".ui.main.MainActivity"
tools:showIn="@layout/activity_main">
-
diff --git a/app/src/main/res/layout/fragment_edit_side_menu.xml b/app/src/main/res/layout/fragment_edit_side_menu.xml
index cdf80b5d..43656582 100644
--- a/app/src/main/res/layout/fragment_edit_side_menu.xml
+++ b/app/src/main/res/layout/fragment_edit_side_menu.xml
@@ -116,12 +116,12 @@
-
-
diff --git a/app/src/main/res/layout/remote_views_record_switch.xml b/app/src/main/res/layout/remote_views_record_switch.xml
new file mode 100644
index 00000000..0d06f376
--- /dev/null
+++ b/app/src/main/res/layout/remote_views_record_switch.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/script_file_operation_popup_menu_content.xml b/app/src/main/res/layout/script_file_operation_popup_menu_content.xml
index b7dff679..d5497aff 100644
--- a/app/src/main/res/layout/script_file_operation_popup_menu_content.xml
+++ b/app/src/main/res/layout/script_file_operation_popup_menu_content.xml
@@ -8,7 +8,7 @@
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
index 158eefea..ae9a1e4a 100644
--- a/app/src/main/res/menu/menu_main.xml
+++ b/app/src/main/res/menu/menu_main.xml
@@ -1,6 +1,6 @@
diff --git a/app/src/main/res/raw/document.md b/app/src/main/res/raw/document.md
index bfc151c8..f0d6f222 100644
--- a/app/src/main/res/raw/document.md
+++ b/app/src/main/res/raw/document.md
@@ -25,6 +25,18 @@
* `notStopped` 若当前脚本处于运行状态时返回`true`, 否则返回`false`。对于某些循环, 例如`while(true)`,请用`while(notStopped())`代替,以免死循环造成的脚本无法正常停止。
* `isStoppd` 若当前脚本处于停止状态时返回`true`, 否则返回`false`。
* `shell(cmd, root=false)` 执行shell命令cmd, 其中参数root表示是否以root权限执行,默认为false。例如`shell("input keyevent 26", true); //锁屏`。
+* `getTexts()` 获取屏幕上的文字列表, 返回一个java.util.List。例如:
+
+```
+launchApp("微信");
+while(!click("通讯录"));
+var texts = getTexts();
+for(var i = 0; i < texts.size(); i++){
+ log(texts.get(i));
+}
+openConsole();
+```
+
###四、全局变量
* `context` ApplicationContext,参见安卓[android.content.Context](https://developer.android.com/reference/android/content/Context.html)
> 这里的context由于是ApplicationContext,是不可见的,不能用于dialog和其他UI相关。如果要显示弹窗或者视图,请启动UI模式(代码的第一行为`"ui";`既可)并使用activity代替。
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
new file mode 100644
index 00000000..989696d8
--- /dev/null
+++ b/app/src/main/res/values-zh/strings.xml
@@ -0,0 +1,36 @@
+
+ 错误报告
+
+ 问题
+ 登录
+
+ 标题
+ 描述
+ 设备信息
+
+ 使用Github账号发送
+ 使用Email发送
+ 匿名发送
+ 用户名
+ 密码
+ 邮箱
+ 联系邮箱 (选填)
+
+ 请输入问题
+ 请输入详细描述
+ 请输入有效的Github用户名
+ 请输入正确的密码
+ 请输入邮箱
+
+ 正在上传到GitHub…
+ 无法发送错误报告
+ 错误的用户名或密码
+ 无效的access token. 请联系软件开发者.
+ Issues不可用,请联系软件开发者.
+ 未知错误
+ OK
+
+ - 描述至少要 %d 个字.
+ - 描述至少要 %d 个字.
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9687e2a5..e40a415b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -99,4 +99,20 @@
Bug Report
提交失败
提交成功
+ 无法处理文件
+ Crash
+ 问题反馈
+ 录制脚本
+ 在通知栏中开始录制
+ 开始录制
+ 停止录制
+ 录制未开始
+ 暂停录制
+ 继续录制
+ 录制结束
+ 复制到剪贴板
+ 文件写入失败
+ 需要打开\"自动操作服务“才能录制脚本
+ 加入QQ交流群
+ 已复制群号到剪贴板
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index b688da75..3090281e 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -11,6 +11,12 @@
+
+
+
+
diff --git a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java
index 86168640..18923ec6 100644
--- a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java
+++ b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java
@@ -2,6 +2,11 @@ package com.stardust.scriptdroid;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
/**
* Example local unit test, which will execute on the development machine (host).
*
@@ -9,7 +14,70 @@ import org.junit.Test;
*/
public class ExampleUnitTest {
@Test
- public void testStack() throws Exception {
+ public void testSync() throws Exception {
+ final Sync sync = new Sync();
+ //sync.print(11);
+ add(sync, 11, 123);
+ //Thread.sleep(1);
+ sync.print(11);
+ add(sync, 11, 456);
+ sync.print(11);
+ }
+ private void add(final Sync sync, final int key, final int i) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ sync.add(key, i);
+ }
+ }).start();
+ }
+
+ private static class Sync {
+
+ private final Map> mMap = new TreeMap<>();
+
+ Sync() {
+ for (int i = 0; i < 10; i++) {
+ List list = new ArrayList<>();
+ for (int j = 0; j < 10; j++) {
+ list.add(j * i);
+ }
+ mMap.put(i, list);
+ }
+ }
+
+ public Sync add(int key, int i) {
+ synchronized (mMap) {
+ List list = ensureList(key);
+ list.add(i);
+ System.out.println("add:" + key + " " + i);
+ }
+ return this;
+ }
+
+ private List ensureList(int key) {
+ List list = mMap.get(key);
+ if (list == null) {
+ list = new ArrayList<>();
+ mMap.put(key, list);
+ }
+ return list;
+ }
+
+ public void print(int key) {
+ synchronized (mMap) {
+ List list = mMap.get(key);
+ System.out.print(key + ":");
+ if (list == null) {
+ System.out.print("null");
+ } else {
+ for (Integer i : list) {
+ System.out.print(i + " ");
+ }
+ }
+ System.out.println();
+ }
+ }
}
}
\ No newline at end of file