[app] Fix possible crashes

This commit is contained in:
tehcneko 2021-05-30 18:25:26 +08:00 committed by LoveSy
parent e91332c2b7
commit 61db23cb18
2 changed files with 4 additions and 336 deletions

View File

@ -79,8 +79,11 @@ public class MainActivity extends BaseActivity {
return;
}
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
if (navHostFragment == null) {
return;
}
NavController navController = navHostFragment.getNavController();
if (intent.getAction().equals("android.intent.action.APPLICATION_PREFERENCES")) {
if (intent.getAction() != null && intent.getAction().equals("android.intent.action.APPLICATION_PREFERENCES")) {
navController.navigate(R.id.settings_fragment);
} else if (intent.hasExtra("modulePackageName")) {
Bundle bundle = new Bundle();

View File

@ -1,335 +0,0 @@
/*
* This file is part of LSPosed.
*
* LSPosed is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LSPosed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
*
* Copyright (C) 2020 EdXposed Contributors
* Copyright (C) 2021 LSPosed Contributors
*/
package org.lsposed.manager.ui.activity;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ViewGroup;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
import com.takisoft.preferencex.PreferenceCategory;
import com.takisoft.preferencex.PreferenceFragmentCompat;
import org.lsposed.manager.BuildConfig;
import org.lsposed.manager.ConfigManager;
import org.lsposed.manager.R;
import org.lsposed.manager.databinding.FragmentSettingsBinding;
import org.lsposed.manager.ui.activity.base.BaseActivity;
import org.lsposed.manager.util.BackupUtils;
import org.lsposed.manager.util.theme.ThemeUtil;
import java.util.Calendar;
import java.util.Locale;
import rikka.core.util.ResourceUtils;
import rikka.material.app.DayNightDelegate;
import rikka.recyclerview.RecyclerViewKt;
import rikka.widget.borderview.BorderRecyclerView;
public class SettingsActivity extends BaseActivity {
private static final String KEY_PREFIX = SettingsActivity.class.getName() + '.';
private static final String EXTRA_SAVED_INSTANCE_STATE = KEY_PREFIX + "SAVED_INSTANCE_STATE";
FragmentSettingsBinding binding;
private boolean restarting;
@NonNull
public static Intent newIntent(@NonNull Context context) {
return new Intent(context, SettingsActivity.class);
}
@NonNull
private static Intent newIntent(@NonNull Bundle savedInstanceState, @NonNull Context context) {
return newIntent(context)
.putExtra(EXTRA_SAVED_INSTANCE_STATE, savedInstanceState);
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {
savedInstanceState = getIntent().getBundleExtra(EXTRA_SAVED_INSTANCE_STATE);
}
super.onCreate(savedInstanceState);
binding = FragmentSettingsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setAppBar(binding.appBar, binding.toolbar);
binding.getRoot().bringChildToFront(binding.appBar);
binding.toolbar.setNavigationOnClickListener(view -> finish());
ActionBar bar = getSupportActionBar();
if (bar != null) {
bar.setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new SettingsFragment()).commit();
}
if (ConfigManager.getXposedVersionName() == null) {
Snackbar.make(binding.snackbar, R.string.lsposed_not_active, Snackbar.LENGTH_LONG).show();
}
}
private void restart() {
Bundle savedInstanceState = new Bundle();
onSaveInstanceState(savedInstanceState);
finish();
startActivity(newIntent(savedInstanceState, this));
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
restarting = true;
}
@Override
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
return restarting || super.dispatchKeyEvent(event);
}
@SuppressLint("RestrictedApi")
@Override
public boolean dispatchKeyShortcutEvent(@NonNull KeyEvent event) {
return restarting || super.dispatchKeyShortcutEvent(event);
}
@Override
public boolean dispatchTouchEvent(@NonNull MotionEvent event) {
return restarting || super.dispatchTouchEvent(event);
}
@Override
public boolean dispatchTrackballEvent(@NonNull MotionEvent event) {
return restarting || super.dispatchTrackballEvent(event);
}
@Override
public boolean dispatchGenericMotionEvent(@NonNull MotionEvent event) {
return restarting || super.dispatchGenericMotionEvent(event);
}
public static class SettingsFragment extends PreferenceFragmentCompat {
ActivityResultLauncher<String> backupLauncher = registerForActivityResult(new ActivityResultContracts.CreateDocument(),
uri -> {
if (uri != null) {
try {
// grantUriPermission might throw RemoteException on MIUI
requireActivity().grantUriPermission(BuildConfig.APPLICATION_ID, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (Exception e) {
e.printStackTrace();
}
AlertDialog alertDialog = new AlertDialog.Builder(requireActivity())
.setCancelable(false)
.setMessage(R.string.settings_backuping)
.show();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
boolean success = BackupUtils.backup(requireContext(), uri);
try {
SettingsActivity activity = (SettingsActivity) requireActivity();
activity.runOnUiThread(() -> {
alertDialog.dismiss();
activity.makeSnackBar(success ? R.string.settings_backup_success : R.string.settings_backup_failed, Snackbar.LENGTH_SHORT);
});
} catch (Exception e) {
e.printStackTrace();
}
});
}
});
ActivityResultLauncher<String[]> restoreLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(),
uri -> {
if (uri != null) {
try {
// grantUriPermission might throw RemoteException on MIUI
requireActivity().grantUriPermission(BuildConfig.APPLICATION_ID, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
} catch (Exception e) {
e.printStackTrace();
}
AlertDialog alertDialog = new AlertDialog.Builder(requireActivity())
.setCancelable(false)
.setMessage(R.string.settings_restoring)
.show();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
boolean success = BackupUtils.restore(requireContext(), uri);
try {
SettingsActivity activity = (SettingsActivity) requireActivity();
activity.runOnUiThread(() -> {
alertDialog.dismiss();
activity.makeSnackBar(success ? R.string.settings_restore_success : R.string.settings_restore_failed, Snackbar.LENGTH_SHORT);
});
} catch (Exception e) {
e.printStackTrace();
}
});
}
});
@Override
public void onCreatePreferencesFix(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.prefs);
boolean installed = ConfigManager.getXposedVersionName() != null;
SwitchPreference prefVerboseLogs = findPreference("disable_verbose_log");
if (prefVerboseLogs != null) {
if (requireActivity().getApplicationInfo().uid / 100000 != 0) {
prefVerboseLogs.setVisible(false);
} else {
prefVerboseLogs.setEnabled(installed);
prefVerboseLogs.setChecked(!ConfigManager.isVerboseLogEnabled());
prefVerboseLogs.setOnPreferenceChangeListener((preference, newValue) -> {
boolean result = ConfigManager.setVerboseLogEnabled(!(boolean) newValue);
SettingsActivity activity = (SettingsActivity) getActivity();
if (result && activity != null) {
Snackbar.make(activity.binding.snackbar, R.string.reboot_required, Snackbar.LENGTH_SHORT)
.setAction(R.string.reboot, v -> ConfigManager.reboot(false, null, false))
.show();
}
return result;
});
}
}
SwitchPreference prefEnableResources = findPreference("enable_resources");
if (prefEnableResources != null) {
prefEnableResources.setEnabled(installed);
prefEnableResources.setChecked(ConfigManager.isResourceHookEnabled());
prefEnableResources.setOnPreferenceChangeListener((preference, newValue) -> ConfigManager.setResourceHookEnabled((boolean) newValue));
}
Preference backup = findPreference("backup");
if (backup != null) {
backup.setEnabled(installed);
backup.setOnPreferenceClickListener(preference -> {
Calendar now = Calendar.getInstance();
backupLauncher.launch(String.format(Locale.US,
"LSPosed_%04d%02d%02d_%02d%02d%02d.lsp",
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
now.get(Calendar.MINUTE), now.get(Calendar.SECOND)));
return true;
});
}
Preference restore = findPreference("restore");
if (restore != null) {
restore.setEnabled(installed);
restore.setOnPreferenceClickListener(preference -> {
restoreLauncher.launch(new String[]{"*/*"});
return true;
});
}
Preference theme = findPreference("dark_theme");
if (theme != null) {
theme.setOnPreferenceChangeListener((preference, newValue) -> {
if (!preferences.getString("dark_theme", ThemeUtil.MODE_NIGHT_FOLLOW_SYSTEM).equals(newValue)) {
DayNightDelegate.setDefaultNightMode(ThemeUtil.getDarkTheme((String) newValue));
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null) {
activity.restart();
}
}
return true;
});
}
Preference black_dark_theme = findPreference("black_dark_theme");
if (black_dark_theme != null) {
black_dark_theme.setOnPreferenceChangeListener((preference, newValue) -> {
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null && ResourceUtils.isNightMode(getResources().getConfiguration())) {
activity.restart();
}
return true;
});
}
Preference primary_color = findPreference("theme_color");
if (primary_color != null) {
primary_color.setOnPreferenceChangeListener((preference, newValue) -> {
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null) {
activity.restart();
}
return true;
});
}
PreferenceCategory prefGroupSystem = findPreference("settings_group_system");
SwitchPreference prefShowHiddenIcons = findPreference("show_hidden_icon_apps_enabled");
if (prefGroupSystem != null && prefShowHiddenIcons != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& requireActivity().checkSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED) {
prefGroupSystem.setVisible(true);
prefShowHiddenIcons.setVisible(true);
prefShowHiddenIcons.setChecked(Settings.Global.getInt(
requireActivity().getContentResolver(), "show_hidden_icon_apps_enabled", 1) != 0);
prefShowHiddenIcons.setOnPreferenceChangeListener((preference, newValue) -> Settings.Global.putInt(requireActivity().getContentResolver(),
"show_hidden_icon_apps_enabled", (boolean) newValue ? 1 : 0));
}
SwitchPreference prefFollowSystemAccent = findPreference("follow_system_accent");
if (prefFollowSystemAccent != null && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || Build.VERSION.SDK_INT == Build.VERSION_CODES.R && Build.VERSION.PREVIEW_SDK_INT != 0)) {
if (primary_color != null) {
primary_color.setVisible(!prefFollowSystemAccent.isChecked());
}
prefFollowSystemAccent.setVisible(true);
prefFollowSystemAccent.setOnPreferenceChangeListener((preference, newValue) -> {
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null) {
activity.restart();
}
return true;
});
}
}
@Override
public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
BorderRecyclerView recyclerView = (BorderRecyclerView) super.onCreateRecyclerView(inflater, parent, savedInstanceState);
RecyclerViewKt.fixEdgeEffect(recyclerView, false, true);
recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> {
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null) {
activity.binding.appBar.setRaised(!top);
}
});
return recyclerView;
}
}
public void makeSnackBar(@StringRes int text, @Snackbar.Duration int duration) {
Snackbar.make(binding.snackbar, text, duration).show();
}
}