Android Studio: предоставление доступа URI к адаптеру фрагмента

#android #kotlin #android-fragments

#Android #kotlin #android-фрагменты

Вопрос:

В настоящее время я пытаюсь создать в своем приложении функциональность, в которой пользователь нажимает кнопку, и отображается галерея изображений. Оттуда пользователь выберет изображение, и Uri этого изображения будет использоваться в адаптере фрагмента. Однако всякий раз, когда я пытаюсь получить доступ к изображению через Uri, я получаю эту ошибку>

java.lang.Исключение SecurityException: отказ в разрешении: открытие провайдера com.android.providers.media.MediaDocumentsProvider … требуется, чтобы вы получили доступ с помощью ACTION_OPEN_DOCUMENT или связанных API

Я извлекаю Uri из фрагмента, а затем передаю его адаптеру. tldr: я хотел бы иметь возможность использовать Uri во всех фрагментах и адаптерах моего приложения, не беспокоясь об исключениях безопасности. Приведенный ниже сокращенный код. Спасибо!

Первый фрагмент

 open class FirstFragment() : Fragment(), FirstFragmentAdapter.Acess2, FirstFragmentAdapter.ListItemCLicked {
    private lateinit var firstFragmentRecyclerView: RecyclerView
    private lateinit var listDataManager: dataManager
    private var arr: ArrayList<String> = arrayListOf<String>()
    companion object{
        const val REQUEST_MEDIA = 101
    }
    var imageURI: Uri? = null
    var uri: String = " "


    private var viewDataList = ArrayList<viewData>()


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        activity?.let {
            listDataManager = ViewModelProvider(this).get(dataManager::class.java)
        }



        viewDataList = listDataManager.readData()
        firstFragmentRecyclerView = view.findViewById<RecyclerView>(R.id.test_recycler)
        firstFragmentRecyclerView.layoutManager = LinearLayoutManager(activity)
        firstFragmentRecyclerView.adapter = FirstFragmentAdapter(viewDataList, this)

        val fab = view.findViewById<FloatingActionButton>(R.id.fababc)
        fab.setOnClickListener {
            showCreateTodoList()
            Log.d("TEST2", "RECIEVING INPUT")

        }
    }

    private fun addToList(viewData: viewData) {
        viewDataList.add(viewData)
        listDataManager.saveData(viewDataList)


        val FirstFragmentAdapter = firstFragmentRecyclerView.adapter as FirstFragmentAdapter
        FirstFragmentAdapter.addList()


    }

    private fun showCreateTodoList() {
        openGallery()

    }


   
    @SuppressLint("InlinedApi")
    private fun openGallery() {
        val gallery = Intent(Intent.ACTION_OPEN_DOCUMENT, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
        gallery.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
        startActivityForResult(gallery, REQUEST_MEDIA)
    }
    @SuppressLint("NewApi")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)   {
        super.onActivityResult(requestCode, resultCode, data)
        if(resultCode == AppCompatActivity.RESULT_OK amp;amp; requestCode == REQUEST_MEDIA){
            Log.d("TESTING", "THIS CODE RUNS")
            imageURI = data!!.data



            activity?.let {
                val dialogTitle = getString(R.string.newScp)
                val positiveButtonTitle = getString(R.string.create)
                val myDialog = AlertDialog.Builder(it)
                val todoTitleEditText = EditText(it)
                todoTitleEditText.inputType =
                        InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_WORDS
                myDialog.setTitle(dialogTitle)
                myDialog.setView(todoTitleEditText)
                myDialog.setPositiveButton(positiveButtonTitle) { dialog, _ ->

                    uri = imageURI.toString()

                    if(uri.contains("com")){
                        arr.add(0, uri)
                        Log.d("DATA", arr.toString())
                    }


                    val list = viewData(todoTitleEditText.text.toString(), arr[0], 0, "SCP Name: ", "SCP Class", "Date Discovered: ", "Kill Count:")
                    addToList(list)
                    dialog.dismiss()
                    ListItemCLickedu(list)

                }
                myDialog.create().show()
            }




        }
        else{  Log.d("TESTING2", "THIS CODE DOES NOT RUN!")


        }
    }
}
 

FragmentAdapter

 class FirstFragmentAdapter(private val list: ArrayList<viewData>, val clickListener: ListItemCLicked): RecyclerView.Adapter<FirstFragmentViewHolder>() {

    interface Acess2{ }


    interface ListItemCLicked{
        fun ListItemCLicked(data: viewData)
    }


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

    }

     @SuppressLint("SetTextI18n")
     override fun onBindViewHolder(holder: FirstFragmentViewHolder, position : Int ) {
        var position2 = position
        holder.testTextView!!.text = "SCP: ${list[position].name}"

         if(position2 > list.size-1) {
            position2 = 0

         }

            if (list[position].image.contains("com")) {
                holder.testImageView?.setImageURI(Uri.parse(list[position].image))
            }
       //  Log.d("ADAPTER_TESTING", list[position].image)
         Log.d("ADAPTER_TESTER2", list[position].toString())

         holder.itemView.setOnClickListener{

             clickListener.ListItemCLicked(list[position])



         }



    }
 

Комментарии:

1. «Однако всякий раз, когда я пытаюсь получить доступ к изображению через Uri, я получаю эту ошибку» — следствием этой ошибки является то, что вы передаете действия Uri between тем или иным способом. Подробнее см. В этом сообщении в блоге .

2. requires that you obtain access using ACTION_OPEN_DOCUMENT or ... Вы не отреагировали на это требование.