diff --git a/app/build.gradle b/app/build.gradle index 66547755..02cf62da 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 19 targetSdkVersion 23 - versionCode 108 - versionName "2.0.5 Beta" + versionCode 109 + versionName "2.0.6 Alpha" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true @@ -70,6 +70,8 @@ dependencies { compile 'io.mattcarroll.hover:hover:0.9.7' compile 'org.greenrobot:eventbus:3.0.0' compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1' + compile 'com.github.0xFireball:Enlightened:v31' + compile 'com.ashokvarma.android:bottom-navigation-bar:1.4.1' compile(name: 'libtermexec-release', ext: 'aar') compile(name: 'emulatorview-release', ext: 'aar') compile(name: 'term-debug', ext: 'aar') diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f7586b98..e01a7e09 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -72,6 +72,7 @@ + mFragments = new ArrayList<>(); + private List mTitles = new ArrayList<>(); + private FragmentActivity mActivity; + + public FragmentPagerAdapterBuilder(FragmentActivity activity) { + mActivity = activity; + } + + public FragmentPagerAdapterBuilder add(Fragment fragment, String title) { + mFragments.add(fragment); + mTitles.add(title); + return this; + } + + public FragmentPagerAdapterBuilder add(Fragment fragment, int titleResId) { + return add(fragment, mActivity.getString(titleResId)); + } + + public StoredFragmentPagerAdapter build() { + return new StoredFragmentPagerAdapter(mActivity.getSupportFragmentManager()) { + @Override + public Fragment getItem(int position) { + return mFragments.get(position); + } + + @Override + public int getCount() { + return mFragments.size(); + } + + @Override + public CharSequence getPageTitle(int position) { + return mTitles.get(position); + } + }; + } + + public abstract static class StoredFragmentPagerAdapter extends FragmentPagerAdapter { + + private SparseArray mStoredFragments = new SparseArray<>(); + + public StoredFragmentPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Object instantiateItem(ViewGroup container, int position) { + Fragment fragment = (Fragment) super.instantiateItem(container, position); + mStoredFragments.put(position, fragment); + return fragment; + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + mStoredFragments.remove(position); + super.destroyItem(container, position, object); + } + + public Fragment getStoredFragment(int position) { + return mStoredFragments.get(position); + } + } +} diff --git a/app/src/main/java/com/stardust/app/NotRemindAgainDialog.java b/app/src/main/java/com/stardust/app/NotAskAgainDialog.java similarity index 94% rename from app/src/main/java/com/stardust/app/NotRemindAgainDialog.java rename to app/src/main/java/com/stardust/app/NotAskAgainDialog.java index 93645a44..10fc4360 100644 --- a/app/src/main/java/com/stardust/app/NotRemindAgainDialog.java +++ b/app/src/main/java/com/stardust/app/NotAskAgainDialog.java @@ -16,9 +16,9 @@ import static com.jecelyin.common.utils.StringUtils.md5; * Created by Stardust on 2017/1/30. */ -public class NotRemindAgainDialog extends MaterialDialog { +public class NotAskAgainDialog extends MaterialDialog { - protected NotRemindAgainDialog(Builder builder) { + protected NotAskAgainDialog(Builder builder) { super(builder); } 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 76ae40af..2bcca4b1 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 @@ -289,7 +289,6 @@ public class DroidRuntime { public ThemeColorMaterialDialogBuilder dialog() { if (App.currentActivity() == null) { - Toast.makeText(App.getApp(), R.string.text_cannot_create_dialog_when_app_invisible, Toast.LENGTH_SHORT).show(); throw new ScriptStopException(App.getApp().getString(R.string.text_cannot_create_dialog_when_app_invisible)); } return new ThemeColorMaterialDialogBuilder(App.currentActivity()) { diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/script/RhinoJavaScriptEngine.java b/app/src/main/java/com/stardust/scriptdroid/droid/script/RhinoJavaScriptEngine.java index d0d68c35..b24c0c03 100644 --- a/app/src/main/java/com/stardust/scriptdroid/droid/script/RhinoJavaScriptEngine.java +++ b/app/src/main/java/com/stardust/scriptdroid/droid/script/RhinoJavaScriptEngine.java @@ -1,17 +1,29 @@ package com.stardust.scriptdroid.droid.script; +import android.net.Uri; + import com.stardust.scriptdroid.droid.Droid; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.droid.runtime.DroidRuntime; import com.stardust.scriptdroid.droid.runtime.ScriptStopException; +import com.stardust.scriptdroid.droid.script.file.ScriptFile; import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextFactory; import org.mozilla.javascript.ImporterTopLevel; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.commonjs.module.RequireBuilder; +import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider; +import org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider; +import java.io.File; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -63,11 +75,23 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { for (Map.Entry variable : mVariableMap.entrySet()) { ScriptableObject.putProperty(scope, variable.getKey(), variable.getValue()); } + initRequireBuilder(context, scope); context.evaluateString(scope, Init.getInitScript(), "", 1, null); mThreads.add(Thread.currentThread()); } + private void initRequireBuilder(Context context, Scriptable scope) { + List paths = Collections.singletonList(new File(ScriptFile.DEFAULT_FOLDER).toURI()); + new RequireBuilder() + .setModuleScriptProvider(new SoftCachingModuleScriptProvider( + new UrlModuleSourceProvider(paths, null))) + .setSandboxed(true) + .createRequire(context, scope) + .install(scope); + + } + @Override public int stopAll() { diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/script/file/ScriptFileList.java b/app/src/main/java/com/stardust/scriptdroid/droid/script/file/ScriptFileList.java index ea6fab4f..7c8e43ed 100644 --- a/app/src/main/java/com/stardust/scriptdroid/droid/script/file/ScriptFileList.java +++ b/app/src/main/java/com/stardust/scriptdroid/droid/script/file/ScriptFileList.java @@ -29,6 +29,8 @@ public abstract class ScriptFileList { public abstract int size(); public boolean deleteFromFileSystem(int i) { + if (i < 0 || i >= size()) + return false; File file = new File(get(i).path); remove(i); return file.delete(); diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/content/RecordNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/content/RecordNavigatorContent.java index 42d84c3d..43d9ee0c 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floating_window/content/RecordNavigatorContent.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floating_window/content/RecordNavigatorContent.java @@ -129,7 +129,6 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat private void startRecord() { mRecorder = mRecordedByRootSwitch.isChecked() ? new TouchRecorder() : AccessibilityActionRecorder.getInstance(); - AccessibilityActionRecorder.getInstance().setRecordMessageEnabled(mRecordToastSwitch.isChecked()); mRecorder.setOnStateChangedListener(this); mRecorder.start(); setState(Recorder.STATE_RECORDING); 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 deleted file mode 100644 index 4f6f756e..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordNotification.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.stardust.scriptdroid.external.notification.record; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.support.v4.app.NotificationCompat; -import android.widget.Toast; - -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.record.Recorder; -import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder; -import com.stardust.scriptdroid.service.AccessibilityWatchDogService; -import com.stardust.scriptdroid.service.VolumeChangeObverseService; -import com.stardust.scriptdroid.ui.main.MainActivity; - -/** - * Created by Stardust on 2017/2/14. - */ - -public class AccessibilityActionRecordNotification { - - private static final String INTENT_ACTION = " com.stardust.scriptdroid.Record"; - private static final String EXTRA_ACTION = "action"; - private static final int ACTION_STOP = 17771; - private static final int ACTION_START_OR_PAUSE = 17772; - private static final int ACTION_DELETE = 17773; - private static final int ACTION_REDO = 17774; - - private static final int NOTIFY_ID = 22236; - private static NotificationCompat.Builder builder; - private static BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - int action = intent.getIntExtra(EXTRA_ACTION, 0); - switch (action) { - case ACTION_STOP: - stopRecord(context); - collapseNotificationBar(context); - break; - case ACTION_START_OR_PAUSE: - startOrPauseRecord(context); - collapseNotificationBar(context); - break; - case ACTION_DELETE: - AccessibilityActionRecordNotification.cancelNotification(); - stopRecordIfNeeded(context); - break; - case ACTION_REDO: - redoRecord(context); - break; - } - } - }; - - - static PendingIntent getStartOrPauseIntent() { - Intent intent = new Intent(INTENT_ACTION) - .putExtra(EXTRA_ACTION, ACTION_START_OR_PAUSE); - return PendingIntent.getBroadcast(App.getApp(), ACTION_START_OR_PAUSE, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - static PendingIntent getStopIntent() { - Intent intent = new Intent(INTENT_ACTION) - .putExtra(EXTRA_ACTION, ACTION_STOP); - return PendingIntent.getBroadcast(App.getApp(), ACTION_STOP, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - static PendingIntent getDeleteIntent() { - Intent intent = new Intent(INTENT_ACTION) - .putExtra(EXTRA_ACTION, ACTION_DELETE); - return PendingIntent.getBroadcast(App.getApp(), ACTION_DELETE, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - - static PendingIntent getRedoIntent() { - Intent intent = new Intent(INTENT_ACTION) - .putExtra(EXTRA_ACTION, ACTION_REDO); - return PendingIntent.getService(App.getApp(), ACTION_REDO, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - public static void showOrUpdateNotification() { - if (builder == null) { - builder = new NotificationCompat.Builder(App.getApp()) - .setAutoCancel(false) - .setSmallIcon(R.drawable.ic_robot_head) - .setDeleteIntent(getDeleteIntent()) - .setCustomContentView(AccessibilityActionRecordSwitchView.getInstance()); - } - showNotification(builder.build()); - App.getApp().startService(new Intent(App.getApp(), VolumeChangeObverseService.class)); - } - - private static void showNotification(Notification notification) { - NotificationManager notificationManager = (NotificationManager) App.getApp().getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.notify(NOTIFY_ID, notification); - App.getApp().registerReceiver(broadcastReceiver, new IntentFilter(INTENT_ACTION)); - } - - public static void cancelNotification() { - NotificationManager notificationManager = (NotificationManager) App.getApp().getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(NOTIFY_ID); - App.getApp().unregisterReceiver(broadcastReceiver); - } - - private static void collapseNotificationBar(Context context) { - context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - } - - private static void stopRecordIfNeeded(Context context) { - int state = AccessibilityActionRecorder.getInstance().getState(); - if (state == Recorder.STATE_RECORDING || state == Recorder.STATE_PAUSED) { - stopRecord(context); - } - } - - private static void startOrPauseRecord(Context context) { - int state = AccessibilityActionRecorder.getInstance().getState(); - if (state == Recorder.STATE_PAUSED) { - resumeRecord(context); - } else if (state == Recorder.STATE_RECORDING) { - pauseRecord(context); - } else { - //state == STOPPED - startRecord(context); - } - } - - public static void startRecord(Context context) { - if (AccessibilityWatchDogService.getInstance() == null) { - Toast.makeText(context, R.string.text_need_enable_accessibility_service_to_record, Toast.LENGTH_SHORT).show(); - return; - } - AccessibilityActionRecorder.getInstance().start(); - AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_RECORDING); - Toast.makeText(context, R.string.text_start_record, Toast.LENGTH_SHORT).show(); - } - - private static void pauseRecord(Context context) { - AccessibilityActionRecorder.getInstance().pause(); - AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_PAUSED); - } - - private static void resumeRecord(Context context) { - AccessibilityActionRecorder.getInstance().resume(); - AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_RECORDING); - } - - public static void stopRecord(Context context) { - if (AccessibilityActionRecorder.getInstance().getState() != Recorder.STATE_STOPPED) { - AccessibilityActionRecorder.getInstance().stop(); - String script = AccessibilityActionRecorder.getInstance().getCode(); - AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_STOPPED); - MainActivity.onActionRecordStopped(context, script); - } else { - Toast.makeText(App.getApp(), R.string.text_not_recording, Toast.LENGTH_SHORT).show(); - } - } - - private static void redoRecord(Context context) { - if (AccessibilityActionRecorder.getInstance().getState() != Recorder.STATE_STOPPED) { - AccessibilityActionRecorder.getInstance().stop(); - AccessibilityActionRecordSwitchView.getInstance().setState(Recorder.STATE_STOPPED); - } - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordSwitchView.java b/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordSwitchView.java deleted file mode 100644 index 62748f65..00000000 --- a/app/src/main/java/com/stardust/scriptdroid/external/notification/record/AccessibilityActionRecordSwitchView.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.stardust.scriptdroid.external.notification.record; - -import android.widget.RemoteViews; - -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.R; -import com.stardust.scriptdroid.record.Recorder; - -/** - * Created by Stardust on 2017/2/14. - */ - -public class AccessibilityActionRecordSwitchView extends RemoteViews { - - private static AccessibilityActionRecordSwitchView instance; - - public static AccessibilityActionRecordSwitchView getInstance() { - if (instance == null) { - instance = new AccessibilityActionRecordSwitchView(); - } - return instance; - } - - private AccessibilityActionRecordSwitchView() { - super(App.getApp().getPackageName(), R.layout.remote_views_record_switch); - setUpOnClick(); - } - - public void setState(int state) { - switch (state) { - case Recorder.STATE_STOPPED: - setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_play_arrow_grey600_48dp); - setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_start_record)); - break; - case Recorder.STATE_RECORDING: - setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_pause_grey600_48dp); - setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_pause_record)); - break; - case Recorder.STATE_PAUSED: - setImageViewResource(R.id.img_start_or_pause, R.drawable.ic_play_arrow_grey600_48dp); - setTextViewText(R.id.text_start_or_pause, App.getApp().getString(R.string.text_resume_record)); - break; - } - AccessibilityActionRecordNotification.showOrUpdateNotification(); - } - - private void setUpOnClick() { - setOnClickPendingIntent(R.id.stop, AccessibilityActionRecordNotification.getStopIntent()); - setOnClickPendingIntent(R.id.start_or_pause, AccessibilityActionRecordNotification.getStartOrPauseIntent()); - setOnClickPendingIntent(R.id.close, AccessibilityActionRecordNotification.getDeleteIntent()); - setOnClickPendingIntent(R.id.redo, AccessibilityActionRecordNotification.getRedoIntent()); - } -} diff --git a/app/src/main/java/com/stardust/scriptdroid/record/accessibility/AccessibilityActionRecorder.java b/app/src/main/java/com/stardust/scriptdroid/record/accessibility/AccessibilityActionRecorder.java index eeb9d5da..9dd6fbf7 100644 --- a/app/src/main/java/com/stardust/scriptdroid/record/accessibility/AccessibilityActionRecorder.java +++ b/app/src/main/java/com/stardust/scriptdroid/record/accessibility/AccessibilityActionRecorder.java @@ -87,9 +87,4 @@ public class AccessibilityActionRecorder extends Recorder.DefaultIMPL implements mShouldIgnoreFirstAction = shouldIgnoreFirstAction; } - - public void setRecordMessageEnabled(boolean recordMessageEnabled) { - // TODO: 2017/3/16 添加录制提示 - mRecordMessageEnabled = recordMessageEnabled; - } } diff --git a/app/src/main/java/com/stardust/scriptdroid/service/VolumeChangeObverseService.java b/app/src/main/java/com/stardust/scriptdroid/service/VolumeChangeObverseService.java index b2b238e7..d3f19fa2 100644 --- a/app/src/main/java/com/stardust/scriptdroid/service/VolumeChangeObverseService.java +++ b/app/src/main/java/com/stardust/scriptdroid/service/VolumeChangeObverseService.java @@ -7,8 +7,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.support.annotation.Nullable; +import android.support.v7.widget.SwitchCompat; -import com.stardust.scriptdroid.external.notification.record.AccessibilityActionRecordNotification; import com.stardust.scriptdroid.record.Recorder; import com.stardust.scriptdroid.record.accessibility.AccessibilityActionRecorder; import com.stardust.scriptdroid.Pref; diff --git a/app/src/main/java/com/stardust/scriptdroid/tool/BackPressedHandler.java b/app/src/main/java/com/stardust/scriptdroid/tool/BackPressedHandler.java index 7350a3ff..e4c5c251 100644 --- a/app/src/main/java/com/stardust/scriptdroid/tool/BackPressedHandler.java +++ b/app/src/main/java/com/stardust/scriptdroid/tool/BackPressedHandler.java @@ -1,6 +1,8 @@ package com.stardust.scriptdroid.tool; import android.app.Activity; +import android.support.v4.widget.DrawerLayout; +import android.view.Gravity; import android.widget.Toast; import com.stardust.scriptdroid.R; @@ -13,7 +15,27 @@ import java.util.List; */ public interface BackPressedHandler { - boolean onBackPressed(); + boolean onBackPressed(Activity activity); + + class Observer implements BackPressedHandler { + + private List mBackPressedHandlers = new ArrayList<>(); + + @Override + public boolean onBackPressed(Activity activity) { + for (BackPressedHandler handler : mBackPressedHandlers) { + if (handler.onBackPressed(activity)) { + return true; + } + } + return false; + } + + public void registerHandler(BackPressedHandler handler) { + mBackPressedHandlers.add(handler); + } + } + class DoublePressExit implements BackPressedHandler { @@ -31,7 +53,7 @@ public interface BackPressedHandler { } @Override - public boolean onBackPressed() { + public boolean onBackPressed(Activity activity) { if (System.currentTimeMillis() - mLastPressedMillis < mDoublePressInterval) { mActivity.finish(); } else { @@ -42,22 +64,23 @@ public interface BackPressedHandler { } } - class Observer implements BackPressedHandler { + class DrawerAutoClose implements BackPressedHandler { - private List mBackPressedHandlers = new ArrayList<>(); + private DrawerLayout mDrawerLayout; + private int mGravity; + + public DrawerAutoClose(DrawerLayout drawerLayout, int gravity){ + mDrawerLayout = drawerLayout; + mGravity = gravity; + } @Override - public boolean onBackPressed() { - for (BackPressedHandler handler : mBackPressedHandlers) { - if (handler.onBackPressed()) { - return true; - } + public boolean onBackPressed(Activity activity) { + if (mDrawerLayout.isDrawerOpen(mGravity)) { + mDrawerLayout.closeDrawer(mGravity); + return true; } return false; } - - public void registerHandler(BackPressedHandler handler) { - mBackPressedHandlers.add(handler); - } } } diff --git a/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java b/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java index c429199b..0674d8c8 100644 --- a/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java +++ b/app/src/main/java/com/stardust/scriptdroid/tool/IntentTool.java @@ -17,7 +17,7 @@ public class IntentTool { public static boolean goToQQ(Context context, String qq) { try { String url = "mqqwpa://im/chat?chat_type=wpa&uin=" + qq; - context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); + context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); return true; } catch (Exception exception) { exception.printStackTrace(); @@ -33,7 +33,7 @@ public class IntentTool { * @return 返回true表示呼起手Q成功,返回false表示呼起失败 ******************/ public static boolean joinQQGroup(Context context, String key) { - Intent intent = new Intent(); + Intent intent = new Intent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key)); // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) try { @@ -48,7 +48,7 @@ public class IntentTool { public static void goToMail(Context context, String sendTo, @Nullable String title, @Nullable String content) { Uri uri = Uri.parse("mailto:" + sendTo); String[] email = {sendTo}; - Intent intent = new Intent(Intent.ACTION_SENDTO, uri); + Intent intent = new Intent(Intent.ACTION_SENDTO, uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(Intent.EXTRA_CC, email); if (title != null) intent.putExtra(Intent.EXTRA_SUBJECT, title); @@ -62,7 +62,7 @@ public class IntentTool { } public static void goToLink(Context context, String link) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)); + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java index 4a2fae2e..af6db8c0 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java @@ -10,6 +10,7 @@ import android.view.View; import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.tool.BackPressedHandler; import com.stardust.theme.ThemeColorManager; import com.stardust.theme.app.ThemeColorAppCompatActivity; @@ -27,6 +28,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; public class BaseActivity extends AppCompatActivity { protected static final int PERMISSION_REQUEST_CODE = 11186; + private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -83,4 +85,15 @@ public class BaseActivity extends AppCompatActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); } } + + public void registerBackPressedHandler(BackPressedHandler handler) { + mBackPressObserver.registerHandler(handler); + } + + @Override + public void onBackPressed() { + if (!mBackPressObserver.onBackPressed(this)) { + super.onBackPressed(); + } + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java index 6e900e7c..07b5c2c8 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/EditActivity.java @@ -185,6 +185,7 @@ public class EditActivity extends Editor920Activity { final EditorView editorView = (EditorView) findViewById(R.id.editor); mEditorDelegate.setEditorView(editorView); editorView.getEditText().setReadOnly(mReadOnly); + editorView.getEditText().setHorizontallyScrolling(true); InputMethodEnhanceBar inputMethodEnhanceBar = (InputMethodEnhanceBar) findViewById(R.id.input_method_enhance_bar); if (mReadOnly) { inputMethodEnhanceBar.setVisibility(View.GONE); diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/IridiumEditActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/IridiumEditActivity.java new file mode 100644 index 00000000..48467f6c --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/IridiumEditActivity.java @@ -0,0 +1,26 @@ +package com.stardust.scriptdroid.ui.edit; + +import android.os.Bundle; +import android.support.annotation.Nullable; + +import com.stardust.scriptdroid.ui.BaseActivity; + +import xyz.iridiumion.iridiumhighlightingeditor.editor.HighlightingDefinition; +import xyz.iridiumion.iridiumhighlightingeditor.editor.IridiumHighlightingEditorJ; +import xyz.iridiumion.iridiumhighlightingeditor.highlightingdefinitions.definitions.JavaScriptHighlightingDefinition; + +/** + * Created by Stardust on 2017/3/22. + */ + +public class IridiumEditActivity extends BaseActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + IridiumHighlightingEditorJ editorJ = new IridiumHighlightingEditorJ(this); + editorJ.setText("1234567"); + editorJ.loadHighlightingDefinition(new JavaScriptHighlightingDefinition()); + setContentView(editorJ); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java index e0eda3ab..8913e55b 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/InputMethodEnhanceBar.java @@ -57,7 +57,8 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio @Override public void onClick(View v) { int position = getChildViewHolder(v).getAdapterPosition(); - mEditTextBridge.appendText(mCodeCompletionList.get(position).getAppendText()); + if (position >= 0 && position < mCodeCompletionList.size()) + mEditTextBridge.appendText(mCodeCompletionList.get(position).getAppendText()); } }; @@ -65,6 +66,8 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio @Override public boolean onLongClick(View v) { int position = getChildViewHolder(v).getAdapterPosition(); + if (position < 0 || position >= mCodeCompletionList.size()) + return false; ((ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("", mCodeCompletionList.get(position).getDisplayText())); Toast.makeText(getContext(), R.string.text_copied, Toast.LENGTH_SHORT).show(); return true; diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/AppbarWithTabFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/AppbarWithTabFragment.java new file mode 100644 index 00000000..21079b82 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/AppbarWithTabFragment.java @@ -0,0 +1,39 @@ +package com.stardust.scriptdroid.ui.main; + +import android.os.Bundle; +import android.support.annotation.CallSuper; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import com.stardust.scriptdroid.R; + +/** + * Created by Stardust on 2017/3/23. + */ + +public abstract class AppbarWithTabFragment extends BottomNavigationFragment { + + + @Nullable + @Override + public View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_app_bar_tab, container, false); + FrameLayout contentContainer = (FrameLayout) view.findViewById(R.id.content); + contentContainer.addView(createContentView(inflater, contentContainer)); + return view; + } + + @CallSuper + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + } + + protected abstract View createContentView(LayoutInflater inflater, @Nullable ViewGroup container); +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/BottomNavigationFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/BottomNavigationFragment.java new file mode 100644 index 00000000..d76d6426 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/BottomNavigationFragment.java @@ -0,0 +1,78 @@ +package com.stardust.scriptdroid.ui.main; + + +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; + +import com.ashokvarma.bottomnavigation.BottomNavigationBar; +import com.ashokvarma.bottomnavigation.BottomNavigationItem; +import com.stardust.app.Fragment; +import com.stardust.theme.ThemeColor; +import com.stardust.theme.ThemeColorManager; +import com.stardust.theme.ThemeColorMutable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Stardust on 2017/3/23. + */ + +public abstract class BottomNavigationFragment extends Fragment { + + public static class Builder implements BottomNavigationBar.OnTabSelectedListener, ThemeColorMutable { + private int mFragmentId; + private BottomNavigationBar mBottomNavigationBar; + private FragmentManager mFragmentManager; + private List mFragments = new ArrayList<>(); + + public Builder(int fragmentId, BottomNavigationBar bottomNavigationBar, FragmentManager fragmentManager) { + mFragmentId = fragmentId; + mBottomNavigationBar = bottomNavigationBar; + mFragmentManager = fragmentManager; + mBottomNavigationBar.setTabSelectedListener(this); + ThemeColorManager.add(this); + } + + public Builder add(BottomNavigationFragment fragment) { + mFragments.add(fragment); + mBottomNavigationBar.addItem(new BottomNavigationItem(fragment.getIconResId(), fragment.getTitle())); + return this; + } + + public void build() { + mBottomNavigationBar.setFirstSelectedPosition(0); + mBottomNavigationBar.initialise(); + mFragmentManager.beginTransaction().replace(mFragmentId, mFragments.get(0)).commit(); + } + + + @Override + public void onTabSelected(int position) { + BottomNavigationFragment fragment = mFragments.get(position); + mFragmentManager.beginTransaction().replace(mFragmentId, fragment).commit(); + } + + @Override + public void onTabUnselected(int position) { + + } + + @Override + public void onTabReselected(int position) { + + } + + @Override + public void setThemeColor(ThemeColor themeColor) { + mBottomNavigationBar.setActiveColor("#" + Integer.toHexString(themeColor.colorPrimary).substring(2)); + } + } + + protected abstract String getTitle(); + + protected abstract int getIconResId(); + + +} 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 32ad1cde..f2ff1ea4 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 @@ -2,6 +2,7 @@ package com.stardust.scriptdroid.ui.main; import android.Manifest; import android.annotation.SuppressLint; +import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -12,7 +13,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; -import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; @@ -27,20 +27,19 @@ import android.widget.Toast; import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.folderselector.FileChooserDialog; -import com.stardust.app.NotRemindAgainDialog; +import com.stardust.app.FragmentPagerAdapterBuilder; +import com.stardust.app.NotAskAgainDialog; 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.external.notification.record.AccessibilityActionRecordNotification; -import com.stardust.scriptdroid.record.inputevent.InputEventRecorder; -import com.stardust.scriptdroid.record.inputevent.InputEventToJsRecorder; import com.stardust.scriptdroid.service.AccessibilityWatchDogService; import com.stardust.scriptdroid.tool.AccessibilityServiceTool; import com.stardust.scriptdroid.tool.ImageSelector; import com.stardust.scriptdroid.ui.BaseActivity; import com.stardust.scriptdroid.ui.main.my_script_list.MyScriptListFragment; import com.stardust.scriptdroid.ui.main.sample_list.SampleScriptListFragment; +import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment; import com.stardust.scriptdroid.ui.settings.SettingsActivity; import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder; import com.stardust.util.MessageEvent; @@ -50,7 +49,6 @@ import com.stardust.scriptdroid.BuildConfig; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.tool.FileUtils; import com.stardust.scriptdroid.tool.BackPressedHandler; -import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation; import com.stardust.view.ViewBinder; import com.stardust.view.accessibility.AccessibilityServiceUtils; @@ -65,39 +63,46 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File private static final String ACTION_ON_ACTION_RECORD_STOPPED = "ACTION_ON_ACTION_RECORD_STOPPED"; private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT"; - private static final String ACTION_ON_ROOT_RECORD_STOPPED = "ACTION_ON_ROOT_RECORD_STOPPED"; - private ScriptFileList mScriptFileList; private DrawerLayout mDrawerLayout; @ViewBinding.Id(R.id.bottom_menu) private SlidingUpPanel mAddBottomMenuPanel; + private FragmentPagerAdapterBuilder.StoredFragmentPagerAdapter mPagerAdapter; - private MyScriptListFragment mMyScriptListFragment; - private SampleScriptListFragment mSampleScriptListFragment; private OnActivityResultDelegate.Intermediary mActivityResultIntermediary = new OnActivityResultDelegate.Intermediary(); - private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setUpUI(); checkPermissions(); - registerBackPressHandler(); + registerBackPressHandlers(); handleIntent(getIntent()); } - private void registerBackPressHandler() { - mBackPressObserver.registerHandler(new BackPressedHandler.DoublePressExit(this)); + private void registerBackPressHandlers() { + registerBackPressedHandler(new BackPressedHandler() { + @Override + public boolean onBackPressed(Activity activity) { + if (mAddBottomMenuPanel.isShowing()) { + mAddBottomMenuPanel.dismiss(); + return true; + } + return false; + } + }); + registerBackPressedHandler(new BackPressedHandler.DrawerAutoClose(mDrawerLayout, Gravity.START)); + registerBackPressedHandler(new BackPressedHandler.DoublePressExit(this)); } private void checkPermissions() { checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE); - goToAccessibilityPermissionSettingIfDisabled(); + showAccessibilitySettingPromptIfDisabled(); } - private void goToAccessibilityPermissionSettingIfDisabled() { + private void showAccessibilitySettingPromptIfDisabled() { if (!AccessibilityServiceUtils.isAccessibilityServiceEnabled(this, AccessibilityWatchDogService.class)) { - new NotRemindAgainDialog.Builder(this, "goToAccessibilityPermissionSettingIfDisabled") + new NotAskAgainDialog.Builder(this, "showAccessibilitySettingPromptIfDisabled") .title(R.string.text_need_to_enable_accessibility_service) .content(R.string.explain_accessibility_permission) .positiveText(R.string.text_go_to_setting) @@ -123,33 +128,23 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File } private void addScriptFile(String name, String path) { - mScriptFileList.add(new ScriptFile(name, path)); + ScriptFileList.getImpl().add(new ScriptFile(name, path)); EventBus.getDefault().post(new MessageEvent(MyScriptListFragment.MESSAGE_SCRIPT_FILE_ADDED)); } private void setUpUI() { mDrawerLayout = (DrawerLayout) View.inflate(this, R.layout.activity_main, null); setContentView(mDrawerLayout); - setUpFragment(); setUpToolbar(); - setUpTabLayout(); + setUpTabViewPager(); setUpDrawerHeader(); + setUpFragment(); ViewBinder.bind(this); getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); } private void setUpFragment() { SlideMenuFragment.setFragment(this, R.id.fragment_slide_menu); - mMyScriptListFragment = new MyScriptListFragment(); - mScriptFileList = ScriptFileList.getImpl(); - mSampleScriptListFragment = new SampleScriptListFragment(); - } - - private void setUpTabLayout() { - TabLayout tabLayout = $(R.id.tab); - ViewPager viewPager = $(R.id.viewpager); - viewPager.setAdapter(new FragmentPagerAdapter()); - tabLayout.setupWithViewPager(viewPager); } @SuppressLint("SetTextI18n") @@ -164,7 +159,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File if (path != null) { setAppBarImage(path); } - $(R.id.drawer).setFitsSystemWindows(false); } private void setDrawerHeaderImage(String path) { @@ -178,13 +172,23 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File Toolbar toolbar = $(R.id.toolbar); setSupportActionBar(toolbar); toolbar.setTitle(R.string._app_name); - ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.text_drawer_open, R.string.text_drawer_close); drawerToggle.syncState(); mDrawerLayout.addDrawerListener(drawerToggle); } + private void setUpTabViewPager() { + TabLayout tabLayout = $(R.id.tab); + ViewPager viewPager = $(R.id.viewpager); + mPagerAdapter = new FragmentPagerAdapterBuilder(this) + .add(new MyScriptListFragment(), R.string.text_my_script) + .add(new SampleScriptListFragment(), R.string.text_sample_script) + .add(new TaskManagerFragment(), R.string.text_task_manage) + .build(); + viewPager.setAdapter(mPagerAdapter); + tabLayout.setupWithViewPager(viewPager); + } @ViewBinding.Click(R.id.add) private void showAddFilePanel() { @@ -218,7 +222,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File } } addScriptFile(name, path); - new ScriptFileOperation.Edit().operate(mMyScriptListFragment.getScriptListRecyclerView(), mScriptFileList, mScriptFileList.size() - 1); + ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0)).editLatest(); } else { Snackbar.make(mDrawerLayout, R.string.text_file_create_fail, Snackbar.LENGTH_LONG).show(); } @@ -232,27 +236,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File .show(); } - @ViewBinding.Click(R.id.record) - private void startScriptRecord() { - if (AccessibilityWatchDogService.getInstance() == null) { - Snackbar.make(mDrawerLayout, R.string.text_need_enable_accessibility_service_to_record, Snackbar.LENGTH_SHORT).show(); - return; - } - AccessibilityActionRecordNotification.showOrUpdateNotification(); - Snackbar.make(mDrawerLayout, R.string.hint_start_record, Snackbar.LENGTH_SHORT).show(); - } - - private InputEventRecorder mInputEventRecorder; - - @ViewBinding.Click(R.id.root_record) - private void startRootRecord() { - if (mInputEventRecorder == null) { - mInputEventRecorder = new InputEventToJsRecorder(); - mInputEventRecorder.listen(); - } - Snackbar.make(mDrawerLayout, R.string.hint_start_root_record, Snackbar.LENGTH_SHORT).show(); - } - @ViewBinding.Click(R.id.setting) private void startSettingActivity() { startActivity(new Intent(this, SettingsActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); @@ -294,13 +277,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File case ACTION_ON_ACTION_RECORD_STOPPED: handleRecordedScript(intent.getStringExtra(ARGUMENT_SCRIPT)); break; - case ACTION_ON_ROOT_RECORD_STOPPED: - if (mInputEventRecorder != null) { - mInputEventRecorder.stop(); - handleRecordedScript(mInputEventRecorder.getCode()); - mInputEventRecorder = null; - } - break; } } @@ -329,19 +305,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File }) .canceledOnTouchOutside(false) .show(); - - } - - - @Override - public void onBackPressed() { - if (mAddBottomMenuPanel.isShowing()) { - mAddBottomMenuPanel.dismiss(); - } else if (mDrawerLayout.isDrawerOpen(Gravity.START)) { - mDrawerLayout.closeDrawer(Gravity.START); - } else { - mBackPressObserver.onBackPressed(); - } } @Override @@ -362,14 +325,6 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File context.startActivity(intent); } - - public static void onRootRecordStopped(Context context) { - Intent intent = new Intent(context, MainActivity.class) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .putExtra(EXTRA_ACTION, ACTION_ON_ROOT_RECORD_STOPPED); - context.startActivity(intent); - } - @ViewBinding.Click(R.id.toolbar) public void OnToolbarClick() { new ImageSelector(this, mActivityResultIntermediary, new ImageSelector.ImageSelectorCallback() { @@ -385,29 +340,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File private void setAppBarImage(String path) { Drawable d = BitmapDrawable.createFromPath(path); if (d != null) { - $(R.id.app_bar).setBackground(d); - } - } - - private class FragmentPagerAdapter extends android.support.v4.app.FragmentPagerAdapter { - - FragmentPagerAdapter() { - super(MainActivity.this.getSupportFragmentManager()); - } - - @Override - public Fragment getItem(int position) { - return position == 0 ? mMyScriptListFragment : mSampleScriptListFragment; - } - - @Override - public int getCount() { - return 2; - } - - @Override - public CharSequence getPageTitle(int position) { - return getString(position == 0 ? R.string.text_my_script : R.string.text_sample_script); + ((ImageView) $(R.id.app_bar_bg)).setImageDrawable(d); } } 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 ffef581e..6ec591b4 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 @@ -4,6 +4,7 @@ import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; +import android.support.v4.app.FragmentActivity; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.SwitchCompat; import android.view.LayoutInflater; @@ -33,7 +34,7 @@ import org.greenrobot.eventbus.Subscribe; public class SlideMenuFragment extends Fragment { - public static void setFragment(AppCompatActivity activity, int viewId) { + public static void setFragment(FragmentActivity activity, int viewId) { SlideMenuFragment fragment = new SlideMenuFragment(); activity.getSupportFragmentManager().beginTransaction().replace(viewId, fragment).commit(); } 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 ff02fb6e..55253058 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 @@ -1,5 +1,6 @@ package com.stardust.scriptdroid.ui.main.my_script_list; +import android.app.Activity; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; @@ -12,6 +13,8 @@ import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.droid.script.file.ScriptFileList; import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList; import com.stardust.scriptdroid.tool.BackPressedHandler; +import com.stardust.scriptdroid.ui.BaseActivity; +import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation; import com.stardust.util.MessageEvent; import com.stardust.widget.SimpleAdapterDataObserver; @@ -30,10 +33,14 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler private ScriptFileList mScriptFileList; private View mNoScriptHint; + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); EventBus.getDefault().register(this); + if(!(getActivity() instanceof BaseActivity)){ + throw new IllegalArgumentException("The fragment can only be used in BaseActivity"); + } } @Nullable @@ -61,8 +68,9 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler mScriptListRecyclerView.setScriptFileList(mScriptFileList); } + //// FIXME: 2017/3/24 @Override - public boolean onBackPressed() { + public boolean onBackPressed(Activity activity) { if (mScriptListRecyclerView.getScriptFileOperationPopupMenu().isShowing()) { mScriptListRecyclerView.getScriptFileOperationPopupMenu().dismiss(); return true; @@ -98,4 +106,8 @@ public class MyScriptListFragment extends Fragment implements BackPressedHandler super.onDestroy(); EventBus.getDefault().unregister(this); } + + public void editLatest() { + ScriptFileOperation.Edit.getInstance().operate(mScriptListRecyclerView, mScriptFileList, mScriptFileList.size() - 1); + } } 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 2407e25a..3b0a7e2e 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 @@ -12,6 +12,7 @@ import com.stardust.scriptdroid.droid.script.file.ScriptFileList; import com.stardust.scriptdroid.external.shortcut.Shortcut; import com.stardust.scriptdroid.external.shortcut.ShortcutActivity; import com.stardust.scriptdroid.ui.edit.EditActivity; +import com.stardust.scriptdroid.ui.edit.IridiumEditActivity; import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder; import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.R; @@ -67,14 +68,28 @@ public abstract class ScriptFileOperation { public static class Edit extends ScriptFileOperation { + private static Edit instance = new Edit(); + public Edit() { super(App.getApp().getString(R.string.text_edit), R.drawable.ic_edit_green_48dp); } + public static Edit getInstance() { + return instance; + } + + public static void setInstance(Edit instance) { + Edit.instance = instance; + } + @Override public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) { ScriptFile scriptFile = scriptFileList.get(position); EditActivity.editFile(App.getApp(), scriptFile.name, scriptFile.path); + //脚本 + //任务&控制台 + //教程 + // } } @@ -88,7 +103,7 @@ public abstract class ScriptFileOperation { public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) { ScriptFile scriptFile = scriptFileList.get(position); Uri uri = Uri.parse("file://" + scriptFile.path); - App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain")); + App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } } @@ -156,7 +171,8 @@ public abstract class ScriptFileOperation { public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) { boolean succeed = scriptFileList.deleteFromFileSystem(position); EventBus.getDefault().post(new ShowMessageEvent(succeed ? R.string.text_already_delete : R.string.text_delete_failed)); - recyclerView.getAdapter().notifyItemRemoved(position); + if (succeed) + recyclerView.getAdapter().notifyItemRemoved(position); } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerFragment.java new file mode 100644 index 00000000..ada56a97 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerFragment.java @@ -0,0 +1,21 @@ +package com.stardust.scriptdroid.ui.main.task; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.stardust.app.Fragment; + +/** + * Created by Stardust on 2017/3/24. + */ + +public class TaskManagerFragment extends Fragment { + @Nullable + @Override + public View createView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return null; + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerRecyclerView.java new file mode 100644 index 00000000..75711884 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerRecyclerView.java @@ -0,0 +1,8 @@ +package com.stardust.scriptdroid.ui.main.task; + +/** + * Created by Stardust on 2017/3/24. + */ + +public class TaskManagerRecyclerView { +} diff --git a/app/src/main/java/com/stardust/widget/CommonMarkdownView.java b/app/src/main/java/com/stardust/widget/CommonMarkdownView.java index 438d4a38..14c732bc 100644 --- a/app/src/main/java/com/stardust/widget/CommonMarkdownView.java +++ b/app/src/main/java/com/stardust/widget/CommonMarkdownView.java @@ -57,13 +57,13 @@ public class CommonMarkdownView extends WebView { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(request.getUrl())); + getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(request.getUrl()).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); return true; } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url))); + getContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); return true; } diff --git a/app/src/main/res/drawable/toolbar_bg_top_clip.xml b/app/src/main/res/drawable/toolbar_bg_top_clip.xml new file mode 100644 index 00000000..9ef38de1 --- /dev/null +++ b/app/src/main/res/drawable/toolbar_bg_top_clip.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index ce5a1526..9a955976 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -12,14 +12,22 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + + + app:tabSelectedTextColor="@android:color/primary_text_dark" + app:tabTextColor="@android:color/secondary_text_dark"/> - + - - - - - - - - - - - - - - - - - @@ -182,6 +143,7 @@ android:layout_width="304dp" android:layout_height="match_parent" android:layout_gravity="start" + android:fitsSystemWindows="false" /> diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index a9db875c..7242fc4b 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -1,11 +1,12 @@ - @@ -13,8 +14,8 @@ - - + diff --git a/app/src/main/res/layout/fragment_app_bar_tab.xml b/app/src/main/res/layout/fragment_app_bar_tab.xml new file mode 100644 index 00000000..f5f3cf7a --- /dev/null +++ b/app/src/main/res/layout/fragment_app_bar_tab.xml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_manager.xml b/app/src/main/res/layout/fragment_manager.xml new file mode 100644 index 00000000..3a15e832 --- /dev/null +++ b/app/src/main/res/layout/fragment_manager.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_scripts.xml b/app/src/main/res/layout/fragment_scripts.xml new file mode 100644 index 00000000..065023e1 --- /dev/null +++ b/app/src/main/res/layout/fragment_scripts.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 94f0073d..10074b9a 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -1,5 +1,6 @@ + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3f85471b..ddd5712c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -177,6 +177,9 @@ KEY_SINGLE_THREAD 已开启 已关闭 + 脚本 + 管理 + 任务管理 diff --git a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java index 05ea5e18..94291852 100644 --- a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java +++ b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java @@ -2,15 +2,23 @@ package com.stardust.scriptdroid; import com.stardust.scriptdroid.droid.script.JavaScriptEngine; import com.stardust.scriptdroid.droid.script.RhinoJavaScriptEngine; +import com.stardust.scriptdroid.droid.script.file.ScriptFile; import com.stardust.scriptdroid.record.inputevent.InputEventToJsConverter; import org.junit.Test; import org.mozilla.javascript.Context; import org.mozilla.javascript.ImporterTopLevel; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.commonjs.module.RequireBuilder; +import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider; +import org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider; +import java.io.File; import java.lang.reflect.Array; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -27,80 +35,63 @@ import static org.junit.Assert.assertEquals; */ public class ExampleUnitTest { // TODO: 2017/3/3 自定义函数 - // TODO: 2017/3/19 + // TODO: 2017/3/19 exist函数 + // TODO: 2017/3/23 tasker插件 + // TODO: 2017/3/23 任务管理与控制台 + // TODO: 2017/3/23 悬浮窗加入控制台 + // TODO: 2017/3/24 文件读写api + // TODO: 2017/3/24 网络读写api + // TODO: 2017/3/24 常驻后台api + // TODO: 2017/3/24 ui。E4x + // TODO: 2017/3/24 编辑界面文档和自动补全 + // TODO: 2017/3/24 驻留模式 + + + // FIXME: 2017/3/23 死机重启问题 + // FIXME: 2017/3/23 卡顿问题 - Counter counter = new Counter(5); - private List mIntegers = new ArrayList<>(); @Test public void test() { - 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(); + + List paths = Collections.singletonList(new File("D:/js/").toURI()); + Context ctx = Context.enter(); + ctx.setOptimizationLevel(-1); + ctx.setLanguageVersion(Context.VERSION_1_7); + ctx.setInstructionObserverThreshold(10000); + ImporterTopLevel scope = new ImporterTopLevel(); + scope.initStandardObjects(ctx, false); + + new RequireBuilder() + .setModuleScriptProvider(new SoftCachingModuleScriptProvider( + new UrlModuleSourceProvider(paths, null))) + .setSandboxed(true) + .createRequire(ctx, scope) + .install(scope); + + + ctx.evaluateString(scope, "require('test.js')()", "", 1, null); + + Context.exit(); } - 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(); - } - } - } + @Test + public void test2(){ + Context context = Context.enter(); + context.setOptimizationLevel(-1); + context.setLanguageVersion(Context.VERSION_1_7); + context.setInstructionObserverThreshold(10000); + ImporterTopLevel scope = new ImporterTopLevel(); + scope.initStandardObjects(context, false); + List paths = Collections.singletonList(new File("D:/js/").toURI()); + new RequireBuilder() + .setModuleScriptProvider(new SoftCachingModuleScriptProvider( + new UrlModuleSourceProvider(paths, null))) + .setSandboxed(true) + .createRequire(context, scope) + .install(scope); + context.evaluateString(scope, "require('test.js')()", "", 1, null); + Context.exit(); } } \ No newline at end of file diff --git a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityAllocator.java b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityAllocator.java new file mode 100644 index 00000000..0140d090 --- /dev/null +++ b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityAllocator.java @@ -0,0 +1,37 @@ +package com.stardust.view.accessibility; + +import android.view.accessibility.AccessibilityNodeInfo; + +import java.util.List; +import java.util.Vector; + +/** + * Created by Stardust on 2017/3/22. + */ + +public class AccessibilityAllocator { + + + private List mAccessibilityNodeInfoList = new Vector<>(); + + public AccessibilityNodeInfo getChild(AccessibilityNodeInfo parent, int i) { + return add(parent.getChild(i)); + } + + private AccessibilityNodeInfo add(AccessibilityNodeInfo nodeInfo) { + mAccessibilityNodeInfoList.add(nodeInfo); + return nodeInfo; + } + + public int recycleAll() { + int recycled = 0; + for (AccessibilityNodeInfo nodeInfo : mAccessibilityNodeInfoList) { + try { + nodeInfo.recycle(); + recycled++; + } catch (IllegalStateException ignored) { + } + } + return recycled; + } +}