Function saves maximum speed - android

I'm trying to do a function that will only save a higher speed than the one already saved.
But the var outside the if loop is always 0.0, inside value is different. Does anyone knows some resolve or even better idea how to save only maximum speed?
private fun updateUI(speed: Double, distance: Double){
val df = DecimalFormat("0.0")
speed_text_view.text = df.format(speed).plus(" km/h")
distance_text_view.text = df.format(distance)
Log.e("getLocationUpdates", df.format(speed))
var getSpeedDouble = 0.0 //here is problem. The value doesn't change
if (speed > getSpeedDouble) {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
val editor = sharedPref.edit()
editor
.putString("SPEED", speed.toString())
.apply()
val getSharedPref = PreferenceManager.getDefaultSharedPreferences(this)
getSharedPref.apply {
val getSpeed = getString("SPEED", "")
getSpeedDouble = getSpeed!!.toDouble()
Log.e("GetSpeedDouble", getSpeedDouble.toString())
max_speed_text_view.text = getSpeed.toString()
}
}
}

For posterity:
Have the speed as a global variable.
val speed:Double = 0.0
when you load the activity fetch its value from the shared preferences:
val preference = getSharedPreferences(yourApp, Context.MODE_PRIVATE)
val editor = preference.edit()
speed = preference.getDouble(“SPEED”,0.0)
when you finish the activity write the value back to the shared preferences:
editor.putDouble(“SPEED”,speed)
editor.commit()
within your method just assign a new value to the variable only if the current reading is bigger than the saved value.
private fun updateUI(newSpeed:Double) {
if (newSpeed > speed)
{
speed = newSpeed
textview.setText((newSpeed).toString())
}
}

How about putting it away in a nice class, and when just initializing that class from you activity:
speedKeeper = MaxSpeedKeeper(this)
then all you have to do is drop in your speeds (ie. speedKeeper.speed = 10.4) and it will stay updated.
Apply() will update to disk async, but the value in initialized sharedPref will stay cached, and is read from companion object's maxSpeed anyway.
This way, you can just drop your speedkeeper in any other processes, classes, fragments etc and it will keep doing what it does, or just initialize it again in a new activity.
class MaxSpeedKeeper(context: Context) {
companion object {
const val SPEED = "SPEED"
const val SHAREDPREFS_NAME = "MY_SHAREDPREFS"
var maxSpeed = 0.0f
}
var speed: Double
get() = maxSpeed.toDouble()
set(speedToCheck) {
if (speedToCheck > maxSpeed) {
maxSpeed=speedToCheck.toFloat()
with(sharedPref.edit()) {
putFloat(SPEED, speedToCheck.toFloat()) // you could change this to a string or bits or something if you want more resolution than a float gives
apply()
}
}
}
private val sharedPref =
context.getSharedPreferences(SHAREDPREFS_NAME, Context.MODE_PRIVATE)
init {
maxSpeed = sharedPref.getFloat(SPEED, 0.0f)
}
}

private fun updateUI(speed: Double) {
var getSpeedDouble = 0.0 //here is problem. The value doesn't change
if (speed > getSpeedDouble) {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
val editor = sharedPref.edit()
editor.putString("SPEED", speed.toString()).apply()
val defaultSpeed = sharedPref.getString("SPEED", "")
getSpeedDouble = defaultSpeed.toString().toDouble()
Log.e("updateUI", getSpeedDouble.toString())
}
}
private fun getSpeed() {
var getSpeedDouble: Double
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
val defaultSpeed = sharedPref.getString("SPEED", "")
getSpeedDouble = defaultSpeed.toString().toDouble()
Log.e("getSpeed", getSpeedDouble.toString())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
updateUI(10.0)
getSpeed()
}
output
updateUI: 10.0
getSpeed: 10.0

Related

Operations With Android LiveData in EditText?

