diff --git a/app/build.gradle b/app/build.gradle
index bf8037ff..0b633908 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "com.stardust.scriptdroid"
minSdkVersion 19
targetSdkVersion 23
- versionCode 10
- versionName "0.17.02050预览版"
+ versionCode 20
+ versionName "1.17.0212"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -46,6 +46,8 @@ dependencies {
compile 'com.furture.react:DuktapeJava:1.1.0'
compile 'com.zzhoujay.markdown:markdown:1.0.2'
compile 'moe.feng:AlipayZeroSdk:1.1'
+ compile 'com.jraska:console:0.4.3'
+ compile 'com.jraska:console-timber-tree:0.4.3'
compile files('libs/JSTransformer.jar')
@@ -57,5 +59,4 @@ dependencies {
compile(name:'920-file_explorer-release', ext:'aar')
compile(name:'920-app-debug', ext:'aar')
-
}
diff --git a/app/libs/mutable-theme-debug.aar b/app/libs/mutable-theme-debug.aar
new file mode 100644
index 00000000..1fb7af45
Binary files /dev/null and b/app/libs/mutable-theme-debug.aar differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 814361a2..e6b0d4cf 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -75,6 +75,7 @@
+
diff --git a/app/src/main/assets/javasccript_engine_init.js b/app/src/main/assets/javasccript_engine_init.js
index efc5525d..08f46a6b 100644
--- a/app/src/main/assets/javasccript_engine_init.js
+++ b/app/src/main/assets/javasccript_engine_init.js
@@ -42,6 +42,8 @@ var longClick = function(a, b, c, d){
var scrollUp = function(a, b, c, d){
if(arguments.length == 0)
return droid.scrollAllUp();
+ if(arguments.length == 1 && typeof a === 'number')
+ return droid.scrollUp(a);
return performAction(function(target){
return droid.scrollUp(target);
}, arguments);
@@ -49,8 +51,10 @@ var scrollUp = function(a, b, c, d){
var scrollDown = function(a, b, c, d){
if(arguments.length == 0)
- return droid.scrollAllDown();
- return performAction(function(target){
+ return droid.scrollAllDown();
+ if(arguments.length == 1 && typeof a === 'number')
+ return droid.scrollDown(a);
+ return performAction(function(target){
return droid.scrollDown(target);
}, arguments);
}
@@ -97,3 +101,18 @@ var notStopped = function(){
return !isStopped();
}
+var log = function(str){
+ droid.log(str);
+}
+
+var err = function(e){
+ droid.err(e);
+}
+
+var openConsole = function(){
+ droid.console();
+}
+
+var clearConsole = function(){
+ droid.clearConsole();
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/stardust/scriptdroid/BaseActivity.java b/app/src/main/java/com/stardust/scriptdroid/BaseActivity.java
index c29b14e5..392966aa 100644
--- a/app/src/main/java/com/stardust/scriptdroid/BaseActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/BaseActivity.java
@@ -1,10 +1,14 @@
package com.stardust.scriptdroid;
import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
import android.view.View;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -18,9 +22,13 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class BaseActivity extends AppCompatActivity {
-
protected static final int PERMISSION_REQUEST_CODE = 11186;
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
@SuppressWarnings("unchecked")
public T $(int resId) {
return (T) findViewById(resId);
@@ -49,4 +57,18 @@ public class BaseActivity extends AppCompatActivity {
return list.toArray(new String[list.size()]);
}
+ public void setToolbarAsBack(String title) {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ toolbar.setTitle(title);
+ setSupportActionBar(toolbar);
+ if (getSupportActionBar() != null) {
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+ }
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/MainActivity.java b/app/src/main/java/com/stardust/scriptdroid/MainActivity.java
index 37411b4f..c9f38170 100644
--- a/app/src/main/java/com/stardust/scriptdroid/MainActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/MainActivity.java
@@ -94,6 +94,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
setUpToolbar();
setUpScriptList();
ViewBinder.bind(this);
+
}
private void setUpToolbar() {
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/ConsoleActivity.java b/app/src/main/java/com/stardust/scriptdroid/droid/ConsoleActivity.java
new file mode 100644
index 00000000..91ac6910
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/ConsoleActivity.java
@@ -0,0 +1,74 @@
+package com.stardust.scriptdroid.droid;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TextView;
+
+import com.jraska.console.Console;
+import com.stardust.scriptdroid.BaseActivity;
+import com.stardust.scriptdroid.R;
+
+/**
+ * Created by Stardust on 2017/2/12.
+ */
+
+public class ConsoleActivity extends BaseActivity {
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setUpUI();
+ }
+
+ private void setUpUI() {
+ setContentView(R.layout.activity_console);
+ setToolbarAsBack(getString(R.string.text_console));
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_console, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ Console.clear();
+ return super.onOptionsItemSelected(item);
+ }
+
+ public static class ConsoleView extends Console {
+
+ public ConsoleView(Context context) {
+ super(context);
+ init();
+ }
+
+ public ConsoleView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public ConsoleView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ public ConsoleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init();
+ }
+
+ private void init() {
+ findViewById(R.id.console_scroll_view).setBackgroundColor(Color.WHITE);
+ ((TextView) findViewById(R.id.console_text)).setTextIsSelectable(true);
+ }
+
+ }
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java b/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java
index 845ed94f..cf4c9233 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java
@@ -1,9 +1,8 @@
package com.stardust.scriptdroid.droid;
import android.app.Activity;
-import android.content.DialogInterface;
-import com.afollestad.materialdialogs.MaterialDialog;
+import com.jraska.console.timber.ConsoleTree;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
@@ -15,12 +14,20 @@ import com.stardust.scriptdroid.file.FileUtils;
import java.io.File;
import java.io.FileNotFoundException;
+import timber.log.Timber;
+
/**
* Created by Stardust on 2017/1/23.
*/
public class Droid {
+ static {
+ Timber.plant(new ConsoleTree.Builder()
+ .infoColor(0xcc000000)
+ .build());
+ }
+
public static final String UI = "\"ui\";";
public interface OnRunFinishedListener {
@@ -34,6 +41,7 @@ public class Droid {
public void onRunFinished(Object result, Exception e) {
if (e != null) {
RUNTIME.toast(App.getApp().getString(R.string.text_error) + ": " + e.getMessage());
+ Timber.e(App.getApp().getString(R.string.text_error), e);
}
}
};
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 b117ad7f..b7c9e5d6 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
@@ -5,12 +5,15 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Handler;
+import android.support.annotation.Nullable;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;
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.droid.runtime.action.Action;
import com.stardust.scriptdroid.droid.runtime.action.ActionFactory;
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
@@ -19,6 +22,8 @@ import com.stardust.scriptdroid.droid.runtime.api.IDroidRuntime;
import java.util.List;
+import timber.log.Timber;
+
;
/**
@@ -30,7 +35,7 @@ public class DroidRuntime implements IDroidRuntime {
private static final String TAG = "DroidRuntime";
private static DroidRuntime runtime = new DroidRuntime();
- private final Object mLock = new Object();
+ private final Object mActionPerformLock = new Object();
private boolean mActionPerformResult;
private Handler mUIHandler;
@@ -105,12 +110,22 @@ public class DroidRuntime implements IDroidRuntime {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
}
+ @Override
+ public boolean scrollUp(int i) {
+ return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, i));
+ }
+
+ @Override
+ public boolean scrollDown(int i) {
+ return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, i));
+ }
+
public boolean scrollAllUp() {
- return performAction(ActionFactory.createScrollAllAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
+ return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
}
public boolean scrollAllDown() {
- return performAction(ActionFactory.createScrollAllAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
+ return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
}
@Override
@@ -133,6 +148,21 @@ public class DroidRuntime implements IDroidRuntime {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_PASTE));
}
+ public void log(@Nullable Object str) {
+ Timber.i("" + str);
+ }
+
+ public void err(@Nullable Object o) {
+ Timber.e("" + o);
+ }
+
+ public void console() {
+ App.getApp().startActivity(new Intent(App.getApp(), ConsoleActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
+
+ public void clearConsole(){
+ Console.clear();
+ }
private boolean performAction(Action action) {
if (ActionPerformService.getInstance() == null) {
@@ -140,9 +170,9 @@ public class DroidRuntime implements IDroidRuntime {
throw new ScriptStopException(App.getApp().getString(R.string.text_no_accessibility_permission));
}
ActionPerformService.setAction(action);
- synchronized (mLock) {
+ synchronized (mActionPerformLock) {
try {
- mLock.wait();
+ mActionPerformLock.wait();
} catch (InterruptedException e) {
ActionPerformService.setActions(ActionPerformService.NO_ACTION);
throw new ScriptStopException(App.getApp().getString(R.string.text_script_stopped), e);
@@ -161,7 +191,6 @@ public class DroidRuntime implements IDroidRuntime {
});
}
-
@Override
public void sleep(long millis) {
try {
@@ -207,8 +236,8 @@ public class DroidRuntime implements IDroidRuntime {
public void notifyActionPerformed(boolean succeed) {
mActionPerformResult = succeed;
- synchronized (mLock) {
- mLock.notify();
+ synchronized (mActionPerformLock) {
+ mActionPerformLock.notify();
}
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionFactory.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionFactory.java
index 611f275b..b5e3be3f 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionFactory.java
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionFactory.java
@@ -50,7 +50,11 @@ public class ActionFactory {
};
}
- public static Action createScrollAllAction(int action) {
- return new ScrollAllAction(action);
+ public static Action createScrollMaxAction(int action) {
+ return new ScrollMaxAction(action);
+ }
+
+ public static Action createScrollAction(int action, int i){
+ return new ScrollAction(action, i);
}
}
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
index da88bfb0..af75677c 100644
--- 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
@@ -24,7 +24,7 @@ import java.util.List;
public class ActionPerformService extends AccessibilityService {
private static final String TAG = "ActionPerformService";
- private static ActionPerformService instance;
+ private static volatile ActionPerformService instance;
@SuppressWarnings("unchecked")
public static final List NO_ACTION = Collections.EMPTY_LIST;
@@ -98,17 +98,22 @@ public class ActionPerformService extends AccessibilityService {
@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) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- instance.disableSelf();
- } else {
- AccessibilityServiceUtils.goToAccessibilitySetting(App.getApp());
- }
+ 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/droid/runtime/action/ScrollAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAction.java
new file mode 100644
index 00000000..e66915fb
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAction.java
@@ -0,0 +1,57 @@
+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/12.
+ */
+public class ScrollAction extends Action {
+
+ private int mIndex, mAction;
+
+ public ScrollAction(int action, int i) {
+ mAction = action;
+ mIndex = i;
+ }
+
+ @Override
+ public boolean perform(AccessibilityNodeInfo root) {
+ List scrollableNodes = findScrollableNodes(root);
+ boolean result = mIndex < scrollableNodes.size() && scrollableNodes.get(mIndex).performAction(mAction);
+ recycle(scrollableNodes, root);
+ return result;
+ }
+
+ private void recycle(List list, AccessibilityNodeInfo root) {
+ for (AccessibilityNodeInfo nodeInfo : list) {
+ if (nodeInfo != root)
+ nodeInfo.recycle();
+ }
+ }
+
+ private List findScrollableNodes(AccessibilityNodeInfo root) {
+ List list = new ArrayList<>();
+ findScrollableNodes(root, list);
+ return list;
+ }
+
+ private static boolean findScrollableNodes(AccessibilityNodeInfo node, List list) {
+ if (node == null) {
+ return false;
+ }
+ if (node.isScrollable()) {
+ list.add(node);
+ }
+ for (int i = 0; i < node.getChildCount(); i++) {
+ AccessibilityNodeInfo child = node.getChild(i);
+ if (child == null)
+ continue;
+ if (!findScrollableNodes(child, list))
+ child.recycle();
+ }
+ return node.isScrollable();
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAllAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAllAction.java
deleted file mode 100644
index dbbfb956..00000000
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollAllAction.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.stardust.scriptdroid.droid.runtime.action;
-
-import android.view.accessibility.AccessibilityNodeInfo;
-
-/**
- * Created by Stardust on 2017/1/27.
- */
-
-public class ScrollAllAction extends Action {
-
- private int mScrollAction;
-
- public ScrollAllAction(int scrollAction) {
- mScrollAction = scrollAction;
- }
-
- @Override
- public boolean perform(AccessibilityNodeInfo rootNodeInfo) {
- AccessibilityNodeInfo scrollableNodeInfo = findScrollableNodeInfo(rootNodeInfo);
- return scrollableNodeInfo != null && scrollableNodeInfo.performAction(mScrollAction);
- }
-
- private AccessibilityNodeInfo findScrollableNodeInfo(AccessibilityNodeInfo nodeInfo) {
- if (nodeInfo == null)
- return null;
- if (nodeInfo.isScrollable()) {
- return nodeInfo;
- }
- for (int i = 0; i < nodeInfo.getChildCount(); i++) {
- AccessibilityNodeInfo node = findScrollableNodeInfo(nodeInfo.getChild(i));
- if (node != null) {
- return node;
- }
- }
- return null;
- }
-
-}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollMaxAction.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollMaxAction.java
new file mode 100644
index 00000000..4057c48e
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ScrollMaxAction.java
@@ -0,0 +1,70 @@
+package com.stardust.scriptdroid.droid.runtime.action;
+
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * Created by Stardust on 2017/1/27.
+ */
+
+public class ScrollMaxAction extends Action {
+
+ private static final String TAG = ScrollMaxAction.class.getSimpleName();
+ private int mScrollAction;
+ private AccessibilityNodeInfo mMaxScrollableNode;
+ private AccessibilityNodeInfo mRootNode;
+
+ public ScrollMaxAction(int scrollAction) {
+ mScrollAction = scrollAction;
+ }
+
+ @Override
+ public boolean perform(AccessibilityNodeInfo rootNodeInfo) {
+ reset();
+ mRootNode = rootNodeInfo;
+ findMaxScrollableNodeInfo(rootNodeInfo);
+ boolean result = mMaxScrollableNode != null && mMaxScrollableNode.performAction(mScrollAction);
+ reset();
+ return result;
+ }
+
+ private void reset() {
+ if (mMaxScrollableNode != null && mMaxScrollableNode != mRootNode) {
+ mMaxScrollableNode.recycle();
+ }
+ mMaxScrollableNode = mRootNode = null;
+ }
+
+ private void findMaxScrollableNodeInfo(AccessibilityNodeInfo nodeInfo) {
+ if (nodeInfo == null)
+ return;
+ if (nodeInfo.isScrollable()) {
+ if (mMaxScrollableNode == null) {
+ mMaxScrollableNode = nodeInfo;
+ } else if (getAreaInScreen(mMaxScrollableNode) < getAreaInScreen(nodeInfo)) {
+ if (mMaxScrollableNode != mRootNode)
+ mMaxScrollableNode.recycle();
+ mMaxScrollableNode = nodeInfo;
+ }
+ }
+ for (int i = 0; i < nodeInfo.getChildCount(); i++) {
+ AccessibilityNodeInfo child = nodeInfo.getChild(i);
+ if (child != null) {
+ findMaxScrollableNodeInfo(child);
+ if (mMaxScrollableNode != child) {
+ child.recycle();
+ }
+ }
+ }
+ }
+
+ private long getAreaInScreen(AccessibilityNodeInfo nodeInfo) {
+ Rect rect = new Rect();
+ nodeInfo.getBoundsInScreen(rect);
+ long area = ((long) rect.width()) * rect.height();
+ Log.v(TAG, "area=" + area);
+ return area;
+ }
+
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/IDroidRuntime.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/IDroidRuntime.java
index 0def225f..4f932863 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/IDroidRuntime.java
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/api/IDroidRuntime.java
@@ -30,6 +30,10 @@ public interface IDroidRuntime {
boolean scrollDown(ActionTarget target);
+ boolean scrollUp(int i);
+
+ boolean scrollDown(int i);
+
boolean focus(ActionTarget target);
boolean select(ActionTarget target);
diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/script/ScriptExecuteActivity.java b/app/src/main/java/com/stardust/scriptdroid/droid/script/ScriptExecuteActivity.java
index 0a1227b2..47346969 100644
--- a/app/src/main/java/com/stardust/scriptdroid/droid/script/ScriptExecuteActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/droid/script/ScriptExecuteActivity.java
@@ -26,7 +26,7 @@ public class ScriptExecuteActivity extends Activity {
ScriptExecuteActivity.script = script;
ScriptExecuteActivity.onRunFinishedListener = listener;
ScriptExecuteActivity.runningConfig = config;
- App.getApp().startActivity(new Intent(App.getApp(), ScriptExecuteActivity.class));
+ App.getApp().startActivity(new Intent(App.getApp(), ScriptExecuteActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@Override
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java
index f31a0b09..34d3437e 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java
@@ -12,6 +12,7 @@ import android.view.ViewGroup;
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.droid.assist.BoundsAssistant;
import com.stardust.view.ViewBinder;
import com.stardust.view.ViewBinding;
@@ -86,6 +87,11 @@ public class EditSideMenuFragment extends com.stardust.app.Fragment {
startActivity(new Intent(getContext(), DocumentActivity.class));
}
+ @ViewBinding.Click(R.id.console)
+ private void startConsoleActivity() {
+ startActivity(new Intent(getContext(), ConsoleActivity.class));
+ }
+
@ViewBinding.Check(R.id.sw_assist_service)
private void setAssistServiceEnable(boolean enable) {
BoundsAssistant.setAssistModeEnable(enable);
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java
index aeffd475..ef1622cf 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java
@@ -14,6 +14,7 @@ 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.droid.Droid;
import com.stardust.scriptdroid.droid.assist.BoundsAssistant;
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
@@ -72,6 +73,12 @@ public class SlideMenuFragment extends Fragment {
App.getStateObserver().register(KEY_ASSIST_MODE_NOTIFICATION, mAssistServiceNotificationSwitch);
}
+
+ @ViewBinding.Click(R.id.console)
+ private void startConsoleActivity() {
+ startActivity(new Intent(getContext(), ConsoleActivity.class));
+ }
+
@ViewBinding.Click(R.id.syntax_and_api)
private void startSyntaxHelpActivity() {
startActivity(new Intent(getContext(), DocumentActivity.class));
diff --git a/app/src/main/java/com/stardust/util/CrashHandler.java b/app/src/main/java/com/stardust/util/CrashHandler.java
index 8982ca2f..b6b36d1f 100644
--- a/app/src/main/java/com/stardust/util/CrashHandler.java
+++ b/app/src/main/java/com/stardust/util/CrashHandler.java
@@ -17,6 +17,8 @@ import java.lang.Thread.UncaughtExceptionHandler;
public class CrashHandler implements UncaughtExceptionHandler {
private static final String TAG = "CrashHandler";
+ private static int crashCount = 0;
+ private static long firstCrashMillis = 0;
private final Class> mErrorReportClass;
public CrashHandler(Class> errorReportClass) {
@@ -26,16 +28,40 @@ public class CrashHandler implements UncaughtExceptionHandler {
public void uncaughtException(Thread thread, Throwable ex) {
try {
Log.e(TAG, "Uncaught Exception", ex);
- String t = App.getApp().getString(R.string.sorry_for_crash) + ex.toString();
- Intent intent = new Intent(App.getApp(), this.mErrorReportClass);
- intent.putExtra("message", t);
- intent.putExtra("error", throwableToString(ex));
- App.getApp().startActivity(intent);
+ if (crashTooManyTimes())
+ return;
+ String msg = App.getApp().getString(R.string.sorry_for_crash) + ex.toString();
+ startErrorReportActivity(msg, throwableToString(ex));
System.exit(0);
- } catch (Throwable var6) {
- var6.printStackTrace();
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
}
+ }
+ private void startErrorReportActivity(String msg, String detail) {
+ Intent intent = new Intent(App.getApp(), this.mErrorReportClass);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.putExtra("message", msg);
+ intent.putExtra("error", detail);
+ App.getApp().startActivity(intent);
+ }
+
+ private boolean crashTooManyTimes() {
+ if (crashIntervalTooLong()) {
+ resetCrashCount();
+ return false;
+ }
+ crashCount++;
+ return crashCount >= 5;
+ }
+
+ private void resetCrashCount() {
+ firstCrashMillis = System.currentTimeMillis();
+ crashCount = 0;
+ }
+
+ private boolean crashIntervalTooLong() {
+ return System.currentTimeMillis() - firstCrashMillis > 3000;
}
public static String throwableToString(Throwable throwable) {
diff --git a/app/src/main/res/drawable/ic_console_green.png b/app/src/main/res/drawable/ic_console_green.png
new file mode 100644
index 00000000..0a147a07
Binary files /dev/null and b/app/src/main/res/drawable/ic_console_green.png differ
diff --git a/app/src/main/res/drawable/ic_robot_green.png b/app/src/main/res/drawable/ic_robot_green.png
index a448ebcd..69fe5222 100644
Binary files a/app/src/main/res/drawable/ic_robot_green.png and b/app/src/main/res/drawable/ic_robot_green.png differ
diff --git a/app/src/main/res/drawable/ic_robot_head_green.png b/app/src/main/res/drawable/ic_robot_head_green.png
index 56c82ee4..b0eae7e9 100644
Binary files a/app/src/main/res/drawable/ic_robot_head_green.png and b/app/src/main/res/drawable/ic_robot_head_green.png differ
diff --git a/app/src/main/res/layout/activity_console.xml b/app/src/main/res/layout/activity_console.xml
new file mode 100644
index 00000000..63f49626
--- /dev/null
+++ b/app/src/main/res/layout/activity_console.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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 785c0600..cdf80b5d 100644
--- a/app/src/main/res/layout/fragment_edit_side_menu.xml
+++ b/app/src/main/res/layout/fragment_edit_side_menu.xml
@@ -5,6 +5,28 @@
android:orientation="vertical"
android:textSize="16sp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/raw/document.md b/app/src/main/res/raw/document.md
index b14b0981..b69a5c1b 100644
--- a/app/src/main/res/raw/document.md
+++ b/app/src/main/res/raw/document.md
@@ -12,7 +12,7 @@
> 以下的longClick、select、scrollUp、scrollDown的参数均与click类似,不再赘述。
* `longClick` 长按
* `select` 选择
-* `scrollUp` 上滑。不加参数时会寻找"最大"的可滑动的控件上滑,例如微信消息列表等。
+* `scrollUp` 上滑。不加参数时会寻找"最大"的可滑动的控件上滑,例如微信消息列表等; 参数为一个整数i时会找到第i个可滑动控件滑动。
* `scrollDown` 下滑。不加参数时与scrollUp类似。
* `input(text)` 把所有输入框的文本都置为text。例如input("测试")。
* `input(i, text)` 把第i个输入框的文本设为text。i从0开始。
@@ -28,7 +28,23 @@
* `context` ApplicationContext,参见安卓[android.content.Context](https://developer.android.com/reference/android/content/Context.html)
> 这里的context由于是ApplicationContext,是不可见的,不能用于dialog和其他UI相关。如果要显示弹窗或者视图,请启动UI模式(代码的第一行为`"ui";`既可)并使用activity代替。
* `activity` UI模式下会启动一个Activity来运行脚本,并在UI线程下运行。可通过该变量来获取该activity。
-###五、在脚本中调用Java
+###五、控制台
+* `openConsole()` 打开控制台。
+* `clearConsole()` 清空控制台。
+* `log(text)` 在控制台中输出日志,以例如`log("Hello world");`。
+* `err(text)` 在控制台中输出错误信息,以红色字体显示,例如:
+
+```
+try{
+ //do something
+}catch(e){
+ err("错误);
+ err(e);
+ openConsole();
+}
+```
+
+###六、在脚本中调用Java
使用importClass来引入要使用的库,例如:
```javascript
importClass("android.view.View.OnClickListener")
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fe61ab44..30c82671 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,6 +1,6 @@
免Root脚本机器人
- Version 0.17.0205
+ Version 1.17.0212
设置
关闭服务
使脚本自动操作(点击、长按、滑动等)所需,若关闭则只能执行不涉及自动操作的脚本。
@@ -93,4 +93,6 @@
重新导入示例脚本文件
导入成功,重新打开应用生效
失败
+ 清空
+ 控制台
diff --git a/app0.17.0205.apk b/app1.17.0212.apk
similarity index 65%
rename from app0.17.0205.apk
rename to app1.17.0212.apk
index aa2198d8..0b6c1489 100644
Binary files a/app0.17.0205.apk and b/app1.17.0212.apk differ