16
16
package com.litekite.systemui.preference
17
17
18
18
import android.content.Context
19
- import android.content.SharedPreferences
19
+ import androidx.datastore.core.DataStore
20
+ import androidx.datastore.preferences.core.Preferences
21
+ import androidx.datastore.preferences.core.booleanPreferencesKey
22
+ import androidx.datastore.preferences.core.edit
23
+ import androidx.datastore.preferences.core.floatPreferencesKey
24
+ import androidx.datastore.preferences.core.intPreferencesKey
25
+ import androidx.datastore.preferences.core.longPreferencesKey
26
+ import androidx.datastore.preferences.core.stringPreferencesKey
27
+ import androidx.datastore.preferences.preferencesDataStore
28
+ import kotlinx.coroutines.CoroutineScope
29
+ import kotlinx.coroutines.Dispatchers
30
+ import kotlinx.coroutines.flow.Flow
31
+ import kotlinx.coroutines.flow.catch
32
+ import kotlinx.coroutines.flow.flowOn
33
+ import kotlinx.coroutines.flow.map
34
+ import kotlinx.coroutines.launch
20
35
import javax.inject.Inject
21
36
import javax.inject.Singleton
22
37
23
38
/* *
24
- * A Controller for Device Protected Shared Preferences that can be accessed even if the device
25
- * was in locked state.
39
+ * A Preference DataStore Controller for Device Protected Storage
40
+ * that can be accessed even if the device was in locked state.
26
41
*
27
42
* These preferences are stored in /data/user[release-version] or in /data/user-de[debug-version]
28
43
*
@@ -32,79 +47,84 @@ import javax.inject.Singleton
32
47
*/
33
48
@Suppress(" UNUSED" )
34
49
@Singleton
35
- class PreferenceController @Inject constructor(private val context : Context ) {
50
+ class PreferenceController @Inject constructor(context : Context ) {
36
51
37
52
companion object {
38
53
const val PREFERENCES_SYSTEM_UI = " preferences_system_ui"
39
54
}
40
55
41
- private val preferences = getPreferences()
42
- private val editor = getEditor()
56
+ private val protectedContext = context.createDeviceProtectedStorageContext()
43
57
44
- fun getBoolean ( key : String ): Boolean {
45
- return preferences.getBoolean(key, false )
46
- }
58
+ private val Context .dataStore : DataStore < Preferences > by preferencesDataStore(
59
+ PREFERENCES_SYSTEM_UI
60
+ )
47
61
48
- fun getInt (key : String ): Int {
49
- return preferences.getInt(key, 0 )
50
- }
62
+ private val scope = CoroutineScope (Dispatchers .IO )
51
63
52
- fun getLong (key : String ): Long {
53
- return preferences.getLong(key, 0 )
64
+ fun getBoolean (key : String ): Flow <Boolean > = protectedContext.dataStore.data.map { pref ->
65
+ pref[booleanPreferencesKey(key)] ? : false
66
+ }.flowOn(
67
+ Dispatchers .IO
68
+ ).catch {
69
+ it.printStackTrace()
54
70
}
55
71
56
- fun getFloat (key : String ): Float {
57
- return preferences.getFloat(key, 0F )
72
+ fun getInt (key : String ): Flow <Int > = protectedContext.dataStore.data.map { pref ->
73
+ pref[intPreferencesKey(key)] ? : 0
74
+ }.flowOn(
75
+ Dispatchers .IO
76
+ ).catch {
77
+ it.printStackTrace()
58
78
}
59
79
60
- fun getDouble (key : String ): Double {
61
- return java.lang.Double .longBitsToDouble(
62
- preferences.getLong(key, 0 )
63
- )
80
+ fun getLong (key : String ): Flow <Long > = protectedContext.dataStore.data.map { pref ->
81
+ pref[longPreferencesKey(key)] ? : 0L
82
+ }.flowOn(
83
+ Dispatchers .IO
84
+ ).catch {
85
+ it.printStackTrace()
64
86
}
65
87
66
- fun getString (key : String ): String {
67
- return preferences.getString(key, " " ) ? : " "
88
+ fun getFloat (key : String ): Flow <Float > = protectedContext.dataStore.data.map { pref ->
89
+ pref[floatPreferencesKey(key)] ? : 0F
90
+ }.flowOn(
91
+ Dispatchers .IO
92
+ ).catch {
93
+ it.printStackTrace()
68
94
}
69
95
70
- fun store (key : String , value : Boolean ) {
71
- editor.putBoolean(key, value).apply ()
96
+ fun getDouble (key : String ): Flow <Double > = protectedContext.dataStore.data.map { pref ->
97
+ java.lang.Double .longBitsToDouble(pref[longPreferencesKey(key)] ? : 0 )
98
+ }.flowOn(
99
+ Dispatchers .IO
100
+ ).catch {
101
+ it.printStackTrace()
72
102
}
73
103
74
- fun store (key : String , value : Int ) {
75
- editor.putInt(key, value).apply ()
104
+ fun getString (key : String ): Flow <String > = protectedContext.dataStore.data.map { pref ->
105
+ pref[stringPreferencesKey(key)] ? : " "
106
+ }.flowOn(
107
+ Dispatchers .IO
108
+ ).catch {
109
+ it.printStackTrace()
76
110
}
77
111
78
- fun store (key : String , value : Long ) {
79
- editor.putLong(
80
- key,
81
- value
82
- ).apply ()
83
- }
112
+ fun store (key : String , value : Boolean ) = set(booleanPreferencesKey(key), value)
84
113
85
- fun store (key : String , value : Float ) {
86
- editor.putFloat(key, value).apply ()
87
- }
114
+ fun store (key : String , value : Int ) = set(intPreferencesKey(key), value)
88
115
89
- fun store (key : String , value : Double ) {
90
- editor.putLong(
91
- key,
92
- java.lang.Double .doubleToRawLongBits((value))
93
- ).apply ()
94
- }
116
+ fun store (key : String , value : Long ) = set(longPreferencesKey(key), value)
95
117
96
- fun store (key : String , value : String ) {
97
- editor.putString(key, value).apply ()
98
- }
118
+ fun store (key : String , value : Float ) = set(floatPreferencesKey(key), value)
99
119
100
- private fun getEditor (): SharedPreferences .Editor {
101
- return preferences.edit()
102
- }
120
+ fun store (key : String , value : Double ) = set(
121
+ longPreferencesKey(key),
122
+ java.lang.Double .doubleToRawLongBits((value))
123
+ )
124
+
125
+ fun store (key : String , value : String ) = set(stringPreferencesKey(key), value)
103
126
104
- private fun getPreferences (): SharedPreferences {
105
- return context.createDeviceProtectedStorageContext().getSharedPreferences(
106
- PREFERENCES_SYSTEM_UI ,
107
- Context .MODE_PRIVATE
108
- )
127
+ private fun <T > set (prefKey : Preferences .Key <T >, value : T ) = scope.launch {
128
+ protectedContext.dataStore.edit { pref -> pref[prefKey] = value }
109
129
}
110
130
}
0 commit comments