Skip to content

Instantly share code, notes, and snippets.

@zmdominguez
Last active July 1, 2019 08:42
Show Gist options
  • Save zmdominguez/421497ece83c84b80d473d4fcc6e782e to your computer and use it in GitHub Desktop.
Save zmdominguez/421497ece83c84b80d473d4fcc6e782e to your computer and use it in GitHub Desktop.
Inspecting and Resetting preferences

This is a helper function for an app's debug or development drawer and is designed to be pasted into an Activity. It retrieves all files from shared_prefs and allows the user to choose which files to inspect or reset to default values. It is extremely helpful when testing one-shot scenarios such as for hints or onboarding, etc.

It assumes that the files are named in a consistent and predictable way -- more specifically by prefixing them with the application ID as mentioned here. For maximum consistency, this assumes that files are named similar to how the system names the default SharedPreferences file (MY.PACKAGE.ID_my_preferences).

All the application-specific preferences files are displayed in an AlertDialog. For readability, the application ID is stripped out.

fun getNiceSharedPrefNames(sharedPrefs: Array<String>): Array<String> {
// Sample: com.woolworths.debug.debug_prefs
// Get the nice displayable name
// Sample: debug_prefs
val niceName = sharedPrefs.map {
it.removePrefix(BuildConfig.APPLICATION_ID)
.removePrefix("_")
.removePrefix(".")
}
return niceName.toTypedArray()
}
fun getAllSharedPrefs(): Array<String> {
val dataDir = File("${filesDir.parent}/shared_prefs")
// Get the prefs files we are concerned with
// Sample: /data/user/0/com.woolworths.debug/shared_prefs/com.woolworths.debug.debug_prefs.xml
val sharedPrefsFiles = dataDir.listFiles().filter { file ->
file.name.startsWith(BuildConfig.APPLICATION_ID)
}
// Get the names for retrieving with getSharedPreferences()
// Sample: com.woolworths.debug.debug_prefs
val androidReadableNames = sharedPrefsFiles.map { file ->
file.name.split(".xml").first()
}
return androidReadableNames.toTypedArray()
}
fun inspectPreferences() {
val sharedPrefs = getAllSharedPrefs()
// We want to use the nice names as list options
// Sample: debug_prefs
val niceSharedPrefNames = getNiceSharedPrefNames(sharedPrefs)
AlertDialog.Builder(this).apply {
setTitle("Inspect Preferences")
setItems(niceSharedPrefNames) { _, which ->
val prefName = sharedPrefs[which]
AlertDialog.Builder(this@DebugInspectActivity).apply {
setTitle(niceSharedPrefNames[which])
// Android needs the file name
// Sample: com.woolworths.debug.debug_prefs
val allVals = getSharedPreferences(prefName, Context.MODE_PRIVATE).all.map { entry ->
"\n${entry.key}: ${entry.value}"
}
setMessage(allVals.toString())
setPositiveButton("Done", null)
}.create().show()
}
}.create().show()
}
fun resetPreferences() {
val sharedPrefs = getAllSharedPrefs()
val selectedItems = mutableListOf<Int>()
val alert = AlertDialog.Builder(this).apply {
setTitle("Reset Preferences")
// We want to use the nice names as list options
// Sample: debug_prefs
setMultiChoiceItems(getNiceSharedPrefNames(sharedPrefs), null
) { _, which, isChecked ->
when {
isChecked -> selectedItems.add(which)
selectedItems.contains(which) -> selectedItems.remove(which)
}
}
setPositiveButton("Clear", null)
setNegativeButton("Cancel", null)
}.create()
alert.setOnShowListener {
alert.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
selectedItems.forEach { prefIndex ->
// Android needs the file name
// Sample: com.woolworths.debug.debug_prefs
val prefName = sharedPrefs[prefIndex]
getSharedPreferences(prefName, Context.MODE_PRIVATE).edit().clear().apply()
alert.dismiss()
}
}
}
alert.show()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment