#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 ...
Вы не отреагировали на это требование.