I have 3 editext and I have to multiply the numbers written in the first two, and make the result appear live on the third using Android Livedata.
viewModel.num1.observe(this,
Observer { newNum1-> binding.ediText1.text = newNum1.toString() }
viewModel.num2.observe(this,
Observer { newNum2-> binding.ediText2.text = newNum2.toString() }
viewModel.num3.observe(this,
Observer { newNum3-> binding.ediText3.text = newNum3.toString() }
I tried something like this, with 2 MutableLiveData and one MediatorLivedata, but i did something wrong because it didn't update live the third EditText. Could someone help me?
class MyViewModel : ViewModel() {
private var num1 = MutableLiveData<Int>();
private var num2 = MutableLiveData<Double>();
private var mun3 = MediatorLiveData<Double>();
num3.addSource(num1, this::onChanged);
num3.addSource(num2, this::onChanged);
private fun onChanged(x : Double) {
var a = num1.value
var b = num2.value
if (a== null)
a= 0;
if (b== null)
b= 0.0;
num3.setValue(a * b);
}
}
I'm using Kotlin but i accept any kind of code, even in java.
Thank you for your patience and help!
Best regards, Mark.
Please try something like that, but be aware of nullability. One of received values can be null
fun <A, B> LiveData<A>.combineWith(b: LiveData<B>): LiveData<Pair<A?, B?>> =
MediatorLiveData<Pair<A?, B?>>().apply {
var lastA: A? = this#combineWith.value
var lastB: B? = b.value
addSource(this#combineWith) {
lastA = it
value = Pair(lastA, lastB)
}
addSource(b) {
lastB = it
value = Pair(lastA, lastB)
}
}
viewModel.num1
.combineWith(viewModel.num2)
.observe(
this,
Observer { (first, second) ->
if (first != null && second != null) {
someEditText.text = (first * second).toString()
}
}
)
That might not be your literal code, because it's not compileable. You can't pass the same function to be used as the observer for either source, since the source types are different.
Your onChanged() function doesn't use the input parameter, so you can remove that and call it from a lambda you pass to each addSource call.
You can also simplify the content of your function by using Elvis operators.
private val num1 = MutableLiveData<Int>()
private val num2 = MutableLiveData<Double>()
private val num3 = MediatorLiveData<Double>().apply {
addSource(num1) { onChanged() }
addSource(num2) { onChanged() }
}
private fun onChanged() {
val a = num1.value ?: 0
val b = num2.value ?: 0.0
num3.value = a * b
}

Saving Switch State In Kotlin

Whenever I open the app and click the switch, dark mode turns on and it stays in the position. However, if I relaunch the app, the switch goes back to default, and dark mode is still on. How would I do this in Kotlin?
Also, is there any reference code for this in Kotlin?
Create Pref class for storing data.
class Prefs (private val context: Context)
private fun getSharedPreferences(prefsName: String) =
context.getSharedPreferences(prefsName, Context.MODE_PRIVATE)
private val PREF_KEY = "pref_key"
private val KEY_VALUE = "key_value"
private val prefValue by lazy { getSharedPreferences(PREF_KEY) }
var currentModeDayNight: Boolean
get() {
return prefValue.getBoolean(KEY_VALUE, false)
}
set(value) {
prefValue.edit().putBoolean(KEY_VALUE, value).apply()
}
Then store data for default dayNightMode.
You may just need to restart your app. But keep in mind, that this code enables the Dark Mode System-wide, not just in App:
public static void setNightMode(Context target){
UiModeManager uiManager = (UiModeManager) target.getSystemService(Context.UI_MODE_SERVICE);
if (VERSION.SDK_INT <= 22) {
uiManager.enableCarMode(0);
}
val pref = Pref(context)
if (pref.currentModeDayNight) {
pref.currentModeDayNight = false
uiManager.setNightMode(UiModeManager.MODE_NIGHT_YES);
} else {
pref.currentModeDayNight = true
uiManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
}
}

Kotlin - Get new index of item in shuffled list

I have a multiple choice quiz with 4 choices per answer. In the ArrayList with the questions and choices, the correct answer is set to the index of the correct option. I want to shuffle the choices but am not sure how to identify the new index of the correct answer. Any thoughts?
Question object
object ConstantsAnalysis {
const val TOTAL_CORRECT: String = "total_correct"
const val TOTAL_OPP: String = "total_opp"
fun getQuestions3(): ArrayList<Questions3> {
val questionList = ArrayList<Questions3>()
val q1 = Questions3(1, null,
"On a graph, the horizontal line along which data are plotted is the _____",
"y axis", "x axis", "origin", "quadrant", 2, R.string.Jones_1995, null)
questionList.addAll(listOf(q1))
questionList.shuffle()
return questionList
}
}
Data class
data class Questions3(
val id: Int, val image: Int?, val question: String, val option1: String, val option2: String,
val option3: String, val option4: String, val correctAnswer: Int, val dialogBox: Int?, val dialogBox2: Int?)
Shuffle choices
val ansorder = arrayOf(question.option1, question.option2, question.option3, question.option4)
ansorder.shuffle()
radio_button1.text = ansorder[0]
radio_button2.text = ansorder[1]
radio_button3.text = ansorder[2]
radio_button4.text = ansorder[3]
Check answer choice
if (questions3!!.correctAnswer != mSelectedOptionPosition) {
//do x
}
Edit (Since correct answer is a string and the index changes after shuffling, answerView(questions3.correctAnswer, R.drawable.correct_option_border.
class QuestionsActivityAnalysis : AppCompatActivity(), View.OnClickListener {
private var mCurrentPosition:Int = 1
private var mQuestionsList:ArrayList<Questions3>? = null
private var mSelectedOptionPosition:Int = 0
private var mCorrectAnswers: Int = 0
private var mSelectedOptionText: String? = null
private fun shuffle() {
val question = mQuestionsList!![mCurrentPosition - 1]
val ansorder = arrayOf(question.option1, question.option2, question.option3, question.option4)
ansorder.shuffle()
radio_button1.text = ansorder[0]
radio_button2.text = ansorder[1]
radio_button3.text = ansorder[2]
radio_button4.text = ansorder[3]
}
override fun onClick(v: View?) {
when(v?.id){
R.id.radio_button1 -> { selectedOptionView(radio_button1, 1)
mSelectedOptionText = radio_button1.text as String?
}
R.id.radio_button2 -> { selectedOptionView(radio_button2, 2)
mSelectedOptionText = radio_button2.text as String?
}
R.id.radio_button3 -> { selectedOptionView(radio_button3, 3)
mSelectedOptionText = radio_button3.text as String?
}
R.id.radio_button4 -> { selectedOptionView(radio_button4, 4)
mSelectedOptionText = radio_button4.text as String?
}
R.id.btn_submit -> {
val questions3 = mQuestionsList?.get(mCurrentPosition - 1)
if (questions3!!.correctAnswer != mSelectedOptionText) {
} else {
mCorrectAnswers++
}
answerView(questions3.correctAnswer, R.drawable.correct_option_border)
private fun answerView(answer: Int, drawableView: Int) {
when(answer){
1 -> {
radio_button1.background = ContextCompat.getDrawable(this, drawableView)
}
2 -> {
radio_button2.background = ContextCompat.getDrawable(this, drawableView)
}
3 -> {
radio_button3.background = ContextCompat.getDrawable(this, drawableView)
}
4 -> {
radio_button4.background = ContextCompat.getDrawable(this, drawableView)
}
}
}
I would really recommend just creating a data class like this:
data class QuestionOption(val question:String, val isCorrect = false)
Afterwards you can shuffle any way you like and just check if the selected QuestionOption has isCorrect set to true. You get a bunch of benefits and the logic gets simpler.
Edit:
To make it easier to declare questions this way:
In general if you add questions in your code you want only as much necessary code as required. For this you can either declare a good constructor or a function that basically maps your values to a constructor. In your case I'd say
data class Questions3(
val id: Int, val question: String, val option1: String, val option2: String,
val option3: String, val correctOption: String, val image: Int?=null,val dialogBox1: Int?=null,val dialogBox2: Int?=null)
(notice how the optional parameters are last, you don't need to specify them as well thanks to them beeing null by default)
Makes sense, in theory you could also (not too clean but easy) just shuffle option 1-3 & correctOption and then just compare if the correctOption String matches the selected String.
Otherwise as I said, you can always create logic for mapping stuff. Here you can either map from Constructor to another Constructor, same with Functions that return a finished Object.

Kotlin: How to save values from RatingBar?

I created a RatingBar in my application. It is for rating movies. I want value to be saved. When I login and go to that activity, I want to see that stars that I rated. It is difficult for me to find the answer because it is written in Kotlin and I'm new to it.
I searched for many other questions and answers, but with no result. Can you tell me what I need to change in my code?
class MovieDetailsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_movie_details)
fiveStars()
val sharedPreference = getPreferences(Context.MODE_PRIVATE)
val rating = sharedPreference.getFloat("numStars", 0f)
ratingBar.rating = rating
}
private fun fiveStars() {
val ratingBar = findViewById<RatingBar>(R.id.ratingBar)
ratingBar.onRatingBarChangeListener = RatingBar.OnRatingBarChangeListener()
{ ratingBar: RatingBar, fl: Float, b: Boolean ->
val sharedPreference = getSharedPreferences("numStars", Context.MODE_PRIVATE)
val editor = sharedPreference.edit()
editor.putFloat("numStars", fl)
editor.apply()
Log.d("rate", ratingBar.rating.toString())
}
}
}
I tried a lot of things, but nothing is working. Hope you could help me. Thanks!
It seems like you're using two different preferences.
Here you are calling getPreferences(Context.MODE_PRIVATE):
val sharedPreference = getPreferences(Context.MODE_PRIVATE)
val rating = sharedPreference.getFloat("numStars", 0f)
ratingBar.rating = rating
and here you are using a specific sharedPreferences:
val sharedPreference = getSharedPreferences("numStars", Context.MODE_PRIVATE)
val editor = sharedPreference.edit()
Either use getPreferences(Context.MODE_PRIVATE) in both cases, or use getSharedPreferences("numStars", Context.MODE_PRIVATE) in both cases

How to set button disabled for 24 hours after some clicks

I have set a button click for some background API service to execute and after 3 clicks,I want the button to be disabled and only enabled after 24 hours.I did the following code but it is failed to be disabled.Here...
companion object {
var clickCount = 0
const val SAVED_TIME = "Time is saved"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val convert: Button = findViewById(R.id.Cbutton)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
inputAmount = findViewById(R.id.editText)
inputAmount!!.textSize = 30f
spin = findViewById(R.id.spin)
birr = findViewById(R.id.converted)
birr!!.text = getString(R.string.initialValue)
progressIndicator = findViewById(R.id.progressBar)
statusBarColorChange()
connectionStatusUpdate()
currencyListAdapterExecute()
convert.setOnClickListener {
val sharedPrefs = applicationContext.getSharedPreferences(SAVED_TIME,Context.MODE_PRIVATE)
if (inputAmount!!.text.isNotEmpty() && connected) {
val dateNow = Date().time
val savedDateTime = sharedPrefs.getLong("time",0)
if(savedDateTime == dateNow){
convert.isEnabled = false
}
clickCount += 1
if(clickCount < 4){
FetchedJsonData(this).execute()
}
else {
val exactTime = Date().time
sharedPrefs.edit().putLong("time",exactTime).apply()
}
}
You can store time in shared preference by following code.
SharedPreferences settings = c.getSharedPreferences(PREFS_NAME, 1);
SharedPreferences.Editor editor = settings.edit();
editor.putString("click_time", your_time);
Whenever need to compare, just compare your current time with the time stored in preference. Check if difference between time is less than 24 hours or not.
TO get time from prefernce:
SharedPreferences settings = c.getSharedPreferences(PREFS_NAME, 1);
String storedTime=settings.getString("clic_time", "");
Get difference in hours:
Date current, Date previous;
long diff = current.getTime() - previous.getTime();
long hours= diff / (60*60 * 1000);
To show timer, when app comes from background, you can get time from preference and start timer by using difference between 2 times.

Categories

Resources