How to remove values from Shared - android

I am working on android using kotlin, I have saved userId in shared preferences but when I try to remove it, it didn't removed. Am I doing it right?
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == R.id.action_settings) {
val pref = applicationContext.getSharedPreferences("Auth", Context.MODE_PRIVATE)
val editor: SharedPreferences.Editor = pref.edit()
editor.remove("UserId")
editor.commit()
Toast.makeText(this, "Sign out", Toast.LENGTH_SHORT).show()
}
return super.onOptionsItemSelected(item)
}
Login code, this is my fun which I am calling when user login and it is called like this:
saveUserIdSession(mAuth.currentUser.uid.toString())
fun saveUserIdSession(id: String) {
val sharedPreferences: SharedPreferences? =
this.activity?.getSharedPreferences("Auth", Context.MODE_PRIVATE)
var editor: SharedPreferences.Editor = sharedPreferences!!.edit()
editor.apply{
putString("UserId", id)
}.apply()
}

Deleting Android Shared Preferences in one line :-)
context.getSharedPreferences("Auth", 0).edit().clear().commit();
Thanks,
Programiner
Note:- Upvote Answer if Helpful.

Related

how to show dialog only once in Kotlin?

When opening my app a dialog is always shown that closes when you press "Ok", I would like it to only be shown the first time they open the app, this is my code:
val miDialogo = AlertDialog.Builder(this)
miDialogo.setTitle(R.string.dialogo_titulo)
miDialogo.setMessage(R.string.dialogo_mensage)
miDialogo.setPositiveButton("Ok", null)
val dialog = miDialogo.create()
dialog.show()
You can save a boolean in SharedPreferences and check it before showing the dialogue if user saw it once switch it to false.
fun isFirstRun() {
var prefs_name = "MyPrefsFile"
var isFirst = false
var prefs: SharedPreferences = getSharedPreferences(prefs_name, MODE_PRIVATE)
var isFirst: Boolean = prefs.getBoolean(prefs_name, false)
if (isFirst) {
//Show the dialogue
prefs.edit().putInt(prefs_name,
false).apply();
}
}

SharedPreferences check if data already exist

i have a problem here, i want to make if same data or value already exists in sharedpreferences it show toast if this data already exist, so i must input other value. i try to check it with contains but everytime i type same value it keeps replacing the same value
this is the code
binding.btnContinue.setOnClickListener {
dataExist()
saveData()
}
}
private fun saveData() {
val pref = this.getSharedPreferences(Data.Preferences.PREF_NAME, MODE_PRIVATE)
val fullName = binding.etFullName.text.toString()
val jobPref = binding.etJob.text.toString()
val emailPref = binding.etEmailSignUp.text.toString()
val passPref = binding.etPassSignUp.text.toString()
pref.edit {
putString(Data.Preferences.PREF_FULLNAME, fullName)
putString(Data.Preferences.PREF_JOB, jobPref)
putString(Data.Preferences.PREF_EMAIL, emailPref)
putString(Data.Preferences.PREF_PASS, passPref)
apply()
}
val intent = Intent(this, SignInActivity::class.java)
startActivity(intent)
}
private fun dataExist(): Boolean {
val pref = this.getSharedPreferences(Data.Preferences.PREF_NAME, MODE_PRIVATE)
val checkName = pref.getString(Data.Preferences.PREF_NAME, "")
val checkJob = pref.getString(Data.Preferences.PREF_JOB, "")
if (pref.contains(checkName)){
Toast.makeText(this, "Name already exist", Toast.LENGTH_SHORT).show()
return true
}else{
return false
}
}
you should check key existence, not value
boolean hasKey = pref.contains(Data.Preferences.PREF_NAME)
and also respect return of dataExist method
if (!dataExist()) saveData() // save only when not exists
edit - working example
if (pref.contains(Data.Preferences.PREF_NAME)){
val checkName = pref.getString(Data.Preferences.PREF_NAME, null)
val fullName = binding.etFullName.text.toString()
// returns true when key exists and value stored under this key
// is exactly same as entered in EditText
if (fullName.equals(checkName)) return true
}
return false // no key at all, so no data stored
You are currently calling contains on the value. You need to call contains on the key if you want to ensure whether the key exists or not.
if (pref.contains(Data.Preferences.PREF_NAME)){
Toast.makeText(this, "Name already exist", Toast.LENGTH_SHORT).show()
return true
}else{
return false
}

