Encrypted shared prefs

A class that is using the “normal” shared preferences for any device with an sdk < M and the EncryptedSharedPreferences for M and above.

Usage

Gradle dependency:

implementation "androidx.security:security-crypto:$security_version"
``

Sample usage using Koin DI, inside an Activity:

```kotlin
private val appModule = module {
    single {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            EncryptedSharedPrefs(applicationContext)
        } else
            SimplePreferences(applicationContext)
    }
}

override fun onCreate() {
    super.onCreate()
    startKoin {
        androidLogger()
        androidContext(this@App)
        modules(appModule)
    }
}

Usage:

class MyFragment : Fragment(R.layout.fragment_my) {
	private val preferences: Preferences by inject()

	...

	preferences.mySetting = false
}

AndroidManifest.xml

If the min SDK is smaller than 27, this line should be added in the Manifest:

<uses-sdk tools:overrideLibrary="androidx.security" />

Preferences.kt

interface Preferences {
    var mySetting: Boolean
    fun get(): SharedPreferences
}

class SimplePreferences(context: Context) : Preferences {
    private val preferences: SharedPreferences =
        context.getSharedPreferences("myapp_preferences", Context.MODE_PRIVATE)

    override fun get(): SharedPreferences = preferences

    override var mySetting: Boolean
        get() = preferences.getBoolean(App.MY_SETTING_PREF_KEY, true)
        set(value) = preferences.edit().putBoolean(App.MY_SETTING_PREF_KEY, value).apply()
}

@TargetApi(Build.VERSION_CODES.M)
class EncryptedSharedPrefs(val context: Context) : Preferences {

    private var encryptedPrefs: SharedPreferences = EncryptedSharedPreferences.create(
        "myapp_encrypted_prefs",
        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
        context,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )

    override fun get(): SharedPreferences = encryptedPrefs

    // A shortcut property to access data stored in the prefs in a consistent way
    override var mySetting: Boolean
        get() = encryptedPrefs.getBoolean(App.MY_SETTING_PREF_KEY, null)
        set(value) = encryptedPrefs.edit().putBoolean(
            App.MY_SETTING_PREF_KEY,
            value
        )
}