From 18ecb626056de308bed0eb79a88968b617663005 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Wed, 16 Jun 2021 18:26:32 +0800 Subject: [PATCH] Listen to wallpaper change and change theme. --- app/src/main/AndroidManifest.xml | 7 +- .../infinityforreddit/AppComponent.java | 3 + .../infinityforreddit/Infinity.java | 4 + .../WallpaperChangeReceiver.java | 21 ++++ .../services/MaterialYouService.java | 46 ++++++++ .../settings/ThemePreferenceFragment.java | 90 ++-------------- .../utils/MaterialYouUtils.java | 101 ++++++++++++++++++ 7 files changed, 187 insertions(+), 85 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/services/MaterialYouService.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/MaterialYouUtils.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4cde57e7..5e6fbdc6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,7 +32,8 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true" tools:replace="android:label"> - + + \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index 922642f2..939858c7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -73,6 +73,7 @@ import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryImageOrGi import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryVideoFragment; import ml.docilealligator.infinityforreddit.services.DownloadMediaService; import ml.docilealligator.infinityforreddit.services.DownloadRedditVideoService; +import ml.docilealligator.infinityforreddit.services.MaterialYouService; import ml.docilealligator.infinityforreddit.services.SubmitPostService; import ml.docilealligator.infinityforreddit.settings.AdvancedPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.CrashReportsFragment; @@ -266,4 +267,6 @@ public interface AppComponent { void inject(AnonymousSubscriptionsActivity anonymousSubscriptionsActivity); void inject(LockScreenActivity lockScreenActivity); + + void inject(MaterialYouService materialYouService); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java index 1514b745..1ea45d67 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java @@ -1,6 +1,7 @@ package ml.docilealligator.infinityforreddit; import android.app.Application; +import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.os.Bundle; @@ -16,6 +17,7 @@ import com.livefront.bridge.SavedStateHandler; import org.greenrobot.eventbus.EventBus; import ml.docilealligator.infinityforreddit.broadcastreceivers.NetworkWifiStatusReceiver; +import ml.docilealligator.infinityforreddit.broadcastreceivers.WallpaperChangeReceiver; import ml.docilealligator.infinityforreddit.events.ChangeNetworkStatusEvent; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -87,6 +89,8 @@ public class Infinity extends Application implements LifecycleObserver { mNetworkWifiStatusReceiver = new NetworkWifiStatusReceiver(() -> EventBus.getDefault().post(new ChangeNetworkStatusEvent(Utils.getConnectedNetwork(getApplicationContext())))); registerReceiver(mNetworkWifiStatusReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); + + registerReceiver(new WallpaperChangeReceiver(), new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); } // @OnLifecycleEvent(Lifecycle.Event.ON_START) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java new file mode 100644 index 00000000..b2e64fb9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/WallpaperChangeReceiver.java @@ -0,0 +1,21 @@ +package ml.docilealligator.infinityforreddit.broadcastreceivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import java.util.Objects; + +import ml.docilealligator.infinityforreddit.services.MaterialYouService; + +public class WallpaperChangeReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Log.i("asfasdf", "s " + intent.getAction()); + if (Objects.equals(intent.getAction(), "android.intent.action.WALLPAPER_CHANGED")) { + Intent materialYouIntent = new Intent(context, MaterialYouService.class); + context.startService(materialYouIntent); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/MaterialYouService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/MaterialYouService.java new file mode 100644 index 00000000..ec4448ff --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/MaterialYouService.java @@ -0,0 +1,46 @@ +package ml.docilealligator.infinityforreddit.services; + +import android.app.IntentService; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Handler; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils; + +public class MaterialYouService extends IntentService { + + @Inject + @Named("light_theme") + SharedPreferences lightThemeSharedPreferences; + @Inject + @Named("dark_theme") + SharedPreferences darkThemeSharedPreferences; + @Inject + @Named("amoled_theme") + SharedPreferences amoledThemeSharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + @Inject + Executor executor; + + public MaterialYouService() { + super("MaterialYouService"); + } + + @Override + protected void onHandleIntent(Intent intent) { + ((Infinity) getApplication()).getAppComponent().inject(this); + MaterialYouUtils.changeTheme(this, executor, new Handler(), customThemeWrapper, + lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java index 292d7bcf..c4d03d48 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java @@ -1,17 +1,13 @@ package ml.docilealligator.infinityforreddit.settings; -import android.app.WallpaperColors; -import android.app.WallpaperManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; -import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; @@ -39,6 +35,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeViewModel; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; @@ -174,65 +171,12 @@ public class ThemePreferenceFragment extends PreferenceFragmentCompat { if (enableMaterialYouSwitchPreference != null) { Handler handler = new Handler(); - enableMaterialYouSwitchPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (true) { - executor.execute(() -> { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { - WallpaperManager wallpaperManager = WallpaperManager.getInstance(activity); - WallpaperColors wallpaperColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM); - - if (wallpaperColors != null) { - int colorPrimaryInt = shiftColorTo255(wallpaperColors.getPrimaryColor().toArgb(), 0.4); - int colorPrimaryDarkInt = shiftColorTo0(colorPrimaryInt, 0.4); - int backgroundColor = shiftColorTo255(colorPrimaryInt, 0.6); - int cardViewBackgroundColor = shiftColorTo255(colorPrimaryInt, 0.9); - Color colorAccent = wallpaperColors.getSecondaryColor(); - int colorAccentInt = shiftColorTo255(colorAccent == null ? customThemeWrapper.getColorAccent() : colorAccent.toArgb(), 0.4); - - int colorPrimaryAppropriateTextColor = getAppropriateTextColor(colorPrimaryInt); - int backgroundColorAppropriateTextColor = getAppropriateTextColor(backgroundColor); - - lightThemeSharedPreferences.edit().putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_DARK, colorPrimaryDarkInt) - .putInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, colorAccentInt) - .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.BACKGROUND_COLOR, backgroundColor) - .putInt(CustomThemeSharedPreferencesUtils.CARD_VIEW_BACKGROUND_COLOR, cardViewBackgroundColor) - .putInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_BACKGROUND_COLOR, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.NAV_BAR_COLOR, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.PRIMARY_TEXT_COLOR, backgroundColorAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_ICON_COLOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.PRIMARY_ICON_COLOR, backgroundColorAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.FAB_ICON_COLOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.TOOLBAR_SECONDARY_TEXT_COLOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR, colorPrimaryAppropriateTextColor) - .putInt(CustomThemeSharedPreferencesUtils.CIRCULAR_PROGRESS_BAR_BACKGROUND, colorPrimaryInt) - .putBoolean(CustomThemeSharedPreferencesUtils.LIGHT_STATUS_BAR, getAppropriateTextColor(colorPrimaryDarkInt) == Color.toArgb(Color.BLACK)) - .apply(); - darkThemeSharedPreferences.edit() - .putInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, colorPrimaryInt) - .apply(); - amoledThemeSharedPreferences.edit() - .putInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, colorPrimaryInt) - .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, colorPrimaryInt) - .apply(); - - handler.post(() -> EventBus.getDefault().post(new RecreateActivityEvent())); - } - } - }); - } - return true; + enableMaterialYouSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { + if (true) { + MaterialYouUtils.changeTheme(activity, executor, new Handler(), customThemeWrapper, + lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences); } + return true; }); } @@ -271,28 +215,6 @@ public class ThemePreferenceFragment extends PreferenceFragmentCompat { }); } - private int shiftColorTo255(int color, double ratio) { - int offset = (int) (Math.min(Math.min(255 - Color.red(color), 255 - Color.green(color)), 255 - Color.blue(color)) * ratio); - return Color.argb(Color.alpha(color), Color.red(color) + offset, - Color.green(color) + offset, - Color.blue(color) + offset); - } - - private int shiftColorTo0(int color, double ratio) { - int offset = (int) (Math.min(Math.min(Color.red(color), Color.green(color)), Color.blue(color)) * ratio); - return Color.argb(Color.alpha(color), Color.red(color) - offset, - Color.green(color) - offset, - Color.blue(color) - offset); - - } - - @ColorInt - public int getAppropriateTextColor(@ColorInt int color) { - // Counting the perceptive luminance - human eye favors green color... - double luminance = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255; - return luminance < 0.5 ? Color.BLACK : Color.WHITE; - } - @Override public void onAttach(@NonNull Context context) { super.onAttach(context); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/MaterialYouUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/MaterialYouUtils.java new file mode 100644 index 00000000..51199bea --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/MaterialYouUtils.java @@ -0,0 +1,101 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.app.WallpaperColors; +import android.app.WallpaperManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.os.Build; +import android.os.Handler; + +import androidx.annotation.ColorInt; + +import org.greenrobot.eventbus.EventBus; + +import java.util.concurrent.Executor; + +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; + +public class MaterialYouUtils { + public static void changeTheme(Context context, Executor executor, Handler handler, + CustomThemeWrapper customThemeWrapper, + SharedPreferences lightThemeSharedPreferences, + SharedPreferences darkThemeSharedPreferences, + SharedPreferences amoledThemeSharedPreferences) { + executor.execute(() -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + WallpaperManager wallpaperManager = WallpaperManager.getInstance(context); + WallpaperColors wallpaperColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM); + + if (wallpaperColors != null) { + int colorPrimaryInt = shiftColorTo255(wallpaperColors.getPrimaryColor().toArgb(), 0.4); + int colorPrimaryDarkInt = shiftColorTo0(colorPrimaryInt, 0.4); + int backgroundColor = shiftColorTo255(colorPrimaryInt, 0.6); + int cardViewBackgroundColor = shiftColorTo255(colorPrimaryInt, 0.9); + Color colorAccent = wallpaperColors.getSecondaryColor(); + int colorAccentInt = shiftColorTo255(colorAccent == null ? customThemeWrapper.getColorAccent() : colorAccent.toArgb(), 0.4); + + int colorPrimaryAppropriateTextColor = getAppropriateTextColor(colorPrimaryInt); + int backgroundColorAppropriateTextColor = getAppropriateTextColor(backgroundColor); + + lightThemeSharedPreferences.edit().putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_DARK, colorPrimaryDarkInt) + .putInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, colorAccentInt) + .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.BACKGROUND_COLOR, backgroundColor) + .putInt(CustomThemeSharedPreferencesUtils.CARD_VIEW_BACKGROUND_COLOR, cardViewBackgroundColor) + .putInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_BACKGROUND_COLOR, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.NAV_BAR_COLOR, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.PRIMARY_TEXT_COLOR, backgroundColorAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_ICON_COLOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.PRIMARY_ICON_COLOR, backgroundColorAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.FAB_ICON_COLOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.TOOLBAR_SECONDARY_TEXT_COLOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR, colorPrimaryAppropriateTextColor) + .putInt(CustomThemeSharedPreferencesUtils.CIRCULAR_PROGRESS_BAR_BACKGROUND, colorPrimaryInt) + .putBoolean(CustomThemeSharedPreferencesUtils.LIGHT_STATUS_BAR, getAppropriateTextColor(colorPrimaryDarkInt) == Color.toArgb(Color.BLACK)) + .apply(); + darkThemeSharedPreferences.edit() + .putInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, colorPrimaryInt) + .apply(); + amoledThemeSharedPreferences.edit() + .putInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, colorPrimaryInt) + .putInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, colorPrimaryInt) + .apply(); + + handler.post(() -> EventBus.getDefault().post(new RecreateActivityEvent())); + } + } + }); + } + + private static int shiftColorTo255(int color, double ratio) { + int offset = (int) (Math.min(Math.min(255 - Color.red(color), 255 - Color.green(color)), 255 - Color.blue(color)) * ratio); + return Color.argb(Color.alpha(color), Color.red(color) + offset, + Color.green(color) + offset, + Color.blue(color) + offset); + } + + private static int shiftColorTo0(int color, double ratio) { + int offset = (int) (Math.min(Math.min(Color.red(color), Color.green(color)), Color.blue(color)) * ratio); + return Color.argb(Color.alpha(color), Color.red(color) - offset, + Color.green(color) - offset, + Color.blue(color) - offset); + + } + + @ColorInt + public static int getAppropriateTextColor(@ColorInt int color) { + // Counting the perceptive luminance - human eye favors green color... + double luminance = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255; + return luminance < 0.5 ? Color.BLACK : Color.WHITE; + } +}