Android Studio: Granting URI Acess to Fragment Adapter

Viewed 69

I am currently attempting to create a functionality in my app where a user will press a button and the image gallery will show up. From there the user will select an image and that image Uri will be used in the fragment's adapter. However, whenever I attempt to access the image via the Uri I get this error >

java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider ... requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

I am retrieving the Uri in the fragment and then passing it to the adapter. tldr: I would like to be able to use the Uri all through out my app's fragments and adapters without worrying about security exceptions. Abridged code below. Thanks!

First Fragment

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 && 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])



         }



    }
0 Answers
Related