Skip to content

Commit 623d2ab

Browse files
Refactor: Made the backup system better so users chose the location.
Signed-off-by: HeCodes2Much <wayne6324@gmail.com>
1 parent 43b1935 commit 623d2ab

File tree

9 files changed

+180
-181
lines changed

9 files changed

+180
-181
lines changed

app/src/main/java/com/github/droidworksstudio/common/ContextExtensions.kt

Lines changed: 0 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -343,151 +343,6 @@ fun Context.isWorkProfileEnabled(): Boolean {
343343
}
344344
}
345345

346-
fun Context.backupSharedPreferences(backupFileNames: Array<String>) {
347-
// Check if external storage is writable
348-
if (!isExternalStorageWritable()) {
349-
showLongToast("External storage is not writable.")
350-
return
351-
}
352-
353-
val downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
354-
val backupDir = File(downloadDir, Constants.PACKAGE_NAME)
355-
356-
// Ensure the directory exists, create it if necessary
357-
if (!backupDir.exists()) {
358-
backupDir.mkdirs()
359-
}
360-
361-
for (backupFileName in backupFileNames) {
362-
val sharedPreferences: SharedPreferences =
363-
this.getSharedPreferences(backupFileName, Context.MODE_PRIVATE)
364-
val allPrefs = sharedPreferences.all
365-
366-
val backupFile = File(backupDir, "$backupFileName.xml")
367-
368-
try {
369-
backupFile.bufferedWriter().use { writer ->
370-
writer.write("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n")
371-
writer.write("<map>\n")
372-
373-
// Loop through all preferences
374-
for ((key, value) in allPrefs) {
375-
if (value != null) {
376-
val valueString = value.toString().replace("'", "&apos;")
377-
val line = when (value) {
378-
is Boolean, is Int, is Float, is Long, is String -> "\t<${value::class.simpleName!!.lowercase()} name='$key' value='$valueString' />\n"
379-
else -> null
380-
}
381-
line?.let {
382-
writer.write(it)
383-
}
384-
}
385-
}
386-
387-
writer.write("</map>")
388-
}
389-
showLongToast("Backup for $backupFileName completed successfully.")
390-
} catch (e: IOException) {
391-
e.printStackTrace()
392-
showLongToast("Failed to backup SharedPreferences $backupFileName: ${e.message}")
393-
}
394-
}
395-
}
396-
397-
398-
private fun isExternalStorageWritable(): Boolean {
399-
return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
400-
}
401-
402-
fun Context.restoreSharedPreferences(backupFileNames: Array<String>) {
403-
// Check if external storage is readable
404-
if (!isExternalStorageReadable()) {
405-
showLongToast("External storage is not readable.")
406-
return
407-
}
408-
409-
val downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
410-
val backupDir = File(downloadDir, Constants.PACKAGE_NAME)
411-
412-
for (backupFileName in backupFileNames) {
413-
val backupFile = File(backupDir, "$backupFileName.xml")
414-
415-
if (backupFile.exists()) {
416-
try {
417-
FileInputStream(backupFile).use { fileInputStream ->
418-
val factory = XmlPullParserFactory.newInstance()
419-
factory.isNamespaceAware = true
420-
val xpp = factory.newPullParser()
421-
xpp.setInput(fileInputStream, null)
422-
423-
var eventType = xpp.eventType
424-
var key: String? = null
425-
var value: Any? = null
426-
427-
while (eventType != XmlPullParser.END_DOCUMENT) {
428-
when (eventType) {
429-
XmlPullParser.START_TAG -> {
430-
when (xpp.name) {
431-
"boolean", "int", "float", "long", "string" -> {
432-
key = xpp.getAttributeValue(null, "name")
433-
val valueString = xpp.getAttributeValue(null, "value")
434-
value = when (xpp.name) {
435-
"boolean" -> valueString.toBoolean()
436-
"int" -> valueString.toInt()
437-
"float" -> valueString.toFloat()
438-
"long" -> valueString.toLong()
439-
else -> valueString
440-
}
441-
}
442-
}
443-
}
444-
445-
XmlPullParser.END_TAG -> {
446-
when (xpp.name) {
447-
"boolean", "int", "float", "long", "string" -> {
448-
if (key != null && value != null) {
449-
saveToSharedPreferences(backupFileName, key, value)
450-
key = null
451-
value = null
452-
}
453-
}
454-
}
455-
}
456-
}
457-
eventType = xpp.next()
458-
}
459-
}
460-
showLongToast("Restore for $backupFileName completed successfully.")
461-
} catch (e: Exception) {
462-
Log.e("Exception", e.toString())
463-
showLongToast("Failed to restore SharedPreferences $backupFileName: ${e.message}")
464-
}
465-
} else {
466-
showLongToast("Backup file for $backupFileName does not exist.")
467-
}
468-
}
469-
}
470-
471-
fun Context.saveToSharedPreferences(prefsFileName: String, key: String, value: Any) {
472-
val sharedPreferences: SharedPreferences = this.getSharedPreferences(prefsFileName, Context.MODE_PRIVATE)
473-
val editor = sharedPreferences.edit()
474-
475-
when (value) {
476-
is Boolean -> editor.putBoolean(key, value)
477-
is Int -> editor.putInt(key, value)
478-
is Float -> editor.putFloat(key, value)
479-
is Long -> editor.putLong(key, value)
480-
is String -> editor.putString(key, value)
481-
}
482-
483-
editor.apply()
484-
}
485-
486-
private fun isExternalStorageReadable(): Boolean {
487-
val state = Environment.getExternalStorageState()
488-
return Environment.MEDIA_MOUNTED == state || Environment.MEDIA_MOUNTED_READ_ONLY == state
489-
}
490-
491346
fun Context.hasInternetPermission(): Boolean {
492347
val permission = Manifest.permission.INTERNET
493348
val result = ContextCompat.checkSelfPermission(this, permission)

app/src/main/java/com/github/droidworksstudio/launcher/helper/AppHelper.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.droidworksstudio.launcher.helper
22

33
import android.annotation.SuppressLint
4+
import android.app.Activity
45
import android.content.ActivityNotFoundException
56
import android.content.ComponentName
67
import android.content.Context
@@ -16,8 +17,6 @@ import android.view.WindowInsets
1617
import android.widget.TextView
1718
import androidx.appcompat.widget.LinearLayoutCompat
1819
import androidx.navigation.NavOptions
19-
import com.github.droidworksstudio.common.backupSharedPreferences
20-
import com.github.droidworksstudio.common.restoreSharedPreferences
2120
import com.github.droidworksstudio.common.showLongToast
2221
import com.github.droidworksstudio.launcher.BuildConfig
2322
import com.github.droidworksstudio.launcher.utils.Constants
@@ -29,7 +28,10 @@ import com.google.gson.Gson
2928
import retrofit2.Retrofit
3029
import retrofit2.converter.gson.GsonConverterFactory
3130
import java.net.UnknownHostException
31+
import java.text.SimpleDateFormat
3232
import java.util.Calendar
33+
import java.util.Date
34+
import java.util.Locale
3335
import java.util.concurrent.TimeUnit
3436
import javax.inject.Inject
3537

@@ -192,14 +194,25 @@ class AppHelper @Inject constructor() {
192194
context.startActivity(Intent.createChooser(emailIntent, "Choose Mail Application"))
193195
}
194196

195-
fun backupSharedPreferences(context: Context) {
196-
val backupFileNames = arrayOf(Constants.PREFS_FILENAME, Constants.WEATHER_PREFS)
197-
context.backupSharedPreferences(backupFileNames)
197+
fun storeFile(activity: Activity) {
198+
// Generate a unique filename with a timestamp
199+
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
200+
val fileName = "backup_$timeStamp.json"
201+
202+
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
203+
addCategory(Intent.CATEGORY_OPENABLE)
204+
type = "application/json"
205+
putExtra(Intent.EXTRA_TITLE, fileName)
206+
}
207+
activity.startActivityForResult(intent, Constants.BACKUP_WRITE, null)
198208
}
199209

200-
fun restoreSharedPreferences(context: Context) {
201-
val backupFileNames = arrayOf(Constants.PREFS_FILENAME, Constants.WEATHER_PREFS)
202-
context.restoreSharedPreferences(backupFileNames)
210+
fun loadFile(activity: Activity) {
211+
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
212+
addCategory(Intent.CATEGORY_OPENABLE)
213+
type = "application/json"
214+
}
215+
activity.startActivityForResult(intent, Constants.BACKUP_READ, null)
203216
}
204217

205218
fun getActionType(actionType: Constants.Swipe): NavOptions {

app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ package com.github.droidworksstudio.launcher.helper
33
import android.content.Context
44
import android.content.SharedPreferences
55
import android.content.res.Configuration
6+
import android.util.Log
67
import android.view.Gravity
78
import com.github.droidworksstudio.launcher.utils.Constants
9+
import com.google.gson.Gson
10+
import com.google.gson.reflect.TypeToken
811
import dagger.hilt.android.qualifiers.ApplicationContext
912
import javax.inject.Inject
1013

1114
class PreferenceHelper @Inject constructor(@ApplicationContext context: Context) {
1215

13-
private val prefs: SharedPreferences = context.getSharedPreferences(Constants.PREFS_FILENAME, 0)
16+
private val prefs: SharedPreferences = context.getSharedPreferences(Constants.PACKAGE_PREFS, 0)
1417

1518
private val setColor = getColor(context)
1619

@@ -257,4 +260,45 @@ class PreferenceHelper @Inject constructor(@ApplicationContext context: Context)
257260
}
258261
}
259262
}
263+
264+
fun saveToString(): String {
265+
val all: HashMap<String, Any?> = HashMap(prefs.all)
266+
return Gson().toJson(all)
267+
}
268+
269+
fun loadFromString(json: String) {
270+
val editor = prefs.edit()
271+
val all: HashMap<String, Any?> =
272+
Gson().fromJson(json, object : TypeToken<HashMap<String, Any?>>() {}.type)
273+
for ((key, value) in all) {
274+
when (value) {
275+
is String -> editor.putString(key, value)
276+
is Boolean -> editor.putBoolean(key, value)
277+
is Int -> editor.putInt(key, value)
278+
is Double -> editor.putInt(key, value.toInt()) // we store everything as int
279+
is Float -> editor.putInt(key, value.toInt())
280+
is MutableSet<*> -> {
281+
val list = value.filterIsInstance<String>().toSet()
282+
editor.putStringSet(key, list)
283+
}
284+
285+
else -> {
286+
Log.d("backup error", "$value")
287+
}
288+
}
289+
}
290+
editor.apply()
291+
}
292+
293+
fun clear() {
294+
prefs.edit().clear().apply()
295+
}
296+
297+
fun clearAll(context: Context) {
298+
val prefsLauncher: SharedPreferences = context.getSharedPreferences(Constants.PACKAGE_PREFS, 0)
299+
val prefsWidgets: SharedPreferences = context.getSharedPreferences(Constants.WEATHER_PREFS, 0)
300+
301+
prefsLauncher.edit().clear().apply()
302+
prefsWidgets.edit().clear().apply()
303+
}
260304
}

app/src/main/java/com/github/droidworksstudio/launcher/helper/UpdateManagerHelper.kt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,18 @@ class UpdateManagerHelper(private val fragment: Fragment) {
162162

163163
@Deprecated("Deprecated in Java")
164164
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
165-
if (requestCode == Constants.REQUEST_INSTALL_PERMISSION) {
166-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
167-
val canInstallPackages = context.packageManager.canRequestPackageInstalls()
168-
if (canInstallPackages) {
169-
// Permission granted, proceed with installation
170-
installApk()
171-
} else {
172-
// Permission still not granted, handle accordingly
173-
context.applicationContext.showLongToast("Please allow install permission to install.")
165+
166+
when (requestCode) {
167+
Constants.REQUEST_INSTALL_PERMISSION -> {
168+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
169+
val canInstallPackages = context.packageManager.canRequestPackageInstalls()
170+
if (canInstallPackages) {
171+
// Permission granted, proceed with installation
172+
installApk()
173+
} else {
174+
// Permission still not granted, handle accordingly
175+
context.applicationContext.showLongToast("Please allow install permission to install.")
176+
}
174177
}
175178
}
176179
}

0 commit comments

Comments
 (0)