Вылетает приложение при очистке словаря
Помогите разобраться, пожалуйста. При очистке словаря "newDictionary" приложение вылетает либо сразу, либо после пару фотографий/загрузок с галереи. Если его не очищать, то всё отлично, но список ListView не чистится и он постоянно мусорится предыдущими значениями с других фото
private val REQUEST_IMAGE_GALLERY = 1
private val REQUEST_IMAGE_CAMERA = 2
private val PERMISSION_REQUEST_CAMERA = 3
private lateinit var imageView: ImageView
private lateinit var btnChoosePhoto: Button
private lateinit var btnTakePhoto: Button
private lateinit var btnRecognize: Button
private lateinit var imageUri: Uri
private lateinit var listView: ListView
val colorsMap: Map<String, String> = mapOf(
"E100" to "GREEN", "E100(i)" to "GREEN", "E100(ii)" to "GREEN", "E101" to "GREEN",
"E106" to "GREEN", "E120" to "GREEN", "E140" to "GREEN"
)
val valuesMap: Map<String, String> = mapOf(
"E100" to "куркумин", "E100(i)" to "куркумин", "E100i" to "куркумин", "Е100(ii)" to "турмерик", "Е100ii" to "турмерик"
)
val newDictionary: MutableMap<String, String> = mutableMapOf()
var array = mutableMapOf<String, String>()
private var recognized = ""
private val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
imageView = findViewById(R.id.image_view)
btnChoosePhoto = findViewById(R.id.btn_choose_photo)
btnTakePhoto = findViewById(R.id.btn_take_photo)
btnRecognize = findViewById(R.id.detect_text_image_btn)
btnChoosePhoto.setOnClickListener {
choosePhotoFromGallery()
}
btnRecognize.setOnClickListener {
}
btnTakePhoto.setOnClickListener {
takePhotoFromCamera()
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// Разрешение не предоставлено, запрашиваем его
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), PERMISSION_REQUEST_CAMERA)
} else {
// Разрешение уже предоставлено, можно использовать камеру
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_CAMERA) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera()
}
}
}
private fun choosePhotoFromGallery() {
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent, REQUEST_IMAGE_GALLERY)
}
private fun takePhotoFromCamera() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), PERMISSION_REQUEST_CAMERA)
} else {
launchCamera()
}
}
private fun launchCamera() {
val imageFile = createImageFile()
imageUri = FileProvider.getUriForFile(this, "com.example.textrecognition.fileprovider", imageFile)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1) // 1 - highest quality
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, "10485760") // Maximum file size (10MB)
intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) // Camera orientation
startActivityForResult(intent, REQUEST_IMAGE_CAMERA)
}
private fun createImageFile(): File {
val imageFileName = "temp_image.jpg"
val storageDir = getExternalFilesDir(null)
return File.createTempFile(imageFileName, null, storageDir)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {
REQUEST_IMAGE_GALLERY -> {
val selectedImageUri = data?.data
imageView.setImageURI(selectedImageUri)
}
REQUEST_IMAGE_CAMERA -> {
imageView.setImageURI(imageUri)
}
}
processImage()
}
}
private fun myDialog(){
val builder = AlertDialog.Builder(this)
builder.setTitle("Нет результатов")
builder.setMessage("Возможно, сканируемый товар не содержит вредных Е-консервантов в составе. Либо " +
"распознать корректно текст не удаётся. "
+"\nЕсли вы уверены, что фото сделано чётко, сфокусировано и без бликов, " +
"то товар безопасен для употребления.")
builder.setPositiveButton("ОК"){DialogInterface, i ->
}
builder.show()
}
private fun processImage() {
array.clear()
val drawable = imageView.drawable
val bitmap = (drawable as? BitmapDrawable)?.bitmap
val textResult = findViewById<TextView>(R.id.text_result)
if (bitmap != null) {
//загрузка
val loading = LoadingDialog(this)
loading.startLoading()
val handler = Handler()
handler.postDelayed(object:Runnable{
override fun run() {
loading.isDismiss()
}
}, 3000)
val image = InputImage.fromBitmap(bitmap, 0)
recognizer.process(image)
.addOnSuccessListener { visionText ->
if (visionText.text == "") {
myDialog()
} else {
textResult.text = "Найденные консерванты:"
listView = findViewById(R.id.listView)
recognized = visionText.text
val pattern = Regex("(E)\\s*(\\d+)")
val matches = pattern.findAll(recognized)
val scannedText = matches.map { it.groupValues[1] + it.groupValues[2] }.toList()
//Log.d("", scannedText.toString())
//Log.d("", recognized)
//заполнили словарь найденными словами
for (text in scannedText) {
newDictionary[text] = "RED"
}
//сравниваем с ешками и закидываем в новый словарь
for((key, value) in newDictionary){
if(colorsMap.containsKey(key)){
array[key] = colorsMap[key]!!
}
}
for ((index, entry) in array.entries.withIndex()) {
val key = entry.key
val value = entry.value
Log.d("Array", "Index: $index, Key: $key, Value: $value")
}
for ((index, entry) in newDictionary.entries.withIndex()) {
val key = entry.key
val value = entry.value
Log.d("Dictionary", "Index: $index, Key: $key, Value: $value")
}
var result = array
.filterKeys {valuesMap.containsKey(it)}
.map { it.key to valuesMap.getValue(it.key) }
.toMap()
val adapter = DictionaryAdapter(result, array)
listView.adapter = adapter
}
}
.addOnFailureListener {
Toast.makeText(this, "Unable to process image", Toast.LENGTH_SHORT).show()
}
} else {
Toast.makeText(this, "Сделайте фото или выберите из галереи!", Toast.LENGTH_SHORT).show()
}
}
private inner class DictionaryAdapter(private val dictionary: Map<String, String>, private val array2: MutableMap<String, String>) : BaseAdapter() {
override fun getCount(): Int {
return dictionary.size
}
override fun getItem(position: Int): Any {
return dictionary.entries.elementAt(position)
}
fun getItem2(position: Int): Any? {
if (position >= 0 && position < array2.entries.size) {
return array2.entries.elementAt(position)
} else {
Log.e("TAG22", "Invalid position: $position")
return null
}
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view = convertView ?: layoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false)
val item = getItem(position) as Map.Entry<String, String>
val item2 = getItem2(position) as Map.Entry<String, String>
val textView = view.findViewById<TextView>(android.R.id.text1)
textView.text = item.key + " - "+ item.value
if (item2.value == "GREEN" && item.key == item2.key) {
textView.setBackgroundColor(Color.rgb(56, 158, 40))
//textView.gravity = Gravity.CENTER
textView.textSize = 15f
textView.setTextColor(Color.BLACK)
} else if (item2.value == "YELLOW" && item.key == item2.key) {
textView.setTextColor(Color.BLACK)
textView.setBackgroundColor(Color.rgb(255, 211, 0))
// textView.gravity = Gravity.CENTER
textView.textSize = 15f
} else if (item2.value == "RED"&& item.key == item2.key){
textView.setTextColor(Color.BLACK)
textView.setBackgroundColor(Color.rgb(186, 47, 57))
// textView.gravity = Gravity.CENTER
textView.textSize = 15f
}
else if (item2.value == "ORANGE" && item.key == item2.key){
textView.setTextColor(Color.BLACK)
textView.setBackgroundColor(Color.rgb( 255, 165, 0))
// textView.gravity = Gravity.CENTER
textView.textSize = 15f
}
view.setOnClickListener {
// Получаем выбранный элемент
val selectedItem = dictionary.entries.elementAt(position)
// Создаем Intent для открытия активности ItemDetailsActivity
val intent = Intent(view.context, activity_detailed::class.java)
// Передаем данные выбранного элемента в Intent
intent.putExtra("key", selectedItem.key)
intent.putExtra("value", selectedItem.value)
// Запускаем активность ItemDetailsActivity
view.context.startActivity(intent)
}
newDictionary.clear()
return view
}
}
}
Источник: Stack Overflow на русском