I've got an activity which uses camera intent. If I take a picture vertically and accept to display it in an imageview vertically there is no problem. If i take a picture horizontally and accept it while having the mobile horizontally it crashes, but if I turn it to vertical it works. Does anybody know why this might be happening? It does not have much sense cause when the app crashes the only thing it says is that the photoFile is null, it seems as if there was no picture but in fact there is a picture. Here is the code from the activity:
private const val FILE_NAME = "photo.jpg"
class TextCameraActivity : AppCompatActivity(), TextToSpeech.OnInitListener {
private lateinit var binding: ActivityTextCameraBinding
private lateinit var bitmap : Bitmap
private lateinit var photoFile: File
private var tts: TextToSpeech? = null
private var locale : Locale = Locale("es", "ES")
private var progressBar : ProgressBar? = null
private var i = 0
private val handler = Handler()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTextCameraBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btn7.setOnClickListener {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
photoFile = getPhotoFile(FILE_NAME)
val fileProvider = FileProvider.getUriForFile(this, "com.example.fileprovider", photoFile)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider)
if(takePictureIntent.resolveActivity(this.packageManager) != null) {
startActivityForResult(takePictureIntent, 42)
} else {
Toast.makeText(this, "Unable to open camera", Toast.LENGTH_SHORT).show()
Log.d("mensaje", "?????Unable to open camera")
}
}
tts = TextToSpeech(this, this)
progressBar = binding.progressBar
binding.btnReconocerImagen.setOnClickListener {
progressBar!!.visibility = View.VISIBLE
i = progressBar!!.progress
Thread(Runnable {
while (i < 10) {
i += 1
handler.post(Runnable {
progressBar!!.progress = i
})
try {
Thread.sleep(100)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
progressBar!!.visibility = View.INVISIBLE
}).start()
recognizeText()
}
val actionBar = supportActionBar
actionBar?.setDisplayHomeAsUpEnabled(true)
}
private fun getPhotoFile(fileName:String):File {
val storageDirectory = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(fileName, ".jpg", storageDirectory)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.getItemId()) {
android.R.id.home -> {
finish()
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
return true
}
override fun onInit(status: Int) {
if (status == TextToSpeech.SUCCESS) {
// set US English as language for tts
val result = tts!!.setLanguage(locale)
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS","The Language specified is not supported!")
} else {
binding.btnReconocerImagen.isEnabled = true
}
} else {
Log.e("TTS", "Initilization Failed!")
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(requestCode == 42 && resultCode == Activity.RESULT_OK) {
bitmap = BitmapFactory.decodeFile(photoFile.absolutePath)
binding.imageView.setImageBitmap(bitmap)
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
private fun recognizeText() {
try {
val image = InputImage.fromBitmap(bitmap, 0)
val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
val result = recognizer.process(image)
.addOnSuccessListener { visionText ->
for (block in visionText.textBlocks) {
val boundingBox = block.boundingBox
val cornerPoints = block.cornerPoints
val text = block.text
Log.d("mensaje", "he encontrado $text")
binding.tvTextoReconocido.text = "El texto reconocido es: $text"
tts!!.speak("El texto reconocido es $text", TextToSpeech.QUEUE_FLUSH, null, "")
for (line in block.lines) {
// ...
for (element in line.elements) {
// ...
}
}
}
}
.addOnFailureListener { e ->
}
} catch (e : Exception) {
Log.d("mensaje", "NO HAY IMAGEN SELECCIONADA")
Toast.makeText(this,"NO HAS SELECCIONADO NINGUNA IMAGEN PARA RECONOCER", Toast.LENGTH_SHORT).show()
}
}
}
Error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.appdigitalinkrecognition, PID: 30407
java.lang.RuntimeException: Unable to resume activity {com.example.appdigitalinkrecognition/com.example.appdigitalinkrecognition.TextCameraActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=42, result=-1, data=null} to activity {com.example.appdigitalinkrecognition/com.example.appdigitalinkrecognition.TextCameraActivity}: kotlin.UninitializedPropertyAccessException: lateinit property photoFile has not been initialized
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4918)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4955)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8653)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=42, result=-1, data=null} to activity {com.example.appdigitalinkrecognition/com.example.appdigitalinkrecognition.TextCameraActivity}: kotlin.UninitializedPropertyAccessException: lateinit property photoFile has not been initialized
at android.app.ActivityThread.deliverResults(ActivityThread.java:5590)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4905)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4955)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8653)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property photoFile has not been initialized
at com.example.appdigitalinkrecognition.TextCameraActivity.onActivityResult(TextCameraActivity.kt:143)
at android.app.Activity.dispatchActivityResult(Activity.java:8550)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5583)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4905)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4955)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8653)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
````
Declaring photoFile
as optional should solve the problem:
private var photoFile: File? = null
You will need to add a null-check in your onActivityResult
:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(requestCode == 42 && resultCode == Activity.RESULT_OK) {
photoFile?.let { photo ->
bitmap = BitmapFactory.decodeFile(photo.absolutePath)
binding.imageView.setImageBitmap(bitmap)
} ?: run {
// Photo is not defined...
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}