How to use sharedpref.edit() only once

I have a code where I called sharedPref.edit() and sharedPref.apply() multiple times. How to make convert it to call only once.
if (success) {
val data = response.getJSONObject("data")
sharedPreferences.edit().putBoolean("isLoggedIn", true).apply()
sharedPreferences.edit()
.putString("user_id", data.getString("user_id")).apply()
sharedPreferences.edit().putString("name", data.getString("name"))
.apply()
sharedPreferences.edit().putString("email", data.getString("email"))
.apply()
sharedPreferences.edit()
.putString("mobile_number", data.getString("mobile_number"))
.apply()
sharedPreferences.edit()
.putString("address", data.getString("address")).apply()
StyleableToast.Builder(this)
.text("Welcome " + data.getString("name"))
.backgroundColor(Color.RED)
.textColor(Color.WHITE).show()
userSuccessfullyLoggedIn()
}
I want to use the method call only once.
This can be called once, the returned editor instance can be stored in
a variable and re-used.
How to do this ??
These little steps will organize your code.
You can put it like this:
val editor = sharedPreferences.edit()
Then use it :
editor.putBoolean("isLoggedIn", true)
And Add others values without ".apply()"
Then Put at the End:
editor.apply()
you can create your custom Shared Preferences
class CustomSharedPreferences {
companion object {
private val PREFERENCES_USER_NAME = "preferences_user_name"
private var sharedPreferences: SharedPreferences? = null
#Volatile private var instance: CustomSharedPreferences? = null
private val lock = Any()
operator fun invoke(context: Context) : CustomSharedPreferences = instance ?: synchronized(lock){
instance ?: makeCustomSharedPreferences(context).also {
instance = it
}
}
private fun makeCustomSharedPreferences(context: Context) : CustomSharedPreferences{
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
return CustomSharedPreferences()
}
}
fun saveUser(name: String, email: String){
sharedPreferences?.edit(commit = true){
putString(PREFERENCES_USER_NAME, name)
}
}
fun getUser() = sharedPreferences?.getString(PREFERENCES_USER_NAME, "")
}
You can save all information to SP in saveUser().

Changing the App Language not working correctly (Kotlin)

