Fix app crashes when applying Material You theme after changing wallpaper. Tweak the design of the fast scroller.

This commit is contained in:
Docile-Alligator 2022-06-01 14:53:30 +08:00
parent db08be065e
commit adb77f44d0
13 changed files with 245 additions and 264 deletions

View File

@ -181,7 +181,7 @@ dependencies {
implementation 'com.nex3z:flow-layout:1.3.3' implementation 'com.nex3z:flow-layout:1.3.3'
// RecyclerView fast scrolling // RecyclerView fast scrolling
implementation 'me.zhanghai.android.fastscroll:library:1.1.7' implementation 'me.zhanghai.android.fastscroll:library:1.1.8'
implementation 'com.otaliastudios:zoomlayout:1.9.0' implementation 'com.otaliastudios:zoomlayout:1.9.0'

View File

@ -438,9 +438,6 @@
android:name=".services.SubmitPostService" android:name=".services.SubmitPostService"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
<service
android:name=".services.MaterialYouService"
android:exported="false" />
<service <service
android:name=".services.EditProfileService" android:name=".services.EditProfileService"
android:enabled="true" android:enabled="true"

View File

@ -81,7 +81,6 @@ import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryVideoFrag
import ml.docilealligator.infinityforreddit.services.DownloadMediaService; import ml.docilealligator.infinityforreddit.services.DownloadMediaService;
import ml.docilealligator.infinityforreddit.services.DownloadRedditVideoService; import ml.docilealligator.infinityforreddit.services.DownloadRedditVideoService;
import ml.docilealligator.infinityforreddit.services.EditProfileService; import ml.docilealligator.infinityforreddit.services.EditProfileService;
import ml.docilealligator.infinityforreddit.services.MaterialYouService;
import ml.docilealligator.infinityforreddit.services.SubmitPostService; import ml.docilealligator.infinityforreddit.services.SubmitPostService;
import ml.docilealligator.infinityforreddit.settings.AdvancedPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.AdvancedPreferenceFragment;
import ml.docilealligator.infinityforreddit.settings.CommentPreferenceFragment; import ml.docilealligator.infinityforreddit.settings.CommentPreferenceFragment;
@ -276,8 +275,6 @@ public interface AppComponent {
void inject(LockScreenActivity lockScreenActivity); void inject(LockScreenActivity lockScreenActivity);
void inject(MaterialYouService materialYouService);
void inject(RPANActivity rpanActivity); void inject(RPANActivity rpanActivity);
void inject(ViewRPANBroadcastFragment viewRPANBroadcastFragment); void inject(ViewRPANBroadcastFragment viewRPANBroadcastFragment);
@ -301,4 +298,6 @@ public interface AppComponent {
void inject(PostPollActivity postPollActivity); void inject(PostPollActivity postPollActivity);
void inject(AccountChooserBottomSheetFragment accountChooserBottomSheetFragment); void inject(AccountChooserBottomSheetFragment accountChooserBottomSheetFragment);
void inject(MaterialYouWorker materialYouWorker);
} }

View File

@ -0,0 +1,55 @@
package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import javax.inject.Inject;
import javax.inject.Named;
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
public class MaterialYouWorker extends Worker {
public static final String UNIQUE_WORKER_NAME = "MYWT";
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@Inject
@Named("light_theme")
SharedPreferences lightThemeSharedPreferences;
@Inject
@Named("dark_theme")
SharedPreferences darkThemeSharedPreferences;
@Inject
@Named("amoled_theme")
SharedPreferences amoledThemeSharedPreferences;
@Inject
RedditDataRoomDatabase redditDataRoomDatabase;
@Inject
CustomThemeWrapper customThemeWrapper;
private Context context;
public MaterialYouWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
((Infinity) context.getApplicationContext()).getAppComponent().inject(this);
}
@NonNull
@Override
public Result doWork() {
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)) {
MaterialYouUtils.changeThemeSync(context, redditDataRoomDatabase,
customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences,
amoledThemeSharedPreferences);
}
return Result.success();
}
}

View File

@ -61,6 +61,7 @@ import com.google.android.material.textfield.TextInputEditText;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -1210,7 +1211,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb
} }
} }
@Subscribe @Subscribe(threadMode = ThreadMode.MAIN)
public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) {
ActivityCompat.recreate(this); ActivityCompat.recreate(this);
} }

View File

@ -17,6 +17,7 @@ import com.google.android.material.appbar.CollapsingToolbarLayout;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -189,7 +190,7 @@ public class SettingsActivity extends BaseActivity implements
EventBus.getDefault().unregister(this); EventBus.getDefault().unregister(this);
} }
@Subscribe @Subscribe(threadMode = ThreadMode.MAIN)
public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) {
ActivityCompat.recreate(this); ActivityCompat.recreate(this);
} }

