Reputation: 1
I have an Activity which is a camera. In that activity, there is permission before using the camera, but there is a problem when the user allows the use of the camera, namely the application will return to the previous page. When the user returns to the activity, only then can the camera be used properly.
I found a clue to the problem via logcat :
java.lang.IllegalStateException: Method setCurrentState must be called on the main thread
My assumption is that setCurrentState (setupCamera) is not on the main thread, but I have tried various ways to make setupCamera conditional on the main thread.
class KameraActivity : AppCompatActivity() {
private lateinit var classifier: ClassificationFromCamera
private lateinit var binding: ActivityKameraBinding
private val executor = ThreadPoolExecutor(
2,
2,
0L,
TimeUnit.MILLISECONDS,
LinkedBlockingQueue()
)
@SuppressLint("MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityKameraBinding.inflate(layoutInflater)
setContentView(binding.root)
classifier = ClassificationFromCamera(assets)
if (hasCameraPermission()) {
setupCamera()
} else {
requestCameraPermissions()
}
}
private fun requestCameraPermissions() {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
REQUEST_CAMERA_CODE
)
}
@SuppressLint("MissingPermission", "SetTextI18n")
private fun setupCamera() {
binding.camera.addPictureTakenListener { imageData ->
executor.execute {
val recognitions = classifier.recognize(imageData.data)
val txt = recognitions.joinToString(separator = "\n\n\n\n")
runOnUiThread {
binding.tvHasil1.text = txt
}
}
}
binding.capturePhoto.setOnClickListener {
binding.camera.capture()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CAMERA_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setupCamera()
} else {
Toast.makeText(
this,
"Aplikasi perlu izin penggunaan kamera",
Toast.LENGTH_LONG
).show()
requestCameraPermissions()
}
}
}
@SuppressLint("MissingPermission")
override fun onResume() {
super.onResume()
if (hasCameraPermission()) {
binding.camera.start()
}
}
override fun onPause() {
if (hasCameraPermission()) {
binding.camera.stop()
}
super.onPause()
}
override fun onDestroy() {
if (hasCameraPermission()) {
binding.camera.destroy()
}
super.onDestroy()
}
private fun hasCameraPermission() =
ActivityCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
companion object {
private const val REQUEST_CAMERA_CODE = 1
}
}
However, the problem that I got has not been solved. Previously I had tried using Mainscope, Globalscope, and coroutines. Help me solve this problem.
Upvotes: 0
Views: 141
Reputation: 1078
This is probably beacause of a wrong Dispatcher. Try this
@SuppressLint("MissingPermission", "SetTextI18n")
private fun setupCamera() {
binding.camera.addPictureTakenListener { imageData ->
launch(Dispatchers.Main) {
...
}
OR
launch(Dispatchers.Default) {
...
}
}
binding.capturePhoto.setOnClickListener {
binding.camera.capture()
}
}
And since you are using Kotlin, I can assure you can acheive everything (almost) you need using Coroutines!
Upvotes: 0