Questions regarding sharedPreferences (Kotlin) - android

I am experimenting around with Kotlin's sharedPreferences, however I cannot seem to get the updated value to stick.
val sharedPreferences = getSharedPreferences("Files", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putInt("numbers",1).apply()
val textview = findViewById<TextView>(R.id.textview)
textview.text = sharedPreferences.getInt("numbers",0).toString()
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
editor.putInt("numbers",2).apply()
textview.text = sharedPreferences.getInt("numbers",0).toString()
}
In the code above I set the initial value of the sharedPreference to 1, upon clicking the button the value will be updated to 2 and displayed.That works fine however when closing the app and reopening it, the value reverts to 1. Is there a way to permanatly keep the updated value?

You are setting it to that value every time you open the activity, since onCreate() is called every time it opens. You should check if the value is already set, and if it is, skip that line of code.
if ("numbers" !in sharedPreferences) {
val editor = sharedPreferences.edit()
editor.putInt("numbers",1).apply()
}
By the way, there is an extension function for editing without having to call apply and editor. repeatedly:
if ("numbers" !in sharedPreferences) {
sharedPreferences.edit {
putInt("numbers",1)
}
}

Related

How keep session active when user clicks checkbox compose

I have been trying to implement a checked box where is user says keep me signed in they stay signed in. The problem however is I am wondering how can I store this value in the pref and and if its positive they just log in.
in my viewModel I have this function
fun keepSignedIn(updatedValue: Boolean){
keepSignedIn.value = updatedValue
}
and in my content screen
#Composable
fun KeepMeSignedInCheckBox() {
Checkbox(checked = state.keepMeSignedIn, onCheckedChange = keepMeSignedIn.invoke(it))
}
I am wondering what is the best way to update this value in the view Model? I have my login function in the view model too.
What I have tried,
fun keepSignedIn(updatedValue: Boolean){
keepSignedIn.value = updatedValue
val signedIn = instance().keepUserSignedIn
if(signedIn){
loginUser
}
}
But my approach does not work when I leave the app it take me to login screen, and does not store that session.
Initialize the variable as
val sessionStored by mutableStateOf(
context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
.getBoolean("isSessionStored", false)
)
Where "prefs" is the name you assigned to the preferences, MODE_PRIVATE is the mode of accessing the SharedPreferences, "isSessionStored" the name of the preference field and false its default value, for obvious reasons.
Use it like so
Checkbox(checked = state.sessionStored, onCheckedChange = viewModel::setSessionStored)
Define setSessionStored like so
fun setSessionStored(sessionStored: Boolean) {
this.sessionStored = sessionStored
context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
.edit()
.putBoolean("isSessionStored", sessionStored)
.apply()
}
'll Work like a charm,
Here's a piece to code to https://youtu.be/RsEoX0FbETI

passing a value through the edit text to be consulted in the GET of the interface

ok soo this is my interface code:
interface CodeService {
#GET("sro-rastro/{code}")
fun list(#Path("code") code : String = "LB524259080HK"
) : Call<Code>
}
And that is my activity getting the value from EditText
binding.btNewPackage.setOnClickListener {
var TrackingNumber = binding.etTrackingNumber.text.toString()
}
so, i want a way to get the value of TrackingNumber and pass it in the interface instead of String = "LB524259080HK"
it is my first time using Retrofit and i'm pretty lost at how i would pass the value to my interface.
I am not sure whether your structure is right calling the API from MainActivity instead of AddActivity because the EditText is defined there. Anyway, what you can do is use SharedPreferences to save the data of trackingNumber whenever btNewPackage is clicked like this:
binding.btNewPackage.setOnClickListener {
val trackingNumber = binding.etTrackingNumber.text.toString()
val sharedPref = getSharedPreferences("preference_file_key", Context.MODE_PRIVATE)
with (sharedPref.edit()) {
putString("tracking_number", trackingNumber)
apply()
}
}
And at the time of calling the API, you can simply fetch the trackingNumber using SharedPreferences and pass it along like this:
val sharedPref = getSharedPreferences("preference_file_key", Context.MODE_PRIVATE)
val trackingNumber = sharedPref.getString("tracking_number", "")
val call = RetrofitInitializer().codeService().list(trackingNumber)

kotlin - applying changes from sharedPreferences instantly