View File

@ -5,9 +5,11 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import androidx.core.content.ContextCompat; import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import ml.docilealligator.infinityforreddit.services.MaterialYouService; import ml.docilealligator.infinityforreddit.MaterialYouWorker;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
public class WallpaperChangeReceiver extends BroadcastReceiver { public class WallpaperChangeReceiver extends BroadcastReceiver {
@ -20,8 +22,9 @@ public class WallpaperChangeReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (sharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)) { if (sharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)) {
Intent materialYouIntent = new Intent(context, MaterialYouService.class); OneTimeWorkRequest materialYouRequest = OneTimeWorkRequest.from(MaterialYouWorker.class);
ContextCompat.startForegroundService(context, materialYouIntent); WorkManager.getInstance(context).enqueueUniqueWork(MaterialYouWorker.UNIQUE_WORKER_NAME,
ExistingWorkPolicy.REPLACE, materialYouRequest);
} }
} }
} }

View File

@ -117,7 +117,7 @@ public class FollowedUsersListingFragment extends Fragment implements FragmentCo
FollowedUsersRecyclerViewAdapter adapter = new FollowedUsersRecyclerViewAdapter(mActivity, FollowedUsersRecyclerViewAdapter adapter = new FollowedUsersRecyclerViewAdapter(mActivity,
mExecutor, mOauthRetrofit, mRedditDataRoomDatabase, mCustomThemeWrapper, accessToken); mExecutor, mOauthRetrofit, mRedditDataRoomDatabase, mCustomThemeWrapper, accessToken);
mRecyclerView.setAdapter(adapter); mRecyclerView.setAdapter(adapter);
new FastScrollerBuilder(mRecyclerView).build(); new FastScrollerBuilder(mRecyclerView).useMd2Style().build();
mSubscribedUserViewModel = new ViewModelProvider(this, mSubscribedUserViewModel = new ViewModelProvider(this,
new SubscribedUserViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, getArguments().getString(EXTRA_ACCOUNT_NAME))) new SubscribedUserViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, getArguments().getString(EXTRA_ACCOUNT_NAME)))

View File

@ -154,7 +154,7 @@ public class MultiRedditListingFragment extends Fragment implements FragmentComm
} }
}); });
} }
new FastScrollerBuilder(mRecyclerView).build(); new FastScrollerBuilder(mRecyclerView).useMd2Style().build();
mMultiRedditViewModel = new ViewModelProvider(this, mMultiRedditViewModel = new ViewModelProvider(this,
new MultiRedditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName)) new MultiRedditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName))

View File

@ -132,7 +132,7 @@ public class SubscribedSubredditsListingFragment extends Fragment implements Fra
} }
mRecyclerView.setAdapter(adapter); mRecyclerView.setAdapter(adapter);
new FastScrollerBuilder(mRecyclerView).build(); new FastScrollerBuilder(mRecyclerView).useMd2Style().build();
mSubscribedSubredditViewModel = new ViewModelProvider(this, mSubscribedSubredditViewModel = new ViewModelProvider(this,
new SubscribedSubredditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName)) new SubscribedSubredditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName))

View File

@ -1,97 +0,0 @@
package ml.docilealligator.infinityforreddit.services;
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
import ml.docilealligator.infinityforreddit.Infinity;
import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.utils.MaterialYouUtils;
import ml.docilealligator.infinityforreddit.utils.NotificationUtils;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
public class MaterialYouService extends Service {
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@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() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
((Infinity) getApplication()).getAppComponent().inject(this);
NotificationChannelCompat serviceChannel =
new NotificationChannelCompat.Builder(
NotificationUtils.CHANNEL_ID_MATERIAL_YOU,
NotificationManagerCompat.IMPORTANCE_LOW)
.setName(NotificationUtils.CHANNEL_MATERIAL_YOU)
.build();
NotificationManagerCompat manager = NotificationManagerCompat.from(this);
manager.createNotificationChannel(serviceChannel);
Notification notification = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_MATERIAL_YOU)
.setContentTitle(getString(R.string.material_you_notification_title))
.setContentText(getString(R.string.please_wait))
.setSmallIcon(R.drawable.ic_notification)
.setColor(customThemeWrapper.getColorPrimaryLightTheme())
.build();
startForeground(NotificationUtils.MATERIAL_YOU_NOTIFICATION_ID, notification);
if (mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_MATERIAL_YOU, false)) {
MaterialYouUtils.changeTheme(this, executor, new Handler(), redditDataRoomDatabase,
customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences,
amoledThemeSharedPreferences, () -> {
stopService();
});
} else {
stopService();
}
return START_NOT_STICKY;
}
private void stopService() {
stopForeground(true);
stopSelf();
}
}

View File

