feat: Added Basic Backup / Restore Feature
This commit is contained in:
@@ -30,6 +30,7 @@ android {
|
||||
applicationIdSuffix = ".debug"
|
||||
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
resValue("string", "app_name", "Easy Launcher (Debug)")
|
||||
resValue("string", "settings_backups_file", "autoBackup.debug.ini")
|
||||
}
|
||||
|
||||
getByName("release") {
|
||||
@@ -37,6 +38,7 @@ android {
|
||||
isShrinkResources = true
|
||||
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
resValue("string", "app_name", "Easy Launcher")
|
||||
resValue("string", "settings_backups_file", "autoBackup.ini")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +89,7 @@ dependencies {
|
||||
implementation("androidx.work:work-runtime-ktx:2.9.0")
|
||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||
implementation("androidx.viewpager2:viewpager2:1.1.0")
|
||||
implementation("androidx.preference:preference-ktx:1.2.1")
|
||||
debugImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.github.droidworksstudio.launcher.helper
|
||||
import android.app.SearchManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.LauncherApps
|
||||
import android.net.Uri
|
||||
import android.os.UserHandle
|
||||
@@ -10,7 +11,11 @@ import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.github.droidworksstudio.launcher.Constants
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
fun View.hideKeyboard() {
|
||||
this.clearFocus()
|
||||
@@ -74,6 +79,86 @@ fun Context.searchCustomSearchEngine(searchQuery: String? = null): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun Context.backupSharedPreferences(backupFileName: String) {
|
||||
val sharedPreferences: SharedPreferences = this.getSharedPreferences(Constants.PREFS_FILENAME, 0)
|
||||
val allPrefs = sharedPreferences.all
|
||||
val backupFile = File(filesDir, backupFileName)
|
||||
|
||||
println("Backup SharedPreferences to: ${backupFile.absolutePath}")
|
||||
|
||||
try {
|
||||
backupFile.bufferedWriter().use { writer ->
|
||||
for ((key, value) in allPrefs) {
|
||||
if (value != null) {
|
||||
val line = when (value) {
|
||||
is Boolean -> "$key=${value}\n"
|
||||
is Int -> "$key=${value}\n"
|
||||
is Float -> "$key=${value}\n"
|
||||
is Long -> "$key=${value}\n"
|
||||
is String -> "$key=${value}\n"
|
||||
is Set<*> -> "$key=${value.joinToString(",")}\n"
|
||||
else -> null
|
||||
}
|
||||
if (line != null) {
|
||||
writer.write(line)
|
||||
println("Writing: $line")
|
||||
} else {
|
||||
println("Skipping unsupported type for key: $key")
|
||||
}
|
||||
} else {
|
||||
println("Null value for key: $key")
|
||||
}
|
||||
}
|
||||
}
|
||||
println("Backup completed successfully.")
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
println("Failed to backup SharedPreferences: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.restoreSharedPreferences(backupFileName: String) {
|
||||
val sharedPreferences: SharedPreferences = this.getSharedPreferences(Constants.PREFS_FILENAME, 0)
|
||||
val editor = sharedPreferences.edit()
|
||||
val backupFile = File(filesDir, backupFileName)
|
||||
|
||||
println("Restoring SharedPreferences from: ${backupFile.absolutePath}")
|
||||
|
||||
if (backupFile.exists()) {
|
||||
try {
|
||||
backupFile.forEachLine { line ->
|
||||
val (key, value) = line.split("=", limit = 2)
|
||||
when {
|
||||
value.toBooleanStrictOrNull() != null -> editor.putBoolean(key, value.toBoolean())
|
||||
value.toIntOrNull() != null -> editor.putInt(key, value.toInt())
|
||||
value.toFloatOrNull() != null -> editor.putFloat(key, value.toFloat())
|
||||
value.toLongOrNull() != null -> editor.putLong(key, value.toLong())
|
||||
value.contains(",") -> editor.putStringSet(key, value.split(",").toSet())
|
||||
else -> editor.putString(key, value)
|
||||
}
|
||||
println("Restoring: $key=$value")
|
||||
}
|
||||
editor.apply()
|
||||
println("Restore completed successfully.")
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
println("Failed to restore SharedPreferences: ${e.message}")
|
||||
}
|
||||
} else {
|
||||
println("Backup file does not exist.")
|
||||
}
|
||||
}
|
||||
|
||||
fun Fragment.restartApp() {
|
||||
val packageManager = requireContext().packageManager
|
||||
val intent = packageManager.getLaunchIntentForPackage(requireContext().packageName)
|
||||
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
if (intent != null) {
|
||||
startActivity(intent)
|
||||
}
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
fun Context.isPackageInstalled(packageName: String, userHandle: UserHandle = android.os.Process.myUserHandle()): Boolean {
|
||||
val launcher = getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
val activityInfo = launcher.getActivityList(packageName, userHandle)
|
||||
|
||||
@@ -267,7 +267,7 @@ class AppHelper @Inject constructor() {
|
||||
return dailyWordsArray[wordIndex]
|
||||
}
|
||||
|
||||
fun shareApp(context: Context){
|
||||
fun shareAppButton(context: Context){
|
||||
val shareIntent = Intent(Intent.ACTION_SEND)
|
||||
shareIntent.type = "text/plain"
|
||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Share Application")
|
||||
@@ -275,19 +275,27 @@ class AppHelper @Inject constructor() {
|
||||
context.startActivity(Intent.createChooser(shareIntent, "Share Application"))
|
||||
}
|
||||
|
||||
fun github(context: Context){
|
||||
fun githubButton(context: Context){
|
||||
val uri = Uri.parse("https://github.com/DroidWorksStudio/EasyLauncher")
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
fun feedback(context: Context){
|
||||
fun feedbackButton(context: Context){
|
||||
val emailIntent = Intent(Intent.ACTION_SENDTO)
|
||||
emailIntent.data = Uri.parse("mailto:droidworksstuido@063240.xyz")
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Easy Launcher")
|
||||
context.startActivity(Intent.createChooser(emailIntent, "Choose Mail Application"))
|
||||
}
|
||||
|
||||
fun backupSharedPreferences(context: Context) {
|
||||
context.backupSharedPreferences(context.getString(R.string.settings_backups_file))
|
||||
}
|
||||
|
||||
fun restoreSharedPreferences(context: Context) {
|
||||
context.restoreSharedPreferences(context.getString(R.string.settings_backups_file))
|
||||
}
|
||||
|
||||
fun enableAppAsAccessibilityService(context: Context, accessibilityState: Boolean) {
|
||||
val state: String = if (accessibilityState) {
|
||||
context.getString(R.string.accessibility_settings_disable)
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.NavController
|
||||
@@ -15,6 +16,7 @@ import com.github.droidworksstudio.launcher.R
|
||||
import com.github.droidworksstudio.launcher.databinding.FragmentSettingsBinding
|
||||
import com.github.droidworksstudio.launcher.helper.AppHelper
|
||||
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
|
||||
import com.github.droidworksstudio.launcher.helper.restartApp
|
||||
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
||||
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AlignmentBottomSheetDialogFragment
|
||||
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.ColorBottomSheetDialogFragment
|
||||
@@ -30,7 +32,6 @@ class SettingsFragment : Fragment(), ScrollEventListener {
|
||||
private var _binding: FragmentSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
//private val viewModel: AppViewModel by viewModels()
|
||||
private val preferenceViewModel: PreferenceViewModel by viewModels()
|
||||
|
||||
@Inject
|
||||
@@ -127,15 +128,27 @@ class SettingsFragment : Fragment(), ScrollEventListener {
|
||||
}
|
||||
|
||||
binding.shareView.setOnClickListener {
|
||||
appHelper.shareApp(requireContext())
|
||||
appHelper.shareAppButton(requireContext())
|
||||
}
|
||||
|
||||
binding.githubView.setOnClickListener {
|
||||
appHelper.github(requireContext())
|
||||
appHelper.githubButton(requireContext())
|
||||
|
||||
}
|
||||
|
||||
binding.feedbackView.setOnClickListener {
|
||||
appHelper.feedback(requireContext())
|
||||
appHelper.feedbackButton(requireContext())
|
||||
}
|
||||
|
||||
binding.backupView.setOnClickListener {
|
||||
appHelper.backupSharedPreferences(requireContext())
|
||||
Toast.makeText(requireContext(), getString(R.string.settings_reload_app_backup), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
binding.restoreView.setOnClickListener {
|
||||
appHelper.restoreSharedPreferences(requireContext())
|
||||
Toast.makeText(requireContext(), getString(R.string.settings_reload_app_restore), Toast.LENGTH_SHORT).show()
|
||||
restartApp()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -673,6 +673,49 @@
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:text="@string/settings_title_backups"
|
||||
android:textSize="@dimen/text_super_large"
|
||||
style="@style/TextDefaultStyle"/>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/backup_view"
|
||||
android:text="@string/settings_backups_backup"
|
||||
android:textSize="@dimen/text_large"
|
||||
android:layout_marginVertical="10dp"
|
||||
style="@style/TextDefaultStyle"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/restore_view"
|
||||
android:text="@string/settings_backups_restore"
|
||||
android:textSize="@dimen/text_large"
|
||||
android:layout_marginVertical="10dp"
|
||||
style="@style/TextDefaultStyle"/>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<string name="settings_title_time_style">Time Style</string>
|
||||
<string name="settings_title_app_manager">App Manage</string>
|
||||
<string name="settings_title_gestures">Gestures</string>
|
||||
<string name="settings_title_backups">Backups</string>
|
||||
<string name="settings_title_others">Others</string>
|
||||
|
||||
<string name="settings_display_status_bar">Show Status Bar</string>
|
||||
@@ -75,6 +76,12 @@
|
||||
<string name="settings_others_feedback">Feedback</string>
|
||||
<string name="settings_others_github">Github</string>
|
||||
|
||||
<string name="settings_backups_backup">Backup Preferences</string>
|
||||
<string name="settings_backups_restore">Restore Preferences</string>
|
||||
|
||||
<string name="settings_reload_app_backup">Preferences backed up.</string>
|
||||
<string name="settings_reload_app_restore">Preferences restored. Restarting.</string>
|
||||
|
||||
<string name="authentication_title">Authentication</string>
|
||||
<string name="authentication_subtitle">Log in using your biometric credentials.</string>
|
||||
<string name="authentication_cancel">Authentication Cancel</string>
|
||||
|
||||
Reference in New Issue
Block a user