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