I have a Splash screen in my kotlin app, where I do some stuff like loading data. Currently it is only in german and I wanted to add english as additional language.
I've create the strings resources and so on.
Now I have added a bit of code to the Splash-Screen, where it checks, if the user already set a preferenced language (saved in sharedPreferences).
When there is nothing saved, a simple alertdialog pops up asking the user for his preference and sets everything accordingly.
Then the splashscreen is reloaded. When I choose english on my device (system language is german), the splash screen gets the correct string resources (english).
But when it changes to the MainActivity, it is german again. Only after restarting the app, everything is in english.
Here is how I change the language on my splashscreen:
private lateinit var mainIntent : Intent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
var localeToSet: String? = prefs.getString("language", "")
if(localeToSet == null || localeToSet.equals("")){
val languages = arrayOf("Deutsch", "English")
val langSelectorBuilder = AlertDialog.Builder(this)
langSelectorBuilder.setTitle(R.string.selectLanguageText)
langSelectorBuilder.setCancelable(false)
langSelectorBuilder.setSingleChoiceItems(languages, -1) { dialog, selection ->
when(selection) {
0 -> {
localeToSet = "de"
setLocale("de")
}
1 -> {
localeToSet = "en"
setLocale("en")
}
}
recreate()
dialog.dismiss()
}.setOnDismissListener {
Handler().postDelayed({
startActivity(mainIntent)
finish()
}, SPLASH_TIME_OUT)
}
langSelectorBuilder.create().show()
}
else{
setLocale(localeToSet!!)
Handler().postDelayed({
startActivity(mainIntent)
finish()
}, SPLASH_TIME_OUT)
}
setContentView(R.layout.activity_splash_screen)
}
private fun createIntent(localeToSet: String){
mainIntent = Intent(this#SplashScreenActivity, MainActivity::class.java).apply {
//Do stuff and pass data to mainactivity
}
private fun setLocale(localeToSet: String) {
createIntent(localeToSet)
val config = resources.configuration
val locale = Locale(localeToSet)
Locale.setDefault(locale)
config.locale = locale
resources.updateConfiguration(config, resources.displayMetrics)
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val editor: SharedPreferences.Editor = prefs.edit()
editor.putString("language", localeToSet)
editor.apply()
}
Nevermind, found the issue:
val langSelectorBuilder = AlertDialog.Builder(this)
langSelectorBuilder.setTitle(R.string.selectLanguageText)
langSelectorBuilder.setCancelable(false)
langSelectorBuilder.setSingleChoiceItems(languages, -1) { dialog, selection ->
when(selection) {
0 -> {
localeToSet = "de"
setLocale("de")
}
1 -> {
localeToSet = "en"
setLocale("en")
}
}
recreate()
dialog.dismiss()
}.setOnDismissListener {
finish()
}
langSelectorBuilder.create().show()
Without starting the MainActivity here, it works like it should

App crashes on reading shared preferences after obfuscation

In my application, I am using SharedPreferences to store some user preferences. The application was not obfuscated (-dontobfuscate in the proguard file).
Now in the next version of the application, I want to enable obfuscation. When I try this, the application returns NullPointerException while reading the SharedPreferences data from the previous version of the application. The error log is not helpful because the code is already obfuscated and it does not provide meaningful information. However, while trying in the debug mode I found the crash may be due to null context which is a static variable in the code! That should not be the case because the application works file if SharedPreferences were not there already.
Is there any way the app can still read the SharedPreferences data from unobfuscated version?
Writing / reading the SharedPreferences is pretty standard:
Writing:
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor prefsEditor = mPrefs.edit();
prefsEditor.putString("userUnitsOption", "C");
//apply the storage
prefsEditor.apply();
Reading:
final SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
return mPrefs.getString("userUnitsOption", "A");
If you want to use shared preferences in Android then use it as given below :
First, you have to store your preferences like this :
SharedPreferences.Editor editor = getSharedPreferences("mySharedPref", MODE_PRIVATE).edit();
editor.putString("myName", "abc");
editor.apply();
Now, To read or get those stored shared preferences write code as given below :
SharedPreferences prefs = MainActivity.this.getSharedPreferences("mySharedPref", MODE_PRIVATE); // Here MainActivity.this represent the context. So you can use your context in place of MainActivity.this
String strName = prefs.getString("myName","defaultName");
In Kotlin,
Usage:
private val sharedPref = defaultPrefs(this)
To Save Data--> sharedPref[KEY] = *String data to save*
To Get Data --> val userDetails = sharedPref[KEY, ""]
Create a shared preference helper class like below.
object PreferenceHelper {
fun defaultPrefs(context: Context): SharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context)
fun customPrefs(context: Context, name: String): SharedPreferences =
context.getSharedPreferences(name, Context.MODE_PRIVATE)
inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
/**
* puts a key value pair in shared prefs if doesn't exists, otherwise updates value on given [key]
*/
operator fun SharedPreferences.set(key: String, value: Any?) {
when (value) {
is String? -> edit { it.putString(key, value) }
is Int -> edit { it.putInt(key, value) }
is Boolean -> edit { it.putBoolean(key, value) }
is Float -> edit { it.putFloat(key, value) }
is Long -> edit { it.putLong(key, value) }
else -> throw UnsupportedOperationException("Not yet implemented")
}
}
/**
* finds value on given key.
* [T] is the type of value
* #param defaultValue optional default value - will take null for strings, false for bool and -1 for numeric values if [defaultValue] is not specified
*/
inline operator fun <reified T : Any> SharedPreferences.get(
key: String,
defaultValue: T? = null
): T? {
return when (T::class) {
String::class -> getString(key, defaultValue as? String) as T?
Int::class -> getInt(key, defaultValue as? Int ?: -1) as T?
Boolean::class -> getBoolean(key, defaultValue as? Boolean ?: false) as T?
Float::class -> getFloat(key, defaultValue as? Float ?: -1f) as T?
Long::class -> getLong(key, defaultValue as? Long ?: -1) as T?
else -> throw UnsupportedOperationException("Not yet implemented")
}
}
}

Categories

Resources