diff --git a/.idea/misc.xml b/.idea/misc.xml index 03872dd..2cdc89a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 618c9c8..8bc381f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "com.vectras.vm" minSdk minApi targetSdk targetApi - versionCode 29 - versionName "3.2.6" + versionCode 30 + versionName "3.2.7" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b30cae8..790caed 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="com.vectras.vm"> @@ -47,7 +47,11 @@ android:largeHeap="true" android:requestLegacyExternalStorage="true" android:supportsRtl="true" - android:theme="@style/AppTheme" > + android:theme="@style/AppTheme"> + + android:label="@string/importRom"> @@ -114,7 +118,7 @@ android:name=".SplashActivity" android:configChanges="uiMode|orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout" android:exported="true" - android:hardwareAccelerated="true" > + android:hardwareAccelerated="true"> @@ -177,23 +181,19 @@ android:windowSoftInputMode="adjustPan" /> + android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|orientation|screenSize|smallestScreenSize" + android:label="@string/settings" /> + android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout" /> + android:exported="true" + android:label="Data Explorer" /> + android:label="Set Qemu Version" /> + android:taskAffinity="com.vectras.vm.x11.LoriePreferences"> - + + + @@ -268,7 +272,7 @@ android:name=".x11.utils.KeyInterceptor" android:exported="true" android:label="Termux:X11 KeyInterceptor" - android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" > + android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> @@ -282,7 +286,7 @@ android:name=".x11.LoriePreferences$Receiver" android:enabled="true" android:exported="true" - tools:ignore="ExportedReceiver" > + tools:ignore="ExportedReceiver"> diff --git a/app/src/main/java/com/vectras/qemu/MainSettingsManager.java b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java index 8b53c98..b3d51f9 100644 --- a/app/src/main/java/com/vectras/qemu/MainSettingsManager.java +++ b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java @@ -29,6 +29,7 @@ import com.google.android.material.appbar.CollapsingToolbarLayout; import com.vectras.vm.R; import com.vectras.vm.SplashActivity; import com.vectras.vm.VectrasApp; +import com.vectras.vm.settings.ThemeActivity; import java.util.Locale; import java.util.Objects; @@ -38,6 +39,10 @@ public class MainSettingsManager extends AppCompatActivity public static final String TAG = "MainSettingsManager"; + public static final int THEME_DEFAULT = 0; + public static final int THEME_LIGHT = 1; + public static final int THEME_DARK = 2; + public static MainSettingsManager activity; private static Handler mHandler; @@ -78,6 +83,11 @@ public class MainSettingsManager extends AppCompatActivity } } + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + } + @Override public boolean onPreferenceStartFragment(@NonNull PreferenceFragmentCompat caller, Preference pref) { // Instantiate the new Fragment @@ -146,6 +156,18 @@ public class MainSettingsManager extends AppCompatActivity return true; } + @Override + public boolean onPreferenceTreeClick(Preference preference) { + if ("userinterface".equals(preference.getKey())) { + Intent intent = new Intent(getContext(), ThemeActivity.class); + startActivity(intent); + //Need to close to avoid lag when this activity recreate. + requireActivity().finish(); + return true; + } + return super.onPreferenceTreeClick(preference); + } + } public static class AppPreferencesFragment extends PreferenceFragmentCompat @@ -244,7 +266,7 @@ public class MainSettingsManager extends AppCompatActivity Preference pref = findPreference("modeNight"); if (pref != null) { pref.setOnPreferenceChangeListener((preference, newValue) -> { - onNightMode(); + //onNightMode(); return true; }); } @@ -986,4 +1008,28 @@ public class MainSettingsManager extends AppCompatActivity return prefs.getBoolean("quickStart", true); } + public static void setTheme(Context context, int value) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putInt("theme", value); + edit.apply(); + } + + public static int getTheme(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getInt("theme", 0); + } + + public static void setDynamicColor(Context context, Boolean _boolean) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("dynamicColor", _boolean); + edit.apply(); + } + + public static Boolean getDynamicColor(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getBoolean("dynamicColor", true); + } + } diff --git a/app/src/main/java/com/vectras/vm/SplashActivity.java b/app/src/main/java/com/vectras/vm/SplashActivity.java index a211baa..31a7336 100644 --- a/app/src/main/java/com/vectras/vm/SplashActivity.java +++ b/app/src/main/java/com/vectras/vm/SplashActivity.java @@ -115,18 +115,6 @@ public class SplashActivity extends AppCompatActivity implements Runnable { com.vectras.qemu.utils.FileInstaller.installFiles(activity, true); } - - public void onStart() { - super.onStart(); - if (MainSettingsManager.getModeNight(activity)) { - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); - VectrasApp.getApp().setTheme(R.style.AppTheme); - } else { - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); - VectrasApp.getApp().setTheme(R.style.AppTheme); - } - } - public static void setupFolders() { try { StartVM.cache = activity.getCacheDir().getAbsolutePath(); diff --git a/app/src/main/java/com/vectras/vm/VectrasApp.java b/app/src/main/java/com/vectras/vm/VectrasApp.java index 504e984..87308d9 100644 --- a/app/src/main/java/com/vectras/vm/VectrasApp.java +++ b/app/src/main/java/com/vectras/vm/VectrasApp.java @@ -23,6 +23,8 @@ import android.widget.HorizontalScrollView; import android.widget.ScrollView; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatDelegate; import androidx.core.content.res.ResourcesCompat; @@ -31,6 +33,7 @@ import com.vectras.qemu.Config; import com.vectras.qemu.MainSettingsManager; import com.vectras.vm.utils.FileUtils; import com.vectras.vm.utils.PackageUtils; +import com.vectras.vm.utils.UIUtils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -76,8 +79,7 @@ public class VectrasApp extends Application { } catch (Throwable ignore) { // ignored } - setModeNight(this); - DynamicColors.applyToActivitiesIfAvailable(this); + setupTheme(); Locale locale = Locale.getDefault(); String language = locale.getLanguage(); @@ -88,6 +90,22 @@ public class VectrasApp extends Application { overrideFont("DEFAULT", R.font.gilroy); } setupAppConfig(getApplicationContext()); + + registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { + @Override + public void onActivityPreCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { + if (MainSettingsManager.getDynamicColor(activity)) + DynamicColors.applyToActivityIfAvailable(activity); + } + + @Override public void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {} + @Override public void onActivityStarted(@NonNull Activity activity) {} + @Override public void onActivityResumed(@NonNull Activity activity) {} + @Override public void onActivityPaused(@NonNull Activity activity) {} + @Override public void onActivityStopped(@NonNull Activity activity) {} + @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {} + @Override public void onActivityDestroyed(@NonNull Activity activity) {} + }); } public void overrideFont(String defaultFontNameToOverride, int customFontResourceId) { @@ -102,15 +120,13 @@ public class VectrasApp extends Application { } } - private void setModeNight(Context context) { - if (MainSettingsManager.getModeNight(context)) { - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); - setTheme(R.style.AppTheme); - } else { - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); - setTheme(R.style.AppTheme); - } + private void setupTheme() { + UIUtils.setDarkOrLight(MainSettingsManager.getTheme(this)); +// if (MainSettingsManager.getDynamicColor(this)) +// DynamicColors.applyToActivitiesIfAvailable(this); + +// setTheme(R.style.AppTheme); } public static Context getApp() { diff --git a/app/src/main/java/com/vectras/vm/home/HomeActivity.java b/app/src/main/java/com/vectras/vm/home/HomeActivity.java index 7b60673..942449b 100644 --- a/app/src/main/java/com/vectras/vm/home/HomeActivity.java +++ b/app/src/main/java/com/vectras/vm/home/HomeActivity.java @@ -93,6 +93,7 @@ import java.util.stream.Collectors; public class HomeActivity extends AppCompatActivity implements RomStoreFragment.RomStoreCallToHomeListener, VmsFragment.VmsCallToHomeListener { private final String TAG = "HomeActivity"; public static boolean isActivate = false; + public static boolean isNeedRecreate = false; public static boolean isOpenRomStore = false; private final ExecutorService executor = Executors.newSingleThreadExecutor(); ActivityHomeBinding binding; @@ -293,6 +294,13 @@ public class HomeActivity extends AppCompatActivity implements RomStoreFragment. public void onResume() { super.onResume(); Log.d(TAG, "onResume"); + + if (isNeedRecreate) { + isNeedRecreate = false; + recreate(); + return; + } + Config.ui = MainSettingsManager.getVmUi(this); Config.defaultVNCPort = Integer.parseInt(MainSettingsManager.getVncExternalDisplay(this)); Config.forceRefeshVNCDisplay = MainSettingsManager.getForceRefeshVNCDisplay(this); diff --git a/app/src/main/java/com/vectras/vm/settings/ThemeActivity.java b/app/src/main/java/com/vectras/vm/settings/ThemeActivity.java new file mode 100644 index 0000000..86ad97b --- /dev/null +++ b/app/src/main/java/com/vectras/vm/settings/ThemeActivity.java @@ -0,0 +1,113 @@ +package com.vectras.vm.settings; + +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; + +import androidx.activity.EdgeToEdge; +import androidx.activity.OnBackPressedCallback; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; + +import com.vectras.qemu.MainSettingsManager; +import com.vectras.vm.R; +import com.vectras.vm.databinding.ActivityThemeBinding; +import com.vectras.vm.home.HomeActivity; +import com.vectras.vm.utils.UIUtils; + +import java.util.Objects; + +public class ThemeActivity extends AppCompatActivity { + ActivityThemeBinding binding; + int oldThemeData; + int newThemeData; + boolean oldDynamicColorData; + boolean newDynamicColorData; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_external_vnc_settings); + binding = ActivityThemeBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setSupportActionBar(binding.toolbar); + Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); + binding.toolbar.setNavigationOnClickListener(view -> onBack()); + initialize(); + + getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + onBack(); + } + }); + } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + } + + @Override + public void onStop() { + super.onStop(); + if (!(oldDynamicColorData == newDynamicColorData)) + HomeActivity.isNeedRecreate = true; + } + + private void initialize() { + oldThemeData = MainSettingsManager.getTheme(this); + newThemeData = oldThemeData; + if (oldThemeData == MainSettingsManager.THEME_DEFAULT) { + binding.dnSelector.check(binding.selectDaynight.getId()); + } else if (oldThemeData == MainSettingsManager.THEME_LIGHT) { + binding.dnSelector.check(binding.selectDay.getId()); + } else if (oldThemeData == MainSettingsManager.THEME_DARK) { + binding.dnSelector.check(binding.selectNight.getId()); + } + + binding.dnSelector.addOnButtonCheckedListener((group, checkedId, isChecked) -> { + if (isChecked) { + if (checkedId == binding.selectDaynight.getId()) { + changeTheme(MainSettingsManager.THEME_DEFAULT); + } else if (checkedId == binding.selectDay.getId()) { + changeTheme(MainSettingsManager.THEME_LIGHT); + } else if (checkedId == binding.selectNight.getId()) { + changeTheme(MainSettingsManager.THEME_DARK); + } + } + }); + + oldDynamicColorData = MainSettingsManager.getDynamicColor(this); + newDynamicColorData = oldDynamicColorData; + + if (Build.VERSION.SDK_INT > 31) { + binding.swDynamiccolor.setChecked(oldDynamicColorData); + binding.lnDynamiccolor.setOnClickListener(v -> binding.swDynamiccolor.toggle()); + binding.swDynamiccolor.setOnCheckedChangeListener((buttonView, isChecked) -> changeDynamicColor(isChecked)); + } else { + binding.lnDynamiccolor.setEnabled(false); + binding.lnDynamiccolor.setAlpha(0.5f); + } + } + + private void onBack() { + startActivity(new Intent(this, MainSettingsManager.class)); + finish(); + } + + private void changeTheme(int mode) { + newThemeData = mode; + MainSettingsManager.setTheme(this, mode); + UIUtils.setDarkOrLight(mode); + recreate(); + } + + private void changeDynamicColor(boolean isEnable) { + newDynamicColorData = isEnable; + MainSettingsManager.setDynamicColor(this, isEnable); + recreate(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/utils/UIUtils.java b/app/src/main/java/com/vectras/vm/utils/UIUtils.java index 1cd95c4..831c0db 100644 --- a/app/src/main/java/com/vectras/vm/utils/UIUtils.java +++ b/app/src/main/java/com/vectras/vm/utils/UIUtils.java @@ -515,4 +515,13 @@ public class UIUtils { return luminance > 186; } + public static void setDarkOrLight(int mode) { + if (mode == MainSettingsManager.THEME_LIGHT) { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); + } else if (mode == MainSettingsManager.THEME_DARK) { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + } else { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); + } + } } diff --git a/app/src/main/java/com/vectras/vterm/Terminal.java b/app/src/main/java/com/vectras/vterm/Terminal.java index 00ccb99..c16f763 100644 --- a/app/src/main/java/com/vectras/vterm/Terminal.java +++ b/app/src/main/java/com/vectras/vterm/Terminal.java @@ -187,9 +187,9 @@ public class Terminal { ProcessBuilder processBuilder = new ProcessBuilder(); // Adjust these environment variables as necessary for your app - String filesDir = Objects.requireNonNull(context.getFilesDir().getAbsolutePath()); + String filesDir = context.getFilesDir().getAbsolutePath(); - File tmpDir = new File(Objects.requireNonNull(context.getFilesDir()), "usr/tmp"); + File tmpDir = new File(context.getFilesDir(), "usr/tmp"); // Setup environment for the PRoot qemuProcess processBuilder.environment().put("PROOT_TMP_DIR", tmpDir.getAbsolutePath()); diff --git a/app/src/main/res/drawable/palette_24px.xml b/app/src/main/res/drawable/palette_24px.xml new file mode 100644 index 0000000..58c504c --- /dev/null +++ b/app/src/main/res/drawable/palette_24px.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_theme.xml b/app/src/main/res/layout/activity_theme.xml new file mode 100644 index 0000000..983d883 --- /dev/null +++ b/app/src/main/res/layout/activity_theme.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-night/theme.xml b/app/src/main/res/values-night/theme.xml index 7dc8b9d..b5728c9 100644 --- a/app/src/main/res/values-night/theme.xml +++ b/app/src/main/res/values-night/theme.xml @@ -1,6 +1,6 @@ -