Answer:
My migration looks like this:
fun migrate() {
val oldPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val newPreferences = EncryptedSharedPreferences.create(...)
with(newPreferences.edit()) {
oldPreferences.all.forEach { (key, value) ->
when (value) {
is Boolean -> putBoolean(key, value)
is Float -> putFloat(key, value)
is String -> putString(key, value)
is Int -> putInt(key, value)
is Long -> putLong(key, value)
is Set<*> -> putStringSet(key, value.map { it.toString() }.toSet())
else -> throw IllegalStateException("unsupported type for shared preferences migration")
}
}
apply()
}
oldPreferences.edit().clear().apply()
}
It is possible to do this without creating new shared preferences file, but why would you...
Explanation:
Any shared preferences are stored in an .xml file. You can find the file and read it, so it's not that hard to see what is happening with it.
I've tried to use EncryptedSharedPreferences with existing file and old values remained unencrypted. And EncryptedSharedPreferences are not able to access old values now.
EncryptedSharedPreferences are not encrypting the file. They encrypt keys and values separately, so your preferences.xml file might look like this:
<map>
<string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a9018b0938...</string>
<string name="AWNywuPwU...">ARu2fgn5N7wV...</string>
<string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">1288018cc6...</string>
</map>
This means you cannot run some oneliner to encrypt existing file. So I believe the only way is to make your own migration as shown in answer.
Hope it helps