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