使用 Glide 加载图像 - 拒绝访问外部存储

问题描述 投票:0回答:1

我正在使用 kotlin 构建一个 Android 应用程序,并使用 Glide 加载图像。

它适用于一个片段,但不适用于另一个片段,我不明白为什么我无法获得权限?!

图像存储在房间数据库内。

我已经检查了我的日志消息和图像-uri(内容),并且两个片段中的上下文是相同的,但一个获得了许可,而另一个则没有......

这是我收到的错误消息

2025-01-06 20:55:51.266  7954-7954  Glide                   com.example.travelfriends            D  Loading image from URI: content://media/external/images/media/1000000032
2025-01-06 20:55:51.266  7954-7954  Glide                   com.example.travelfriends            D  Context available: com.example.travelfriends.ui.MainActivity@9085568
2025-01-06 20:55:51.312  7954-7999  GlideExecutor           com.example.travelfriends            E  Request threw uncaught throwable
                                                                                                    java.lang.SecurityException: com.example.travelfriends has no access to content://media/external/images/media/1000000032

清单.xml

<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

glide 起作用的片段

package com.example.travelfriends.data

import android.net.Uri
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.travelfriends.R

class BookAdapter(
    private val books: List<Book>,
    private val onBookClick: (Book) -> Unit
) : RecyclerView.Adapter<BookAdapter.BookViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_book, parent, false)
        return BookViewHolder(view)
    }

    override fun onBindViewHolder(holder: BookViewHolder, position: Int) {
        val book = books[position]
        holder.bookTitle.text = book.name
        holder.bookDescription.text = book.description

        Log.d("Glide", "Context available: ${holder.itemView.context}")
        Log.d("Glide", "Loading image from URI: ${book.image}")
        
        // Verwende Glide, um das Bild zu laden
        Glide.with(holder.itemView.context)
            .load(Uri.parse(book.image)) 
            .placeholder(R.drawable.ic_launcher_foreground) 
            .error(R.drawable.ic_launcher_foreground) 
            .into(holder.bookImage)

        holder.itemView.setOnClickListener {
            onBookClick(book) 
        }
    }

    override fun getItemCount(): Int {
        return books.size
    }

    // ViewHolder für jedes Buch
    class BookViewHolder(view: android.view.View) : RecyclerView.ViewHolder(view) {
        val bookTitle: TextView = view.findViewById(R.id.tvRecViewBookTitle)
        val bookDescription: TextView = view.findViewById(R.id.tvRecViewBookDescription)
        val bookImage: ImageView = view.findViewById(R.id.ivRecViewBookImage)
    }

}

Glide 不起作用的片段

package com.example.travelfriends.ui.fragments

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.bumptech.glide.Glide
import com.example.travelfriends.R
import com.example.travelfriends.data.AppViewModel
import com.example.travelfriends.data.Entry

class BookDisplayFragment : Fragment() {

    private lateinit var ivBookImage: ImageView
    private lateinit var tvBookTitle: TextView
    private lateinit var appViewModel: AppViewModel
    private var bookId: Int = -1

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_book_display, container, false)

        ivBookImage = view.findViewById(R.id.bookImage)
        tvBookTitle = view.findViewById(R.id.bookTitle)
        val btnNextEntry: Button = view.findViewById(R.id.nextEntryButton)

        appViewModel = ViewModelProvider(requireActivity())[AppViewModel::class.java]

        // Abrufen der übergebenen Argumente
        arguments?.let {
            bookId = it.getInt("bookId", -1)  
        }

        if (bookId != -1) {
            appViewModel.getBookById(bookId)
            observeBookData()
        }

        return view
    }

    private fun observeBookData() {
        appViewModel.allBooks.observe(viewLifecycleOwner, Observer { books ->
            if (books.isNotEmpty()) {
                val book = books[0]
                tvBookTitle.text = book.name
                
                Log.d("Glide", "Loading image from URI: ${book.image}")
                Log.d("Glide", "Context available: ${requireContext()}")

                    Glide.with(requireContext())
                        .load(book.image)
                        .placeholder(R.drawable.ic_launcher_foreground)
                        .error(R.drawable.ic_launcher_foreground)
                        .into(ivBookImage)
            }
        })
    }
}

我试图理解为什么这个片段没有加载图像的权限,但另一个片段有...... 但我找不到答案,日志消息也没有帮助我。

我是一名学生,不是最有经验的程序员,所以请保持友善。

谢谢!

android image kotlin android-glide
1个回答
0
投票

我认为问题出在生命周期状态或上下文中。

尝试将您的 Glide 放入

onResume
。或者再加一个条件:

if (!book.image.isNullOrEmpty()) {
    Glide.with(requireContext())
        .load(book.image)
        .placeholder(R.drawable.ic_launcher_foreground)
        .error(R.drawable.ic_launcher_foreground)
        .into(ivBookImage)
} else {
    Log.d("Glide", "Invalid image URI: ${book.image}")
}

您也可以尝试在观察者中添加检查

private fun observeBookData() {
    appViewModel.allBooks.observe(viewLifecycleOwner, Observer { books ->
        if (books.isNotEmpty()) {
            val book = books[0]
            tvBookTitle.text = book.name

            Log.d("Glide", "Loading image from URI: ${book.image}")
            Log.d("Glide", "Context available: ${requireContext()}")

            if (isAdded && !book.image.isNullOrEmpty()) {
                Glide.with(requireContext())
                    .load(book.image)
                    .placeholder(R.drawable.ic_launcher_foreground)
                    .error(R.drawable.ic_launcher_foreground)
                    .into(ivBookImage)
            } else {
                Log.d("Glide", "Fragment not attached or invalid image URI")
            }
        }
    })
}
© www.soinside.com 2019 - 2024. All rights reserved.