diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 85fc7dc2..471e75c0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -80,7 +80,7 @@ diff --git a/app/src/main/java/com/stardust/UIActionPerformActivity.java b/app/src/main/java/com/stardust/UIActionPerformActivity.java deleted file mode 100644 index 25865fda..00000000 --- a/app/src/main/java/com/stardust/UIActionPerformActivity.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.stardust; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; - -import com.stardust.scriptdroid.App; -import com.stardust.scriptdroid.droid.runtime.DroidRuntime; - - -/** - * Created by Stardust on 2017/1/31. - */ - -public class UIActionPerformActivity extends AppCompatActivity { - - - private static volatile UIAction action; - - public static void performAction(UIAction action) { - if (UIActionPerformActivity.action != null) { - return; - } - UIActionPerformActivity.action = action; - App.getApp().startActivity(new Intent(App.getApp(), UIActionPerformActivity.class)); - } - - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - DroidRuntime.setContext(this); - action.setActivity(this).run(); - } - - - public abstract static class UIAction implements Runnable { - - protected Activity mActivity; - - public UIAction setActivity(Activity activity) { - mActivity = activity; - return this; - } - - } - - -} diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java index 8d2e3d0f..39eef9df 100644 --- a/app/src/main/java/com/stardust/scriptdroid/App.java +++ b/app/src/main/java/com/stardust/scriptdroid/App.java @@ -1,8 +1,10 @@ package com.stardust.scriptdroid; import android.app.Application; +import android.preference.PreferenceManager; import com.stardust.util.CrashHandler; +import com.stardust.util.StateObserver; /** * Created by Stardust on 2017/1/27. @@ -11,14 +13,21 @@ import com.stardust.util.CrashHandler; public class App extends Application { private static App instance; + private static StateObserver stateObserver; public static App getApp() { return instance; } + public static StateObserver getStateObserver() { + return stateObserver; + } + + public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class)); instance = this; + stateObserver = new StateObserver(PreferenceManager.getDefaultSharedPreferences(this)); } } diff --git a/app/src/main/java/com/stardust/scriptdroid/AssistModeSwitchService.java b/app/src/main/java/com/stardust/scriptdroid/AssistModeSwitchService.java index 9e5f4c66..c523d7c3 100644 --- a/app/src/main/java/com/stardust/scriptdroid/AssistModeSwitchService.java +++ b/app/src/main/java/com/stardust/scriptdroid/AssistModeSwitchService.java @@ -7,7 +7,8 @@ import android.os.IBinder; import android.support.annotation.Nullable; import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService; -import com.stardust.scriptdroid.ui.AssistModeSwitchNotification; + +import static com.stardust.scriptdroid.ui.AssistModeSwitchNotification.KEY_ASSIST_MODE_NOTIFICATION; /** * Created by Stardust on 2017/2/2. @@ -18,19 +19,19 @@ public class AssistModeSwitchService extends Service { Intent intent = new Intent(App.getApp(), AssistModeSwitchService.class) .putExtra("intentValid", true) .putExtra("switch", "assistMode"); - return PendingIntent.getService(App.getApp(), 0, intent, 0); + return PendingIntent.getService(App.getApp(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } @Override public int onStartCommand(Intent intent, int flags, int startId) { boolean intentValid = intent.getBooleanExtra("intentValid", false); if (intentValid) { - String action = intent.getStringExtra("action"); + String action = intent.getStringExtra("switch"); if (action != null) { if (action.equals("assistMode")) { ActionPerformService.setAssistModeEnable(!ActionPerformService.isAssistModeEnable()); } else { - AssistModeSwitchNotification.setEnable(false); + App.getStateObserver().setState(KEY_ASSIST_MODE_NOTIFICATION, false); } } } @@ -48,6 +49,6 @@ public class AssistModeSwitchService extends Service { Intent deleteIntent = new Intent(App.getApp(), AssistModeSwitchService.class) .putExtra("intentValid", true) .putExtra("switch", "assistModeNotification"); - return PendingIntent.getService(App.getApp(), 0, deleteIntent, 0); + return PendingIntent.getService(App.getApp(), 0, deleteIntent, PendingIntent.FLAG_ONE_SHOT); } } diff --git a/app/src/main/java/com/stardust/EditAndRunIntentActivity.java b/app/src/main/java/com/stardust/scriptdroid/EditAndRunIntentActivity.java similarity index 95% rename from app/src/main/java/com/stardust/EditAndRunIntentActivity.java rename to app/src/main/java/com/stardust/scriptdroid/EditAndRunIntentActivity.java index 2f05de55..87ab924c 100644 --- a/app/src/main/java/com/stardust/EditAndRunIntentActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/EditAndRunIntentActivity.java @@ -1,4 +1,4 @@ -package com.stardust; +package com.stardust.scriptdroid; import android.content.Intent; import android.os.Bundle; diff --git a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformService.java b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformService.java index c07a9f23..0caccb08 100644 --- a/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformService.java +++ b/app/src/main/java/com/stardust/scriptdroid/droid/runtime/action/ActionPerformService.java @@ -3,7 +3,6 @@ package com.stardust.scriptdroid.droid.runtime.action; import android.accessibilityservice.AccessibilityService; import android.content.ClipData; import android.content.ClipboardManager; -import android.content.Intent; import android.graphics.Rect; import android.os.Build; import android.preference.PreferenceManager; @@ -28,12 +27,8 @@ import java.util.List; public class ActionPerformService extends AccessibilityService { - - public static final String ACTION_CHANGE_ASSIST_MODE = App.getApp().getPackageName() + ".ACTION_CHANGE_ASSIST_MODE"; - - private static final String TAG = "ActionPerformService"; - private static final String KEY_ASSIST_MODE_ENABLE = "ASSIST_MODE_ENABLE"; + public static final String KEY_ASSIST_MODE_ENABLE = "ASSIST_MODE_ENABLE"; private static ActionPerformService instance; @SuppressWarnings("unchecked") @@ -69,8 +64,7 @@ public class ActionPerformService extends AccessibilityService { public static void setAssistModeEnable(boolean assistModeEnable) { ActionPerformService.assistModeEnable = assistModeEnable; - PreferenceManager.getDefaultSharedPreferences(App.getApp()).edit().putBoolean(KEY_ASSIST_MODE_ENABLE, assistModeEnable).apply(); - App.getApp().sendBroadcast(new Intent(ACTION_CHANGE_ASSIST_MODE).putExtra("enable", assistModeEnable)); + App.getStateObserver().setState(KEY_ASSIST_MODE_ENABLE, assistModeEnable); } @Override diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/AssistModeSwitchNotification.java b/app/src/main/java/com/stardust/scriptdroid/ui/AssistModeSwitchNotification.java index 22f39687..f1779e4e 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/AssistModeSwitchNotification.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/AssistModeSwitchNotification.java @@ -10,6 +10,9 @@ import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.AssistModeSwitchService; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService; +import com.stardust.util.StateObserver; + +import static com.stardust.scriptdroid.droid.runtime.action.ActionPerformService.KEY_ASSIST_MODE_ENABLE; /** * Created by Stardust on 2017/2/2. @@ -18,19 +21,46 @@ import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService; public class AssistModeSwitchNotification { private static final int NOTIFY_ID = 11126; - private static final String KEY_ASSIST_MODE_NOTIFICATION = "KEY_ASSIST_MODE_NOTIFICATION"; + public static final String KEY_ASSIST_MODE_NOTIFICATION = "KEY_ASSIST_MODE_NOTIFICATION"; private static boolean enable = false; private static Notification notification; - static { - readPreference(); - } - public static boolean isEnable() { return enable; } + static { + App.getStateObserver().register(KEY_ASSIST_MODE_NOTIFICATION, new StateObserver.OnBooleanStateChangedListener() { + @Override + public void onStateChanged(Boolean newState) { + setEnable(newState); + } + + @Override + public void initState(Boolean state) { + enable = state; + if (enable) { + showNotification(); + } + } + }); + App.getStateObserver().register(KEY_ASSIST_MODE_ENABLE, new StateObserver.OnBooleanStateChangedListener() { + @Override + public void onStateChanged(Boolean newState) { + if (enable) { + setEnable(false); + setEnable(true); + } + } + + @Override + public void initState(Boolean state) { + + } + }); + } + public static void setEnable(boolean enable) { if (AssistModeSwitchNotification.enable == enable) return; @@ -43,13 +73,6 @@ public class AssistModeSwitchNotification { } } - public static void notifyAssistModeChanged() { - if (enable) { - setEnable(false); - setEnable(true); - } - } - private static void showNotification() { notification = new NotificationCompat.Builder(App.getApp()) @@ -74,10 +97,4 @@ public class AssistModeSwitchNotification { notificationManager.cancel(NOTIFY_ID); } - - private static void readPreference() { - enable = PreferenceManager.getDefaultSharedPreferences(App.getApp()).getBoolean(KEY_ASSIST_MODE_NOTIFICATION, false); - setEnable(enable); - } - } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java new file mode 100644 index 00000000..24ba7a5e --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/EditSideMenuFragment.java @@ -0,0 +1,20 @@ +package com.stardust.scriptdroid.ui; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * Created by Stardust on 2017/2/4. + */ + +public class EditSideMenuFragment extends com.stardust.app.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/SlideMenuFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java index ab78b10e..89b652d7 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/SlideMenuFragment.java @@ -1,9 +1,6 @@ package com.stardust.scriptdroid.ui; -import android.content.BroadcastReceiver; -import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; @@ -14,6 +11,7 @@ import android.view.View; import android.view.ViewGroup; import com.stardust.app.Fragment; +import com.stardust.scriptdroid.App; import com.stardust.scriptdroid.DocumentActivity; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.droid.Droid; @@ -22,7 +20,8 @@ import com.stardust.view.ViewBinder; import com.stardust.view.ViewBinding; import com.stardust.view.accessibility.AccessibilityServiceUtils; -import static com.stardust.scriptdroid.droid.runtime.action.ActionPerformService.ACTION_CHANGE_ASSIST_MODE; +import static com.stardust.scriptdroid.droid.runtime.action.ActionPerformService.KEY_ASSIST_MODE_ENABLE; +import static com.stardust.scriptdroid.ui.AssistModeSwitchNotification.KEY_ASSIST_MODE_NOTIFICATION; /** * Created by Stardust on 2017/1/30. @@ -37,7 +36,6 @@ public class SlideMenuFragment extends Fragment { } private SwitchCompat mAutoOperateServiceSwitch, mAssistServiceSwitch, mAssistServiceNotificationSwitch; - private Receiver mReceiver = new Receiver(); @Nullable @Override @@ -51,9 +49,6 @@ public class SlideMenuFragment extends Fragment { if (mAutoOperateServiceSwitch == null) { setUpSwitchCompat(); ViewBinder.bind(this); - IntentFilter filter = new IntentFilter(); - filter.addAction(ACTION_CHANGE_ASSIST_MODE); - getContext().registerReceiver(mReceiver, filter); } syncSwitchState(); } @@ -73,6 +68,8 @@ public class SlideMenuFragment extends Fragment { mAutoOperateServiceSwitch = $(R.id.sw_auto_operate_service); mAssistServiceSwitch = $(R.id.sw_assist_service); mAssistServiceNotificationSwitch = $(R.id.sw_assist_service_notification); + App.getStateObserver().register(KEY_ASSIST_MODE_ENABLE, mAssistServiceSwitch); + App.getStateObserver().register(KEY_ASSIST_MODE_NOTIFICATION, mAssistServiceNotificationSwitch); } @ViewBinding.Click(R.id.syntax_and_api) @@ -97,7 +94,6 @@ public class SlideMenuFragment extends Fragment { @ViewBinding.Check(R.id.sw_assist_service) private void setAssistServiceEnable(boolean enable) { ActionPerformService.setAssistModeEnable(enable); - AssistModeSwitchNotification.notifyAssistModeChanged(); } @ViewBinding.Click(R.id.assist_service) @@ -126,21 +122,7 @@ public class SlideMenuFragment extends Fragment { @Override public void onDestroy() { - getContext().unregisterReceiver(mReceiver); super.onDestroy(); } - private class Receiver extends BroadcastReceiver { - - - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(ACTION_CHANGE_ASSIST_MODE)) { - AssistModeSwitchNotification.notifyAssistModeChanged(); - mAssistServiceSwitch.setChecked(intent.getBooleanExtra("enable", false)); - } - } - } - - } diff --git a/app/src/main/java/com/stardust/util/CrashHandler.java b/app/src/main/java/com/stardust/util/CrashHandler.java index 9006246d..3e513fe8 100644 --- a/app/src/main/java/com/stardust/util/CrashHandler.java +++ b/app/src/main/java/com/stardust/util/CrashHandler.java @@ -41,6 +41,7 @@ public class CrashHandler implements UncaughtExceptionHandler { public static String throwableToString(Throwable throwable) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); + throwable.printStackTrace(); throwable.printStackTrace(pw); return sw.toString(); } diff --git a/app/src/main/java/com/stardust/util/StateObserver.java b/app/src/main/java/com/stardust/util/StateObserver.java new file mode 100644 index 00000000..0517889e --- /dev/null +++ b/app/src/main/java/com/stardust/util/StateObserver.java @@ -0,0 +1,125 @@ +package com.stardust.util; + +import android.content.SharedPreferences; +import android.support.v7.widget.SwitchCompat; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by Stardust on 2017/2/3. + */ + +public class StateObserver { + + public interface OnStateChangedListener { + + void onStateChanged(T newState); + + void initState(T state); + } + + + public static abstract class SimpleOnStateChangedListener implements OnStateChangedListener { + + @Override + public void initState(T state) { + onStateChanged(state); + } + } + + public interface OnBooleanStateChangedListener extends OnStateChangedListener { + + } + + public static abstract class SimpleOnBooleanStateChangedListener implements OnBooleanStateChangedListener { + + @Override + public void initState(Boolean state) { + onStateChanged(state); + } + } + + + private final Map> mKeyStateListenersMap = new HashMap<>(); + private SharedPreferences mSharedPreferences; + + public StateObserver(SharedPreferences sharedPreferences) { + mSharedPreferences = sharedPreferences; + } + + public void register(final String key, SwitchCompat switchCompat) { + final WeakReference switchCompatWeakReference = new WeakReference<>(switchCompat); + register(key, new SimpleOnBooleanStateChangedListener() { + @Override + public void onStateChanged(Boolean newState) { + if (switchCompatWeakReference.get() != null) { + switchCompatWeakReference.get().setChecked(newState); + } else { + unregister(key, this); + } + } + }); + } + + public void register(String key, OnStateChangedListener listener) { + T initialState = readState(key, listener); + if (initialState != null) + listener.initState(initialState); + synchronized (mKeyStateListenersMap) { + getListenerListOrCreateIfNotExists(key).add(listener); + } + } + + + private void unregister(String key, OnStateChangedListener stateChangedListener) { + synchronized (mKeyStateListenersMap) { + List listeners = mKeyStateListenersMap.get(key); + if (listeners == null) { + return; + } + listeners.remove(stateChangedListener); + } + } + + public void setState(String key, T state) { + synchronized (mKeyStateListenersMap) { + List listeners = mKeyStateListenersMap.get(key); + if (listeners == null || listeners.isEmpty()) { + return; + } + if (listeners.get(0) instanceof OnBooleanStateChangedListener) { + mSharedPreferences.edit().putBoolean(key, (Boolean) state).apply(); + notifyBooleanStateChanged(listeners, (Boolean) state); + } + } + } + + private void notifyBooleanStateChanged(List listeners, boolean state) { + for (OnStateChangedListener listener : listeners) { + listener.onStateChanged(state); + } + } + + @SuppressWarnings("unchecked") + protected T readState(String key, OnStateChangedListener listener) { + if (listener instanceof OnBooleanStateChangedListener) { + return mSharedPreferences.contains(key) ? (T) Boolean.valueOf(mSharedPreferences.getBoolean(key, false)) : null; + } + return null; + } + + private List getListenerListOrCreateIfNotExists(String key) { + List listeners = mKeyStateListenersMap.get(key); + if (listeners == null) { + listeners = new ArrayList<>(); + mKeyStateListenersMap.put(key, listeners); + } + return listeners; + } + + +}