Saving and retrieving data in Android - 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.

Related

Questions regarding sharedPreferences (Kotlin)

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)
}
}

How to save variable data in Kotlin

I'm trying to make this so that is saves every time I close the app. The tutorials I found are not clear for me, can anyone please assist me? If needed, here's how my variable I want saved is defined:
private var coins = 0
Here is the GitHub link if needed, which goes straight to MainActivity.
You can use shared preferences to save and retrieve simple data
save data
val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) ?: return
with (sharedPref.edit()) {
putInt("MY_COINS", coins)
apply()
}
Read data
val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) ?: return
val coins = sharedPref.getInt("MY_COINS"), defaultValue)
You can use Shared Preferences for state management or save data in key-value pair.
lateinit var shared : SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_spactivity)
shared = getSharedPreferences("CoinsDB" , Context.MODE_PRIVATE)
var coins = 0
For Save
val edit = shared.edit()
edit.putInt("coins" , coins )
edit.apply()
For retrieve or read
val coinsValue = shared.getInt("coins")
I recommend using storage in files if that isn't a problem for you.

Looking for a way to persist user data

I need my users to be able to enter an API key in a "Setup" fragment and I need to use this API key in various other places such as other Fragments, Activities, Workers.
It is my understanding so far that getSharedPreferences is designed for this sort of purpose, much like the NSUserDefaults under iOS: save something somewhere, get it elsewhere.
Yet I can't seem to get the getSharedPreferences thing to work, I've had it initialized throughout the app with MainActivity.context but it always loses the data (the API key)
I am using ModelPreferencesManager https://gist.github.com/malwinder-s/bf2292bcdda73d7076fc080c03724e8a
I have an ApplicationState class as follows:
public class ApplicationState : Application() {
companion object {
// ...
lateinit var mContext: Context
var api_key : String = "undefined"
// ...
}
fun save(){
Log.e("ApplicationState", "save")
ModelPreferencesManager.with(mContext)
ModelPreferencesManager.put(api_key , key: "api_key_identifier")
}
fun load(){
Log.e("ApplicationState", "load")
ModelPreferencesManager.with(mContext)
api_key = ModelPreferencesManager.get<String>(key: "api_key_identifier") ?: "not read"
}
}
First, I store the application context on the first Activity (before anything else):
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
ApplicationState.mContext = applicationContext
// ...
}
}
I now expect to be able to save the api_key as follows:
ApplicationState.api_key = "blablah" // from some input in a random fragment
ApplicationState.save()
And to load it later:
ApplicationState.load()
var api_key = ApplicationState.api_key // in some activity or random fragment or worker
However it doesn't produce the expected result, the api_key is not saved (or loaded? can't figure out)
I have also tried using a JSON file but still no luck, looks like it either doesn't write/read or just gets deleted for some reason.
I could use a helping hand from someone more experienced as I am new to Android development and can't seem to find my way through these intricacies
I don't know what you are doing with your ModelPreferencesManager.
But this is the standard way to save something in preferences.
val sharedPref = requireContext().getSharedPreferences(keyPrefIdentifier,
Context.MODE_PRIVATE) //get shared preferences
val editor = sharedPref.edit() //make modifications to shared preferences
editor.putString("userApiKeyIdent", "theActualKey")
editor.apply() //save shared preferences persitent.
This is how you read them again.
val sharedPref = requireContext().getSharedPreferences(keyPrefIdentifier,
Context.MODE_PRIVATE)
val apiKey = sharedPref.getString("userApiKeyIdent", "defaultValue")
Edit: You are saving the api key as the identifiery for the preference. But get it as "api key "
It should look like this
fun save(){
Log.e("ApplicationState", "save")
ModelPreferencesManager.with(mContext)
ModelPreferencesManager.put("api_key ", api_key) //like this
}

How to save app data in Android after app shutdown using onSaveInstanceState()?

I am trying simulate app shut down using ADB. I am storing the data in a bundle in onSaveInstanceState() so that I'm able to get the data back once I get back to the app. But I'm unable to get the data back.
Here's the code I'm using (It's from one of Google's codelabs)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dessertTimer = DessertTimer(this.lifecycle)
if(savedInstanceState != null)
{
revenue = savedInstanceState.getInt(KEY_REVENUE,0)
dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD,0)
dessertTimer.secondsCount = savedInstanceState.getInt(KEY_TIMER_SECONDS,0)
}
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.dessertButton.setOnClickListener {
onDessertClicked()
}
binding.revenue = revenue
binding.amountSold = dessertsSold
binding.dessertButton.setImageResource(currentDessert.imageId)
}
This is the code in onSaveInstanceState()
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
outState!!.putInt(KEY_REVENUE,revenue)
outState!!.putInt(KEY_DESSERT_SOLD,dessertsSold)
outState!!.putInt(KEY_TIMER_SECONDS,dessertTimer.secondsCount)
}
As #Beko has said, don't use onSaveInstaceState to save something you'll need after an app shutdown. It can not be recovered.
You have two solutions:
Use SharedPreferences.Editor to store your data. SharedPreference.Editor can be got through SharedPreferences#edit;
Or store the data you need to be saved in a database and fetch it later.

How to save a score in Kotlin?

How can I save a score in my game scene even if I close the app and open it again? I'm new to android and I only know that in Swift things like that can be saved by using user defaults but I don't what to do in Android Studio.
Here is the score I want to save:
var score = 1
later in the scene ->
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
score =+ 2 //save the score here
}
If you want to use shared preferences, you can do the following:
Getting the shared preferences (if you only need one shared preferences file) instance by adding this code:
val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE)
Write to shared preferences using:
sharedPref.edit()
putInt("Score", score)
commit()
Read from shared preferences using:
val score = sharedPref.getInt(getString("Score"), 0)

Categories

Resources