Android: Android 15 URI fixes

This commit is contained in:
Jarrod Norwell 2024-09-15 14:46:43 -06:00 committed by OpenSauce04
parent 73774333da
commit 620abbc8dd
5 changed files with 40 additions and 29 deletions

View File

@ -160,6 +160,7 @@ android {
jniLibs.srcDir(downloadedJniLibsPath) jniLibs.srcDir(downloadedJniLibsPath)
} }
} }
buildToolsVersion = "35.0.0"
} }
dependencies { dependencies {

View File

@ -5,6 +5,7 @@
package io.github.lime3ds.android.fragments package io.github.lime3ds.android.fragments
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -159,7 +160,7 @@ class HomeSettingsFragment : Fragment() {
R.string.select_lime3ds_user_folder, R.string.select_lime3ds_user_folder,
R.string.select_lime3ds_user_folder_home_description, R.string.select_lime3ds_user_folder_home_description,
R.drawable.ic_home, R.drawable.ic_home,
{ mainActivity?.openLime3DSDirectory?.launch(null) }, { mainActivity?.openLime3DSDirectory?.launch(Uri.parse(null)) },
details = homeViewModel.userDir details = homeViewModel.userDir
), ),
HomeSetting( HomeSetting(

View File

@ -60,7 +60,7 @@ class Lime3DSDirectoryDialogFragment : DialogFragment() {
} }
.setNegativeButton(android.R.string.cancel) { _: DialogInterface?, _: Int -> .setNegativeButton(android.R.string.cancel) { _: DialogInterface?, _: Int ->
if (!PermissionsHandler.hasWriteAccess(requireContext())) { if (!PermissionsHandler.hasWriteAccess(requireContext())) {
(requireActivity() as MainActivity)?.openLime3DSDirectory?.launch(null) (requireActivity() as MainActivity)?.openLime3DSDirectory?.launch(Uri.parse(null))
} }
} }
.show() .show()

View File

@ -6,6 +6,7 @@ package io.github.lime3ds.android.fragments
import android.app.Dialog import android.app.Dialog
import android.content.DialogInterface import android.content.DialogInterface
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
@ -26,7 +27,7 @@ class SelectUserDirectoryDialogFragment : DialogFragment() {
.setTitle(R.string.select_lime3ds_user_folder) .setTitle(R.string.select_lime3ds_user_folder)
.setMessage(R.string.cannot_skip_directory_description) .setMessage(R.string.cannot_skip_directory_description)
.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int -> .setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int ->
mainActivity?.openLime3DSDirectory?.launch(null) mainActivity?.openLime3DSDirectory?.launch(Uri.parse(null))
} }
.show() .show()
} }

View File

@ -1,4 +1,4 @@
// Copyright 2023 Citra Emulator Project // Copyright Citra Emulator Project / Lime3DS Emulator Project
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
@ -16,6 +16,7 @@ import io.github.lime3ds.android.LimeApplication
import io.github.lime3ds.android.model.CheapDocument import io.github.lime3ds.android.model.CheapDocument
import java.io.BufferedInputStream import java.io.BufferedInputStream
import java.io.File import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
@ -100,18 +101,21 @@ object FileUtil {
@JvmStatic @JvmStatic
fun openContentUri(path: String, openMode: String): Int { fun openContentUri(path: String, openMode: String): Int {
try { try {
context val uri = Uri.parse(path)
.contentResolver context.contentResolver.openFileDescriptor(uri, openMode)?.use { parcelFileDescriptor ->
.openFileDescriptor(Uri.parse(path), openMode) return parcelFileDescriptor.detachFd()
.use { parcelFileDescriptor -> } ?: run {
if (parcelFileDescriptor == null) { Log.error("[FileUtil]: Cannot get the file descriptor from uri: $path")
Log.error("[FileUtil]: Cannot get the file descriptor from uri: $path") return -1
return -1 }
} } catch (e: FileNotFoundException) {
return parcelFileDescriptor.detachFd() Log.error("[FileUtil]: File not found for uri: $path. ${e.message}")
} return -1
} catch (e: SecurityException) {
Log.error("[FileUtil]: Security exception while accessing uri: $path, ${e.message}")
return -1
} catch (e: Exception) { } catch (e: Exception) {
Log.error("[FileUtil]: Cannot open content uri, error: " + e.message) Log.error("[FileUtil]: Unexpected error while opening content uri: $path. ${e.message}")
return -1 return -1
} }
} }
@ -130,8 +134,9 @@ object FileUtil {
DocumentsContract.Document.COLUMN_DISPLAY_NAME, DocumentsContract.Document.COLUMN_DISPLAY_NAME,
DocumentsContract.Document.COLUMN_MIME_TYPE DocumentsContract.Document.COLUMN_MIME_TYPE
) )
var c: Cursor? = null var cursor: Cursor? = null
val results: MutableList<CheapDocument> = ArrayList() val results = mutableListOf<CheapDocument>()
try { try {
val docId = if (isRootTreeUri(uri)) { val docId = if (isRootTreeUri(uri)) {
DocumentsContract.getTreeDocumentId(uri) DocumentsContract.getTreeDocumentId(uri)
@ -140,21 +145,24 @@ object FileUtil {
} }
val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, docId) val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, docId)
c = context.contentResolver.query(childrenUri, columns, null, null, null) cursor = context.contentResolver.query(childrenUri, columns, null, null, null)
while (c!!.moveToNext()) {
val documentId = c.getString(0) cursor?.use { c ->
val documentName = c.getString(1) while (c.moveToNext()) {
val documentMimeType = c.getString(2) val documentId = c.getString(c.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_DOCUMENT_ID))
val documentUri = DocumentsContract.buildDocumentUriUsingTree(uri, documentId) val documentName = c.getString(c.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_DISPLAY_NAME))
val document = CheapDocument(documentName, documentMimeType, documentUri) val documentMimeType = c.getString(c.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_MIME_TYPE))
results.add(document) val documentUri = DocumentsContract.buildDocumentUriUsingTree(uri, documentId)
val document = CheapDocument(documentName, documentMimeType, documentUri)
results.add(document)
}
} ?: run {
Log.error("[FileUtil]: Cursor is null")
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.error("[FileUtil]: Cannot list file error: " + e.message) Log.error("[FileUtil]: Cannot list files: ${e.message}")
} finally {
closeQuietly(c)
} }
return results.toTypedArray<CheapDocument>() return results.toTypedArray()
} }
/** /**