In my app i have a settings fragment which the user can set data like the amount of decimal places they want. Currently, using shared preferences the app successfully remembers the last entered data when reopening the app. However the change is only applied when the user reopens the app and not when first applied.
the following code is located in the MainActivity.kt:
val sp = PreferenceManager.getDefaultSharedPreferences(this.applicationContext)
val decimalPlaces = sp.getString("decimalPlaces", "")
sharedViewModel.form = DecimalFormat("#,###.##")
when(decimalPlaces!!.toInt()){
0 -> sharedViewModel.form = DecimalFormat("#,###")
1 -> sharedViewModel.form = DecimalFormat("#,###.#")
2 -> sharedViewModel.form = DecimalFormat("#,###.##")
3 -> sharedViewModel.form = DecimalFormat("#,###.###")
4 -> sharedViewModel.form = DecimalFormat("#,###.####")
}
upon researching solutions to have the changes apply while still in the app, i came across the following:
Commit() and apply()
Along with other similar approaches, However i was unable to successfully implement these methods.
Would anyone have a suggestion on how to have the changes apply without exiting the app?
Changes are being applied instantly but it seems that you are only reading shared preferences when app is started. in order to change your based on the changed value of decimal place, you need to inform your Activity that decimal place value is changed and it should update the view accordingly.
One way to accomplish this is to use a LiveData object and post changed decimal place value to it, when you save to shared preferences.
In SharedViewModel declare a LiveData object
val decimalPlaces : MutableLiveData<String> = MutableLiveData()
When you save value to shared preferences, update this LiveData as
fun saveToSharedPreferences(newDecimalPlacesValue: String){
// Your code that saves to shared preferences
decimalPlaces.postValue(newDecimalPlacesValue)
}
Finally observe this LiveData in your Activity and update UI
override fun onCreate(){
...
sharedViewModel.decimalPlaces.observe(this, Observe{
if(!it.isNullOrEmpty()){
when(it.toInt()){
0 -> sharedViewModel.form = DecimalFormat("#,###")
1 -> sharedViewModel.form = DecimalFormat("#,###.#")
2 -> sharedViewModel.form = DecimalFormat("#,###.##")
3 -> sharedViewModel.form = DecimalFormat("#,###.###")
4 -> sharedViewModel.form = DecimalFormat("#,###.####")
}
}
})
}

Saving and retrieving data in Android

private var highScore: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_game)
loadData()
playGame()
}
override fun onDestroy() {
super.onDestroy()
saveData()
}
private fun saveData(){
val sharedPreferences = getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.apply{
putInt("INTEGER_KEY", highScore)
}.apply()
}
private fun loadData(){
val sharedPreferences = getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE)
val savedInt = sharedPreferences.getInt("INTEGER_KEY", 0)
highScore = savedInt
binding.highScore.text = "Highscore: $savedInt"
}
I've made a simple game and I need to store the the highscore value and retrieve the value when the app is relaunched. I've tried to use sharedPreferences in the given code. But the highscore data is lost when I close the app and relaunch it. How can I save and retrieve the value?
PS: The highscore value is saved/retrieved properly when running the app in Android Studio's emulator. But it doesn't work when I run the app on my phone. It resets to 0 every time I relaunch it.
you are trying to save, when the app is destroyed. This might work sometimes, when onDestroy is actually called, but that does not happen for sure.
Apply is saving the data asynchronous to the disk, which won't happen as you are trying to do it when the app is destroyed. You have to use commit instead of apply to save the data synchronous.
I would recommend to save the data at another point of your app instead of in onDestroy, as this won't be called every time the app is closed/killed.

SharedPreferences not updating values [duplicate]

This question already has answers here:
Misbehavior when trying to store a string set using SharedPreferences
(6 answers)
Closed 4 years ago.
I save some string values in SharedPreference and it is not updating, where I do mistake?
I try to update SharedPreference value from Timer().
I tried to use commit() and apply() after updating SharedPreference.Editor value,but it does not update values.At every step of for loop I add new values to val protocols which is getting own value from SharedPreference
val sharedPreferences = activity!!.getSharedPreferences("session",Context.MODE_PRIVATE)
val protocols = sharedPreferences.getStringSet("protocols",hashSetOf())
Log.d("old protocols",protocols.toString())
Timer().scheduleAtFixedRate(object : TimerTask() {
override fun run() {
Query(context!!).post(url,params,headers,object:ResponseCallBack{
override fun onSuccess(response: String?) {
val res = response?.string()
val document = Jsoup.parse(res)
val bals = document.select("#newspaper-b tbody tr")
if(!protocols.containsAll(bals.eachText())) {
for (bal in bals) {
val bprotokol = bal.allElements[5].text()
if (!protocols.contains(bprotokol)) {
protocols.add(bprotokol)
notification()
}
}
val editor = sharedPreferences.edit()
editor.putStringSet("protocols", protocols)
editor.apply()
val updatedProtocols = sharedPreferences.getStringSet("protocols",null)
Log.d("updated protocols",updatedProtocols.toString())
}
}
})
}
}, 0, 5000)
First Log.d("old protocols") output is {protocols=[MMX6859280]} it is okay first time opening app. In the for loop there are two values MMX6859280 and MMX6859281.
The second Log.d("updated protocols") output is {protocols=[MMX6859280,MMX6859281]},it is also okay. But when close app and open again I expected first Log.d output {protocols=[MMX6859280,MMX6859281]} but it returns {protocols=[MMX6859280]},so it is not updating values. The strange situation is when I add another value to SharedPreference with this updating,I get result what I want,but the second time all is same.
Try this
sharedPreferences.edit().putStringSet("protocols", protocols).apply();
You are applying to reference variable

Categories

Resources