@ -179,7 +179,7 @@ public class ThemePreferenceFragment extends CustomFontPreferenceFragmentCompat
enableMaterialYouSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { enableMaterialYouSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> {
if ((Boolean) newValue) { if ((Boolean) newValue) {
MaterialYouUtils.changeTheme(activity, executor, new Handler(), MaterialYouUtils.changeThemeASync(activity, executor, new Handler(),
redditDataRoomDatabase, customThemeWrapper, redditDataRoomDatabase, customThemeWrapper,
lightThemeSharedPreferences, darkThemeSharedPreferences, lightThemeSharedPreferences, darkThemeSharedPreferences,
amoledThemeSharedPreferences, null); amoledThemeSharedPreferences, null);
@ -191,7 +191,7 @@ public class ThemePreferenceFragment extends CustomFontPreferenceFragmentCompat
}); });
applyMaterialYouPreference.setOnPreferenceClickListener(preference -> { applyMaterialYouPreference.setOnPreferenceClickListener(preference -> {
MaterialYouUtils.changeTheme(activity, executor, new Handler(), MaterialYouUtils.changeThemeASync(activity, executor, new Handler(),
redditDataRoomDatabase, customThemeWrapper, redditDataRoomDatabase, customThemeWrapper,
lightThemeSharedPreferences, darkThemeSharedPreferences, lightThemeSharedPreferences, darkThemeSharedPreferences,
amoledThemeSharedPreferences, null); amoledThemeSharedPreferences, null);

View File

@ -40,7 +40,21 @@ public class MaterialYouUtils {
}); });
} }
public static void changeTheme(Context context, Executor executor, Handler handler, public static void changeThemeSync(Context context,
RedditDataRoomDatabase redditDataRoomDatabase,
CustomThemeWrapper customThemeWrapper,
SharedPreferences lightThemeSharedPreferences,
SharedPreferences darkThemeSharedPreferences,
SharedPreferences amoledThemeSharedPreferences) {
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) { }
if (changeTheme(context, redditDataRoomDatabase, customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences)) {
EventBus.getDefault().post(new RecreateActivityEvent());
}
}
public static void changeThemeASync(Context context, Executor executor, Handler handler,
RedditDataRoomDatabase redditDataRoomDatabase, RedditDataRoomDatabase redditDataRoomDatabase,
CustomThemeWrapper customThemeWrapper, CustomThemeWrapper customThemeWrapper,
SharedPreferences lightThemeSharedPreferences, SharedPreferences lightThemeSharedPreferences,
@ -51,6 +65,23 @@ public class MaterialYouUtils {
try { try {
Thread.sleep(2000); Thread.sleep(2000);
} catch (InterruptedException ignored) { } } catch (InterruptedException ignored) { }
if (changeTheme(context, redditDataRoomDatabase, customThemeWrapper, lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences)) {
handler.post(() -> {
if (materialYouListener != null) {
materialYouListener.applied();
}
EventBus.getDefault().post(new RecreateActivityEvent());
});
}
});
}
private static boolean changeTheme(Context context,
RedditDataRoomDatabase redditDataRoomDatabase,
CustomThemeWrapper customThemeWrapper,
SharedPreferences lightThemeSharedPreferences,
SharedPreferences darkThemeSharedPreferences,
SharedPreferences amoledThemeSharedPreferences) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
CustomTheme lightTheme = CustomThemeWrapper.getIndigo(context); CustomTheme lightTheme = CustomThemeWrapper.getIndigo(context);
CustomTheme darkTheme = CustomThemeWrapper.getIndigoDark(context); CustomTheme darkTheme = CustomThemeWrapper.getIndigoDark(context);
@ -131,12 +162,7 @@ public class MaterialYouUtils {
CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(darkTheme, darkThemeSharedPreferences); CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(darkTheme, darkThemeSharedPreferences);
CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(amoledTheme, amoledThemeSharedPreferences); CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(amoledTheme, amoledThemeSharedPreferences);
handler.post(() -> { return true;
if (materialYouListener != null) {
materialYouListener.applied();
}
EventBus.getDefault().post(new RecreateActivityEvent());
});
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(context); WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
WallpaperColors wallpaperColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM); WallpaperColors wallpaperColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
@ -207,15 +233,11 @@ public class MaterialYouUtils {
CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(darkTheme, darkThemeSharedPreferences); CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(darkTheme, darkThemeSharedPreferences);
CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(amoledTheme, amoledThemeSharedPreferences); CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(amoledTheme, amoledThemeSharedPreferences);
handler.post(() -> { return true;
if (materialYouListener != null) {
materialYouListener.applied();
}
EventBus.getDefault().post(new RecreateActivityEvent());
});
} }
} }
});
return false;
} }
private static int lightenColor(int color, double ratio) { private static int lightenColor(int color, double ratio) {