As startActivityForResult
has been deprecated, I would rather don't use it for getting the absolute path of the selected image from the gallery.
Therefor I have tried without it as the code below, however it doesn't work. What am I doing wrong?
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@ id/img_camera"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
android:src="@drawable/camera"/>
<TextView
android:id="@ id/txt_path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Path"
android:layout_marginTop="30dp"/>
</LinearLayout>
MainAcitivty.kt
package com.gearsrun.choosephotoapplication
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.graphics.drawable.toBitmap
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.gearsrun.choosephotoapplication.databinding.ActivityMainBinding
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.*
class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
private var mImagePath = ""
private lateinit var activityResultLauncher:ActivityResultLauncher<Intent>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val getImage = registerForActivityResult(
ActivityResultContracts.GetContent(),
ActivityResultCallback {
Glide.with(this)
.load(it)
.centerCrop()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.listener(object : RequestListener<Drawable>{
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
Log.e("TAG", "Error loading image", e)
return false // important to return false so the error placeholder can be placed
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
val bitmap: Bitmap = (resource?.toBitmap() ?: null) as Bitmap
mImagePath = saveImageToInternalStorage(bitmap)
binding.txtPath.text = mImagePath
return false
}
})
}
)
binding.imgCamera.setOnClickListener {
getImage.launch("image/*")
}
}
private fun saveImageToInternalStorage(bitmap: Bitmap): String {
val wrapper = ContextWrapper(applicationContext)
var file = wrapper.getDir(IMAGE_DIRECTORY, Context.MODE_PRIVATE)
file = File(file,"${UUID.randomUUID()}.jpg")
try{
val stream :OutputStream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream)
stream.flush()
stream.close()
}catch (e:IOException){
e.printStackTrace()
}
return file.absolutePath
}
companion object {
private const val IMAGE_DIRECTORY = "GearsRunImages"
}
}
CodePudding user response:
I believe the issue occurred in the implementation of Glide
.
Glide was used to load an image, Im assuming the imgCamera
was used to preview the loaded image. Therefore, need to add into(binding.imgCamera)
in your Glide
implementation.
So, after the image loaded, the onResourceReady()
will triggered and your logic may run there.
I think, update getImage
like in the following code may works
val getImage = registerForActivityResult(
ActivityResultContracts.GetContent(),
ActivityResultCallback {
Glide.with(this)
.load(it)
.centerCrop()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.listener(object : RequestListener<Drawable>{
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
Log.e("TAG", "Error loading image", e)
return false // important to return false so the error placeholder can be placed
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
val bitmap: Bitmap = (resource?.toBitmap() ?: null) as Bitmap
mImagePath = saveImageToInternalStorage(bitmap)
binding.txtPath.text = mImagePath
return false
}
})
.into(binding.imgCamera)
}
)