I click the button first time to turn on the flashlight enable the seekBar. then on the second click the button switch the text and stop the flashlight and disable the seekBar.
the problem is if i click the button many times in a row sometimes i need to click the button like 3-4-5 times in a row before it will change the state. sometimes it’s working well and change the state on each single click but many times i need to click more times to change the state.
i suspect that it’s something either with the flag bool logic or the loop that does not stop sometimes.
my code:
package com.example.flashlight
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Button
import android.widget.ImageButton
import android.widget.SeekBar
import android.widget.TextView
class MainActivity : AppCompatActivity() {
var flashLightStatus: Boolean = false
var flashLightOn = false
var counter: Long = 0
private val handler = Handler(Looper.getMainLooper())
@SuppressLint("SetTextI18n", "MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = findViewById<TextView>(R.id.text_view)
val seek = findViewById<SeekBar>(R.id.seekBar)
val button = findViewById<Button>(R.id.my_button)
// Initially, disable the SeekBar
seek.isEnabled = false
seek.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar?,
progress: Int,
fromUser: Boolean
) {
counter = progress.toLong()
textView.text = counter.toString()
}
override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
override fun onStopTrackingTouch(seekBar: SeekBar?) = Unit
},
)
// Set an OnClickListener for the button
button.setOnClickListener {
if (flashLightOn) {
// If the flashlight is on, turn it off and change the button background to "Turn On"
seek.isEnabled = false
flashLightOn = false
handler.removeCallbacksAndMessages(null) // Stop the flashing effect
openFlashLight() // Ensure the flashlight is turned off
} else {
// If the flashlight is off, turn it on and change the button background to "Turn Off"
seek.isEnabled = true
flashLightOn = true
HandleFlashlight() // Start the flashlight logic with the flashing effect
}
}
}
override fun onBackPressed() {
finish()
System.exit(0)
}
private fun openFlashLight() {
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraId = cameraManager.cameraIdList[0]
if (flashLightOn) {
try {
cameraManager.setTorchMode(cameraId, true)
flashLightStatus = true
} catch (e: CameraAccessException) {
e.printStackTrace()
}
} else {
try {
cameraManager.setTorchMode(cameraId, false)
flashLightStatus = false
} catch (e: CameraAccessException) {
e.printStackTrace()
}
}
}
private fun HandleFlashlight() {
// Clear any existing callbacks
handler.removeCallbacksAndMessages(null)
// Set up the repeating task
handler.postDelayed(object : Runnable {
override fun run() {
if (flashLightOn) {
openFlashLight() // Turn the flashlight on
} else {
openFlashLight() // Turn the flashlight off
}
// Toggle the flashlight state for the next cycle
flashLightOn = !flashLightOn
// Schedule the next toggle after 'counter' milliseconds
handler.postDelayed(this, counter)
}
}, counter)
}
}