diff --git a/.gitignore b/.gitignore index 96aaa3d0..af31524e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ /build /captures .externalNativeBuild -.apk \ No newline at end of file +*.apk \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 19817bc0..66547755 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 19 targetSdkVersion 23 - versionCode 106 - versionName "2.0.3 Beta" + versionCode 108 + versionName "2.0.5 Beta" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true diff --git a/app/src/main/assets/sample/选择器/朋友圈点赞.js b/app/src/main/assets/sample/选择器/朋友圈点赞.js new file mode 100644 index 00000000..be431142 --- /dev/null +++ b/app/src/main/assets/sample/选择器/朋友圈点赞.js @@ -0,0 +1,18 @@ +function 下滑(){ + className("ListView").scrollForward(); +} + +function 尝试点赞(btn){ + btn.click(); + sleep(300); + if(!click("赞")) + btn.click(); +} + +while(true){ +var c = className("ImageView").desc("评论").untilFind(); +c.each(function(btn){ + 尝试点赞(btn); +}); +下滑(); +} \ No newline at end of file diff --git a/app/src/main/java/com/stardust/app/Fragment.java b/app/src/main/java/com/stardust/app/Fragment.java index 1e792185..8e5851b0 100644 --- a/app/src/main/java/com/stardust/app/Fragment.java +++ b/app/src/main/java/com/stardust/app/Fragment.java @@ -1,6 +1,7 @@ package com.stardust.app; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; @@ -16,6 +17,7 @@ public abstract class Fragment extends android.support.v4.app.Fragment { private View mView; + @NonNull public View getView() { return mView; } @@ -36,14 +38,9 @@ public abstract class Fragment extends android.support.v4.app.Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { mView = createView(inflater, container, savedInstanceState); - afterCreateView(); return mView; } - protected void afterCreateView() { - - } - @Nullable public abstract View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState); diff --git a/app/src/main/java/com/stardust/scriptdroid/Pref.java b/app/src/main/java/com/stardust/scriptdroid/Pref.java index 6cfe573e..f4dca9a9 100644 --- a/app/src/main/java/com/stardust/scriptdroid/Pref.java +++ b/app/src/main/java/com/stardust/scriptdroid/Pref.java @@ -4,16 +4,35 @@ import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import com.stardust.automator.AccessibilityEventCommandHost; + /** * Created by Stardust on 2017/1/31. */ public class Pref { private static final SharedPreferences DISPOSABLE_BOOLEAN = App.getApp().getSharedPreferences("DISPOSABLE_BOOLEAN", Context.MODE_PRIVATE); - public static final String SAMPLE_SCRIPTS_COPIED = "SAMPLE_SCRIPTS_COPIED"; - private static final String KEY_MAX_TEXT_LENGTH_FOR_CODE_COMPLETION = "KEY_MAX_TEXT_LENGTH_FOR_CODE_COMPLETION"; public static final String KEY_DRAWER_HEADER_IMAGE_PATH = "KEY_DRAWER_HEADER_IMAGE_PATH"; public static final String KEY_APP_BAR_IMAGE_PATH = "KEY_APP_BAR_IMAGE_PATH"; + private static SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(App.getResString(R.string.key_run_mode))) { + AccessibilityEventCommandHost.getInstance().setRunMode(getRunModeFromValue(sharedPreferences.getString(key, null))); + } + } + }; + + private static int getRunModeFromValue(String value) { + switch (value) { + case "KEY_THREAD_POOL": + return AccessibilityEventCommandHost.RUN_MODE_THREAD_POOL; + case "KEY_NEW_THREAD_EVERY_TIME": + return AccessibilityEventCommandHost.RUN_MODE_NEW_THREAD_EVERY_TIME; + default: + return AccessibilityEventCommandHost.RUN_MODE_SINGLE_THREAD; + } + } public static SharedPreferences def() { return PreferenceManager.getDefaultSharedPreferences(App.getApp()); @@ -64,4 +83,23 @@ public class Pref { return getDisposableBoolean("isFirstUsing", true); } + public static String getDrawerHeaderImagePath() { + return def().getString(KEY_DRAWER_HEADER_IMAGE_PATH, null); + } + + public static void setDrawerHeaderImagePath(String path) { + def().edit().putString(KEY_DRAWER_HEADER_IMAGE_PATH, path).apply(); + } + + public static String getAppBarImagePath() { + return def().getString(KEY_APP_BAR_IMAGE_PATH, null); + } + + public static void setAppBarImagePath(String path) { + def().edit().putString(KEY_APP_BAR_IMAGE_PATH, path).apply(); + } + + static { + def().registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener); + } } 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 61ea8804..8991a9b4 100644 --- a/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java +++ b/app/src/main/java/com/stardust/scriptdroid/droid/Droid.java @@ -2,17 +2,12 @@ package com.stardust.scriptdroid.droid; import android.content.Intent; import android.support.annotation.NonNull; -import android.util.Log; -import android.widget.Toast; -import com.jraska.console.timber.ConsoleTree; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.droid.runtime.DroidRuntime; -import com.stardust.scriptdroid.droid.runtime.ScriptStopException; import com.stardust.scriptdroid.droid.script.JavaScriptEngine; -import com.stardust.scriptdroid.droid.script.RhinoJavaScriptEngine; import com.stardust.scriptdroid.droid.script.ScriptExecuteActivity; import com.stardust.scriptdroid.service.VolumeChangeObverseService; import com.stardust.scriptdroid.tool.FileUtils; @@ -21,7 +16,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.Serializable; import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.Date; import timber.log.Timber; @@ -102,7 +96,7 @@ public class Droid { } public void runScriptFile(File file, OnRunFinishedListener listener) { - Timber.v(DateFormat.getTimeInstance().format(new Date()) + "/" + App.getResString(R.string.text_start_running) + file); + Timber.v(DateFormat.getTimeInstance().format(new Date()) + " " + App.getResString(R.string.text_start_running) + " " + file); listener = listener == null ? DEFAULT_LISTENER : listener; try { checkFile(file); @@ -178,7 +172,7 @@ public class Droid { public void run() { try { if (mScript.startsWith(AUTO)) - DroidRuntime.getRuntime().ensureAccessibilityServiceEnable(); + DroidRuntime.getRuntime().ensureAccessibilityServiceEnabled(); mOnRunFinishedListener.onRunFinished(JAVA_SCRIPT_ENGINE.execute(mScript)); } catch (Exception e) { mOnRunFinishedListener.onException(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 dbe9769d..76ae40af 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 @@ -12,7 +12,6 @@ import android.os.Environment; import android.os.Handler; import android.support.annotation.Nullable; import android.text.SpannableString; -import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.util.Log; @@ -201,7 +200,7 @@ public class DroidRuntime { } private T performAction(Action action) { - ensureAccessibilityServiceEnable(); + ensureAccessibilityServiceEnabled(); ActionPerformAccessibilityDelegate.setAction(action); synchronized (mActionPerformLock) { try { @@ -214,7 +213,7 @@ public class DroidRuntime { return (T) action.getResult(); } - public void ensureAccessibilityServiceEnable() { + public void ensureAccessibilityServiceEnabled() { if (AccessibilityWatchDogService.getInstance() == null) { String errorMessage = null; if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), AccessibilityWatchDogService.class)) { @@ -263,12 +262,12 @@ public class DroidRuntime { } public String currentPackage() { - ensureAccessibilityServiceEnable(); + ensureAccessibilityServiceEnabled(); return AccessibilityInfoProvider.getInstance().getLatestPackage(); } public String currentActivity() { - ensureAccessibilityServiceEnable(); + ensureAccessibilityServiceEnabled(); return AccessibilityInfoProvider.getInstance().getLatestActivity(); } diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/UiSelector.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/UiSelector.java index b687c7a8..1eddfef6 100644 --- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/UiSelector.java +++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/UiSelector.java @@ -1,9 +1,7 @@ package com.stardust.scriptdroid.droid.runtime; import android.accessibilityservice.AccessibilityService; -import android.os.Bundle; import android.support.annotation.NonNull; -import android.util.Log; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; @@ -69,12 +67,16 @@ public class UiSelector extends UiGlobalSelector { private static final String TAG = "UiSelector"; public UiObjectCollection find() { - DroidRuntime.getRuntime().ensureAccessibilityServiceEnable(); + ensureAccessibilityServiceEnabled(); FindCommand command = new FindCommand(); AccessibilityEventCommandHost.getInstance().executeAndWaitForEvent(command); return command.result; } + private void ensureAccessibilityServiceEnabled(){ + DroidRuntime.getRuntime().ensureAccessibilityServiceEnabled(); + } + @NonNull public UiObjectCollection untilFind() { 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 index cc96658c..4779b786 100644 --- 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 @@ -30,7 +30,7 @@ public class ActionPerformAccessibilityDelegate implements AccessibilityDelegate private static Action action; - private Executor mExecutor = Executors.newFixedThreadPool(5); + //private Executor mExecutor = Executors.newFixedThreadPool(5); public static void setAction(Action action) { synchronized (ACTION_LOCK) { @@ -54,7 +54,7 @@ public class ActionPerformAccessibilityDelegate implements AccessibilityDelegate } private void performAction(final AccessibilityNodeInfo root, final Action action) { - mExecutor.execute(new Runnable() { + new Runnable() { @Override public void run() { Log.i(TAG, "perform action:" + action); @@ -66,7 +66,7 @@ public class ActionPerformAccessibilityDelegate implements AccessibilityDelegate onActionPerformed(); } } - }); + }.run(); } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/HoverMenuService.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/HoverMenuService.java index e87d28b8..b2fecc61 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/HoverMenuService.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/HoverMenuService.java @@ -17,10 +17,12 @@ import com.stardust.hover.SimpleHoverMenuTransitionListener; import com.stardust.hover.WindowHoverMenu; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.droid.runtime.DroidRuntime; import com.stardust.scriptdroid.external.floating_window.view.FloatingLayoutBoundsView; import com.stardust.scriptdroid.external.floating_window.view.FloatingLayoutHierarchyView; import com.stardust.scriptdroid.layout_inspector.LayoutInspector; import com.stardust.scriptdroid.layout_inspector.NodeInfo; +import com.stardust.scriptdroid.tool.AccessibilityServiceTool; import com.stardust.theme.ThemeColorManagerCompat; import com.stardust.util.MessageEvent; @@ -165,6 +167,7 @@ public class HoverMenuService extends Service { tryInitViews(); if (mWindowHoverMenu != null) mWindowHoverMenu.show(); + AccessibilityServiceTool.enableAccessibilityServiceByRootIfNeeded(); return START_STICKY; } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordNotification.java b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordNotification.java index 24b375bd..4f6f756e 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordNotification.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordNotification.java @@ -132,7 +132,7 @@ public class AccessibilityActionRecordNotification { public static void startRecord(Context context) { if (AccessibilityWatchDogService.getInstance() == null) { - Toast.makeText(context, R.string.text_need_enable_accessibility_service, Toast.LENGTH_SHORT).show(); + Toast.makeText(context, R.string.text_need_enable_accessibility_service_to_record, Toast.LENGTH_SHORT).show(); return; } AccessibilityActionRecorder.getInstance().start(); diff --git a/app/src/main/java/com/stardust/scriptdroid/tool/AccessibilityServiceTool.java b/app/src/main/java/com/stardust/scriptdroid/tool/AccessibilityServiceTool.java index 98019a97..7b27191b 100644 --- a/app/src/main/java/com/stardust/scriptdroid/tool/AccessibilityServiceTool.java +++ b/app/src/main/java/com/stardust/scriptdroid/tool/AccessibilityServiceTool.java @@ -57,4 +57,11 @@ public class AccessibilityServiceTool { } } } + + public static void enableAccessibilityServiceByRootIfNeeded() { + if (AccessibilityWatchDogService.getInstance() == null) + if (Pref.def().getBoolean(App.getApp().getString(R.string.key_enable_accessibility_service_by_root), false)) { + AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(AccessibilityWatchDogService.class, 3000); + } + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/EditSideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/EditSideMenuFragment.java index ee215a32..f9ed6e22 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/EditSideMenuFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/sidemenu/EditSideMenuFragment.java @@ -50,8 +50,11 @@ public class EditSideMenuFragment extends Fragment { return inflater.inflate(R.layout.fragment_edit_side_menu, container, false); } + + @Override - protected void afterCreateView() { + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); setUpUI(); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java index 3319367c..32ad1cde 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java @@ -32,7 +32,6 @@ import com.stardust.app.OnActivityResultDelegate; import com.stardust.scriptdroid.Pref; 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.AccessibilityActionRecordNotification; import com.stardust.scriptdroid.record.inputevent.InputEventRecorder; import com.stardust.scriptdroid.record.inputevent.InputEventToJsRecorder; @@ -99,7 +98,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File private void goToAccessibilityPermissionSettingIfDisabled() { if (!AccessibilityServiceUtils.isAccessibilityServiceEnabled(this, AccessibilityWatchDogService.class)) { new NotRemindAgainDialog.Builder(this, "goToAccessibilityPermissionSettingIfDisabled") - .title(R.string.text_alert) + .title(R.string.text_need_to_enable_accessibility_service) .content(R.string.explain_accessibility_permission) .positiveText(R.string.text_go_to_setting) .negativeText(R.string.text_cancel) @@ -157,11 +156,11 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File private void setUpDrawerHeader() { TextView version = $(R.id.version); version.setText("Version " + BuildConfig.VERSION_NAME); - String path = Pref.def().getString(Pref.KEY_DRAWER_HEADER_IMAGE_PATH, null); + String path = Pref.getDrawerHeaderImagePath(); if (path != null) { setDrawerHeaderImage(path); } - path = Pref.def().getString(Pref.KEY_APP_BAR_IMAGE_PATH, null); + path = Pref.getAppBarImagePath(); if (path != null) { setAppBarImage(path); } @@ -236,7 +235,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File @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(); + Snackbar.make(mDrawerLayout, R.string.text_need_enable_accessibility_service_to_record, Snackbar.LENGTH_SHORT).show(); return; } AccessibilityActionRecordNotification.showOrUpdateNotification(); @@ -270,7 +269,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File @Override public void onImageSelected(ImageSelector selector, String path) { setDrawerHeaderImage(path); - Pref.def().edit().putString(Pref.KEY_DRAWER_HEADER_IMAGE_PATH, path).apply(); + Pref.setDrawerHeaderImagePath(path); mActivityResultIntermediary.removeDelegate(selector); } }).select(); @@ -376,7 +375,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File new ImageSelector(this, mActivityResultIntermediary, new ImageSelector.ImageSelectorCallback() { @Override public void onImageSelected(ImageSelector selector, String path) { - Pref.def().edit().putString(Pref.KEY_APP_BAR_IMAGE_PATH, path).apply(); + Pref.setAppBarImagePath(path); setAppBarImage(path); mActivityResultIntermediary.removeDelegate(selector); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java index 1a2250ea..ffef581e 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/SlideMenuFragment.java @@ -52,8 +52,9 @@ public class SlideMenuFragment extends Fragment { return inflater.inflate(R.layout.fragment_slide_menu, container, false); } + @Override - protected void afterCreateView() { + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { setUpSwitchCompat(); ViewBinder.bind(this); } @@ -124,9 +125,9 @@ public class SlideMenuFragment extends Fragment { private void stopAllRunningScripts() { int n = Droid.getInstance().stopAll(); if (n > 0) - Snackbar.make(getActivityContentView(), String.format(getString(R.string.text_already_stop_n_scripts), n), Snackbar.LENGTH_SHORT).show(); + Snackbar.make(getView(), String.format(getString(R.string.text_already_stop_n_scripts), n), Snackbar.LENGTH_SHORT).show(); else - Snackbar.make(getActivityContentView(), R.string.text_no_running_script, Snackbar.LENGTH_SHORT).show(); + Snackbar.make(getView(), R.string.text_no_running_script, Snackbar.LENGTH_SHORT).show(); } @Override diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/my_script_list/MyScriptListFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/my_script_list/MyScriptListFragment.java index 64089201..ff02fb6e 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/my_script_list/MyScriptListFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/my_script_list/MyScriptListFragment.java @@ -43,7 +43,8 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler } @Override - protected void afterCreateView() { + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); mScriptListRecyclerView = $(R.id.script_list); mScriptFileList = ScriptFileList.getImpl(); mNoScriptHint = $(R.id.hint_no_script); @@ -60,15 +61,6 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler mScriptListRecyclerView.setScriptFileList(mScriptFileList); } - private void init() { - setUpScriptList(); - } - - private void setUpScriptList() { - - } - - @Override public boolean onBackPressed() { if (mScriptListRecyclerView.getScriptFileOperationPopupMenu().isShowing()) { diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java index 1ec67daa..2407e25a 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/operation/ScriptFileOperation.java @@ -73,9 +73,8 @@ public abstract class ScriptFileOperation { @Override public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) { - Context context = recyclerView.getContext(); ScriptFile scriptFile = scriptFileList.get(position); - EditActivity.editFile(context, scriptFile.name, scriptFile.path); + EditActivity.editFile(App.getApp(), scriptFile.name, scriptFile.path); } } @@ -87,10 +86,9 @@ public abstract class ScriptFileOperation { @Override public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) { - Context context = recyclerView.getContext(); ScriptFile scriptFile = scriptFileList.get(position); Uri uri = Uri.parse("file://" + scriptFile.path); - context.startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain")); + App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain")); } } @@ -125,9 +123,8 @@ public abstract class ScriptFileOperation { @Override public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) { - Context context = recyclerView.getContext(); ScriptFile scriptFile = scriptFileList.get(position); - new Shortcut(context).name(scriptFile.name) + new Shortcut(App.getApp()).name(scriptFile.name) .targetClass(ShortcutActivity.class) .icon(R.drawable.ic_robot_green) .extras(new Intent().putExtra("path", scriptFile.path)) diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/sample_list/SampleScriptListFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/sample_list/SampleScriptListFragment.java index a9f99d9b..f6fe9389 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/sample_list/SampleScriptListFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/sample_list/SampleScriptListFragment.java @@ -39,7 +39,8 @@ public class SampleScriptListFragment extends Fragment { } @Override - protected void afterCreateView() { + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); mSampleScriptListRecyclerView = $(R.id.script_list); mSampleScriptListRecyclerView.setSamples(SampleFileManager.getInstance().getSamplesFromAssets(getContext().getAssets(), "sample")); mSampleScriptListRecyclerView.setOnItemLongClickListener(new SampleScriptListRecyclerView.OnItemLongClickListener() { diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/settings/SettingsActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/settings/SettingsActivity.java index 90fe05bf..d240bf99 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/settings/SettingsActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/settings/SettingsActivity.java @@ -110,9 +110,8 @@ public class SettingsActivity extends BaseActivity { .entry(getString(R.string.text_reset_background), new Runnable() { @Override public void run() { - Pref.def().edit().putString(Pref.KEY_APP_BAR_IMAGE_PATH, null) - .putString(Pref.KEY_DRAWER_HEADER_IMAGE_PATH, null) - .apply(); + Pref.setAppBarImagePath(null); + Pref.setDrawerHeaderImagePath(null); Toast.makeText(getActivity(), R.string.text_restart_app_to_apply, Toast.LENGTH_SHORT).show(); } }) diff --git a/app/src/main/res/layout/floating_script_list_recycler_view_item.xml b/app/src/main/res/layout/floating_script_list_recycler_view_item.xml index 4860318a..7af2383b 100644 --- a/app/src/main/res/layout/floating_script_list_recycler_view_item.xml +++ b/app/src/main/res/layout/floating_script_list_recycler_view_item.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:foreground="?android:selectableItemBackground" + android:foreground="?android:attr/selectableItemBackground" android:orientation="vertical" android:paddingBottom="12dp" android:paddingLeft="16dp" diff --git a/app/src/main/res/layout/floating_window_main_menu.xml b/app/src/main/res/layout/floating_window_main_menu.xml index 8c6a7c45..f44114c9 100644 --- a/app/src/main/res/layout/floating_window_main_menu.xml +++ b/app/src/main/res/layout/floating_window_main_menu.xml @@ -9,7 +9,7 @@ android:id="@+id/layout_hierarchy" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:padding="16dp" android:text="@string/text_layout_hierarchy" android:textColor="@android:color/primary_text_dark" @@ -24,7 +24,7 @@ android:id="@+id/layout_bounds" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:padding="16dp" android:text="@string/text_layout_bounds" android:textColor="@android:color/primary_text_dark" @@ -39,7 +39,7 @@ android:id="@+id/stop_all_running_scripts" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:padding="16dp" android:text="@string/text_close_all_running_scripts" android:textColor="@android:color/primary_text_dark" @@ -54,7 +54,7 @@ android:id="@+id/open_launcher" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:padding="16dp" android:text="@string/text_open_launcher" android:textColor="@android:color/primary_text_dark" @@ -69,7 +69,7 @@ android:id="@+id/current_package" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:padding="16dp" android:textColor="@android:color/primary_text_dark" android:textSize="16sp"/> @@ -83,7 +83,7 @@ android:id="@+id/current_activity" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:padding="16dp" android:textColor="@android:color/primary_text_dark" android:textSize="16sp"/> diff --git a/app/src/main/res/layout/floating_window_record.xml b/app/src/main/res/layout/floating_window_record.xml index 483a7b0e..731981cf 100644 --- a/app/src/main/res/layout/floating_window_record.xml +++ b/app/src/main/res/layout/floating_window_record.xml @@ -1,5 +1,6 @@ @@ -32,7 +33,9 @@ android:id="@+id/sw_recorded_by_root" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentRight="true"/> + android:layout_alignParentRight="true" + android:textOn="@string/text_on" + android:textOff="@string/text_off"/> @@ -62,7 +65,9 @@ android:id="@+id/sw_record_toast" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentRight="true"/> + android:layout_alignParentRight="true" + android:textOn="@string/text_on" + android:textOff="@string/text_off"/> UiAutomator - 设置 - 关闭服务 - 使脚本自动操作(点击、长按、滑动等)所需,若关闭则只能执行不涉及自动操作的脚本。 - 新建文件 - 从文件导入 - 退出 - 服务已关闭 - 找不到文件管理器T.T - 文件创建失败 - 请输入名称 - 名称 - 去设置 - 软件需要打开\"自动操作服务\"才能运行,请在随后的设置中选择\"免Root脚本精灵\"并开启服务。\n您也可以稍后在侧拉菜单中设置。 - 取消 - 路径为空 - 文件不存在 - 无文件读写权限 - 内嵌920测试 - 自动操作服务未启动,脚本已停止运行 - 关闭侧拉菜单 - 打开侧拉菜单 - 撤销 - 重做 - 保存 - 运行 - 提示 - 内容尚未保存,您确定要退出吗? - 保存并退出 - 直接退出 - 设置 - 退出 - 自动操作服务 - 帮助 - 关闭所有正在运行的脚本 - 关于 - 开放源代码许可 - 不再提示 - 支付宝扫一扫 - 示例:打开正在运行的服务(安卓6.0+) - 示例:简单计算器 + Settings + Disable Service + Required by the script automatic operation (click, long press, slide, etc.). + New File + Import File + Exit + Service disabled. + No file explorer T.T + File creation failed + Input name + Name + Go to setting + Need to enable the Accessibility service.\nYou can also enable it later in the side menu. + Cancel + Path is empty + File dost not exist + No file read and write permissions + The accessibility service is disabled and the script has stopped + Close drawer + Open drawer + Undo + Redo + Save + Run + Prompt + The content has not been saved, are you sure you want to exit? + Save & Exit + Exit + Settings + Exit + Accessibility Service + Help + Stop all running scripts + About + Open Sources Licenses + Don\'t show again Copyright©2016 All right reserves. - 星尘幻影 + Stardust 946994919 hybbbb1996@gmail.com - 软件源代码 - 已复制到剪贴板 - 打赏作者 - 邮箱 + Source Code + Copied + Donate + Email https://github.com/hyb1996/NoRootScriptDroid - [免Root脚本精灵]下载地址:http://www.coolapk.com/apk/com.stardust.scriptdroid - 悬浮窗 - 通知栏点击区域辅助开关 - 其他 - 点击区域辅助服务已开启(点击关闭) - 点击区域辅助服务已关闭(点击开启) - 错误报告 - 示例:QQ自动抢红包 - 再按一次退出程序 - 常用函数 - 很抱歉(ಥ _ ಥ)程序遇到未知错误,即将停止运行\n错误代码: - 没有正在运行的脚本 - 已停止%d个正在运行的脚本 - 开始运行 - 用其他应用打开 - 重命名 - 同时重命名原文件 - 请输入新名称 - 创建桌面快捷方式 - 已创建 - 删除 - 彻底删除 - 已删除 - 文件删除失败 - 选择一个文件 - /脚本/ - 错误 - 还没有文档/(ㄒoㄒ)/~~ - 复制调试信息 - 这是软件开发者(。・・)ノ - 略略略 - 请选择邮件应用 - 点击定位剪贴板 - 脚本已停止 - \"点击区域辅助服务\"是在要点击的区域不是文本时使用的,参见\"帮助\"。\"点击区域辅助服务\"只有在\"自动操作服务\"开启时才有效。 - 请选择 - 崩溃了o(≧口≦)o - 点击\"退出\"退出程序(ಥ _ ಥ)或者提交错误报告或者复制调试信息反馈给开发者(≧∇≦)ノ - 无法在后台显示弹框,脚本已停止运行 - 示例:QQ强制聊天 - 重新导入示例脚本文件 - 导入成功 - 失败 - 清空 - 控制台 - 微信扫一扫 - 提交错误报告 + [UiAutomator]Download:http://www.coolapk.com/apk/com.stardust.scriptdroid + Floating Window + Others + Bug Report + Press again to exit + Common using functions + No running scipts + %d script(s) is(are) stopped + Running + Open by other apps + Rename + Rename file + Input new name + Create shortcut + Created + Delete + Delete file + Deleted + File deletion failed + Choose a file + /Scripts/ + Error + There is no documentation yet/(ㄒoㄒ)/~~ + Copy debugging log + This is a software developer(。・・)ノ + lol + Choose a email application + Script stopped + Please choose + Crash~ o(≧口≦)o + (ಥ _ ಥ)Exit or submit a bug report or copy debugging log to the developer(≧∇≦)ノ + Failed + Clear + Console + Submit Bug report Bug Report - 提交失败 - 提交成功 - 无法处理文件 + Submission Failed + Submitted successfully + Cannot process file Crash - 问题反馈 - 录制脚本 - 在通知栏中开始录制 - 开始录制 - 停止录制 - 录制未开始 - 暂停录制 - 继续录制 - 录制结束 - 复制到剪贴板 - 文件写入失败 - 需要打开\"自动操作服务“才能录制脚本 - 加入QQ交流群 - 已复制到剪贴板 - 关闭 - 重新录制 - 使用音量键控制 - 开启后每次音量变化会开始或停止脚本录制 + Feedback + Record touches + Start + Stop + Recording is not started + Pause + Resume + Recording stopped + Copy + File writing failed + Need to enable the Accessibility Service + Join in QQ Group + Copied + Close + Use the volume keys to control + Stop or start recording when volume changes key_use_volume_control_record - 未安装手机QQ - 编辑 + Not installed mobile QQ + Edit key_max_length_for_code_completion - 代码补全最大文件长度 - 文件已存在 - 无障碍服务 - 通过Root权限自动启用服务 - 自动操作服务已启用但并未运行,这可能是安卓的BUG,您可能需要重启手机 + Maximum file length of code complements + The file exists + Accessibility Service + Enable service automatically with root + Accessibility service is enabled but not running. This may be Android\'s BUG. You may need to restart your phone key_enable_accessibility_service_by_root - 使用Root权限启动自动操作服务超时 - 开启后运行脚本会使用Root权限自动开启自动操作服务 - 外观 - 主题色 - 选择图片 - 帮助 - 录制脚本(root) - 使用音量上键,音量下键结束录制 - 没有悬浮窗权限 - 节点信息 - 布局层次分析 - 布局范围查看 - 无障碍服务未启动 - 示例脚本 - 我的脚本 - 点击右上角新建第一个脚本吧~(。・・)ノ - 重置背景图片设置 - 重启软件生效 - 使用root权限录制 - 录制提示 - 文字改变 - 滑动 - 长按 - 点击 - 打开主界面 - 导入到我的脚本 - 导入成功 - 免Root脚本录制 - Root脚本录制 - 开始录制按键 - 结束录制按键 + Start the accessibility service timeout + Enable accessibility service automatically when needed + Appearance + Theme Color + Choose a picture + Help + No floating window permission + Node info + View layout hierarchy + View layout bounds + Accessibility service is not activated + Sample Scripts + My Scripts + Click ADD to create your first script~(。・・)ノ + Reset background settings + Restart to apply + Recording with Rooting + Recording Prompt + Text Changed + Scrolled + Long Clicked + Clicked + Open Application + Import to my scripts + Import successful + Record without root + Record with root + Key to start + Key to stop NONE key_start_record_trigger key_stop_record_trigger - 当前活动: - 当前应用包名: - + Current Activity: + Current Package: + Accessibility Services->UiAutomator]]> + Script + key_use_volume_control_running + Stop all scripts when volume changes + Need to enable Accessibility Service + Advanced + Auto operation function running mode + If the app responses slowly when running script, choose Thread Pool or Create Thread. But it may causes rebooting of the device + ON + OFF - - 音量上键 - 音量下键 - 照相键 + None + Volume Up + Volume Down + Camera - - NONE - KEY_VOLUMEUP - KEY_VOLUMEDOWN - KEY_CAMERA + + Single Thread + Create New Thread Every Time + Thread Pool + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ec9c8797..3f85471b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -112,7 +112,7 @@ 录制结束 复制到剪贴板 文件写入失败 - 需要打开\"自动操作服务“才能录制脚本 + 需要打开\"自动操作服务“才能录制脚本 加入QQ交流群 已复制到剪贴板 关闭 @@ -169,6 +169,14 @@ 脚本运行 key_use_volume_control_running 每次音量键变化停止所有脚本 + 需要启用无障碍服务 + 高级 + 运行方式 + 自动操作函数执行方式 + 如果运行脚本后界面卡顿请尝试多线程或线程池,但这可能导致设备重启 + KEY_SINGLE_THREAD + 已开启 + 已关闭 @@ -183,4 +191,16 @@ KEY_VOLUMEDOWN KEY_CAMERA + + + 单线程 + 每次都创建新线程 + 线程池 + + + + KEY_SINGLE_THREAD + KEY_NEW_THREAD_EVERY_TIME + KEY_THREAD_POOL + diff --git a/app/src/main/res/xml/accessibility_service_config.xml b/app/src/main/res/xml/accessibility_service_config.xml index 1cba8e94..ec4d9dc2 100644 --- a/app/src/main/res/xml/accessibility_service_config.xml +++ b/app/src/main/res/xml/accessibility_service_config.xml @@ -3,6 +3,7 @@ android:accessibilityEventTypes="typeAllMask" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds|flagRetrieveInteractiveWindows" + android:canRequestEnhancedWebAccessibility="true" android:canRetrieveWindowContent="true" android:description="@string/text_accessibility_service_description" android:notificationTimeout="100"/> \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 71870703..44114da6 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -60,6 +60,18 @@ + + + + + diff --git a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java index 615ed9d5..05ea5e18 100644 --- a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java +++ b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java @@ -9,7 +9,14 @@ import org.mozilla.javascript.Context; import org.mozilla.javascript.ImporterTopLevel; import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import static org.junit.Assert.assertEquals; @@ -20,26 +27,80 @@ import static org.junit.Assert.assertEquals; */ public class ExampleUnitTest { // TODO: 2017/3/3 自定义函数 - // TODO: 2017/3/19 翻译 - // FIXME: 2017/3/19 开始运行的提示覆盖问题 - // TODO: 2017/3/19 + // TODO: 2017/3/19 + Counter counter = new Counter(5); + private List mIntegers = new ArrayList<>(); @Test public void test() { - assertEquals(1, 1); - Context context = Context.enter(); - context.setOptimizationLevel(-1); - context.setLanguageVersion(Context.VERSION_1_7); - context.setInstructionObserverThreshold(10000); - ImporterTopLevel importerTopLevel = new ImporterTopLevel(); - importerTopLevel.initStandardObjects(context, false); - context.evaluateString(importerTopLevel, "var a = 1;var b = function(){};", "", 1, null); - String[] ids = (String[]) importerTopLevel.getIds(); - System.out.println(ids[0].getClass()); - System.out.println(Arrays.toString(ids)); - for(Object id : ids){ - System.out.println(importerTopLevel.get(id)); + ExecutorService executor = Executors.newFixedThreadPool(10); + executor.execute(new Task(1, 100)); + executor.execute(new Task(2, 1000)); + System.out.println(0); + executor.execute(new Task(3, 100)); + executor.execute(new Task(4, 100)); + executor.execute(new Task(5, 100)); + System.out.println(100); + counter.lock(); + } + + private class Task implements Runnable { + + public Task(int i, int delay) { + this.i = i; + this.delay = delay; + } + + private final int i, delay; + + @Override + public void run() { + if (delay > 0) + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + System.out.println(i); + synchronized (mIntegers) { + mIntegers.add(i); + for (Integer integer : mIntegers) { + System.out.println(i + ":" + integer); + } + } + counter.minus(); } } + + private static class Counter { + + private final Object lock = new Object(); + + public Counter(int i) { + this.i = i; + } + + private volatile int i; + + void minus() { + i--; + if (i == 0) { + synchronized (lock) { + lock.notify(); + } + } + } + + void lock() { + synchronized (lock) { + try { + lock.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + } } \ No newline at end of file diff --git a/automator/src/main/java/com/stardust/automator/AccessibilityEventCommandHost.java b/automator/src/main/java/com/stardust/automator/AccessibilityEventCommandHost.java index 7777671d..a3e54a22 100644 --- a/automator/src/main/java/com/stardust/automator/AccessibilityEventCommandHost.java +++ b/automator/src/main/java/com/stardust/automator/AccessibilityEventCommandHost.java @@ -31,31 +31,50 @@ public class AccessibilityEventCommandHost implements AccessibilityDelegate { private static final String TAG = "CommandHostDelegate"; + public static final int RUN_MODE_SINGLE_THREAD = 0; + public static final int RUN_MODE_THREAD_POOL = 1; + public static final int RUN_MODE_NEW_THREAD_EVERY_TIME = 2; + + private final Queue mCommands = new LinkedList<>(); private Executor mExecutor = Executors.newFixedThreadPool(5); + private int mRunMode = 0; @Override public boolean onAccessibilityEvent(final AccessibilityService service, final AccessibilityEvent event) { synchronized (mCommands) { if (!mCommands.isEmpty()) { - Log.v(TAG, "execute " + mCommands.size() + " commands"); + Log.v(TAG, "will execute " + mCommands.size() + " commands"); } while (!mCommands.isEmpty()) { final Command command = mCommands.poll(); - mExecutor.execute(new Runnable() { - @Override - public void run() { - command.execute(service, event); - synchronized (command) { - command.notify(); - } - } - }); + executeCommand(command, service, event); } } return false; } + private void executeCommand(final Command command, final AccessibilityService service, final AccessibilityEvent event) { + Runnable r = new Runnable() { + @Override + public void run() { + Log.v(TAG, "executing " + command); + command.execute(service, event); + synchronized (command) { + Log.v(TAG, "notify " + mCommands.size() + " commands"); + command.notify(); + } + } + }; + if (mRunMode == RUN_MODE_SINGLE_THREAD) { + r.run(); + } else if (mRunMode == RUN_MODE_NEW_THREAD_EVERY_TIME) { + new Thread(r).start(); + } else { + mExecutor.execute(r); + } + } + public void executeAndWaitForEvent(Command command) { synchronized (mCommands) { @@ -70,4 +89,8 @@ public class AccessibilityEventCommandHost implements AccessibilityDelegate { } } + public void setRunMode(int mode) { + mRunMode = mode; + } + }