首页 > 解决方案 > 在不使用 startActivityForResult 从图库中选择图像时,如何获得真实路径?

问题描述

正如startActivityForResult已被弃用的那样,我宁愿不使用它来从图库中获取所选图像的绝对路径。

因此,我已经尝试不使用它作为下面的代码,但是它不起作用。我究竟做错了什么?

在此处输入图像描述

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>

主要活动.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"
    }
}

标签: androidkotlin

解决方案


我相信问题发生在Glide.

Glide 用于加载图像,我假设imgCamera用于预览加载的图像。因此,需要into(binding.imgCamera)在您的Glide实现中添加。

因此,在加载图像后,onResourceReady()将触发并且您的逻辑可能会在那里运行。

我认为,getImage如下代码中的更新可能有效

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)
            }
        )

推荐阅读