rokkonet

PC・Androidソフトウェア・アプリの開発・使い方に関するメモ

android開発 URIからファイルシステム上のパスを取得する

2022 May 02.
2021 Sep. 12.

出典 Invalid URI at getting path in different android api - Stack Overflow

端末

Android 11 (API レベル 30)

概要

ContentResolverにて、collectionにuriを、projectionに"_data"をセットしqueryする

サンプルkotlinコード
// get filepath of myUri
val proj = arrayOf("_data")
val cursor = this.getContentResolver().query(myUri, proj, null, null, null)
if (cursor == null) {
    findViewById<TextView>(R.id.textViewFilePath).text = "Could not find."
} else {
    val pathColumn = cursor.getColumnIndexOrThrow("_data")
    cursor.moveToFirst()
    findViewById<TextView>(R.id.textViewFilePath).text = cursor.getString(pathColumn)
    cursor.close()
}



(参考)
出典 Android: Files: Unable to get file path from content URI when file is selected from RECENT section in file browser - Stack Overflow

    fun getPathFromUri(context: Context, uri: Uri): String? {
        // DocumentProvider
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(
                context,
                uri
            )
        ) {
            if (isExternalStorageDocument(uri)) {
                val docId = DocumentsContract.getDocumentId(uri)
                val split = docId.split(":").toTypedArray()
                val type = split[0]
                return Environment.getExternalStorageDirectory().toString() + "/" + split[1]

                // TODO handle non-primary volumes
            } else if (isDownloadsDocument(uri)) {
                try {
                    val id = DocumentsContract.getDocumentId(uri)
                    //Log.d(TAG, "getPath: id= " + id);
                    val contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        java.lang.Long.valueOf(id)
                    )
                    return getDataColumn(context, contentUri, null, null)
                } catch (e: Exception) {
                    e.printStackTrace()
                    val segments = uri.pathSegments
                    if (segments.size > 1) {
                        val rawPath = segments[1]
                        return if (!rawPath.startsWith("/")) {
                            rawPath.substring(rawPath.indexOf("/"))
                        } else {
                            rawPath
                        }
                    }
                }
            } else if (isMediaDocument(uri)) {
                val docId = DocumentsContract.getDocumentId(uri)
                val split = docId.split(":").toTypedArray()
                val type = split[0]
                var contentUri: Uri? = null
                if ("image" == type) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                } else if ("video" == type) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                } else if ("audio" == type) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                }
                val selection = "_id=?"
                val selectionArgs = arrayOf(
                    split[1]
                )
                return getDataColumn(context, contentUri, selection, selectionArgs)
            }
        } else if ("content".equals(uri.scheme, ignoreCase = true)) {

            // Return the remote address
            return if (isGooglePhotosUri(uri)) uri.lastPathSegment else getDataColumn(
                context,
                uri,
                null,
                null
            )
        } else if ("file".equals(uri.scheme, ignoreCase = true)) {
            return uri.path
        }
        return null
    }

    fun getDataColumn(
        context: Context, uri: Uri?, selection: String?,
        selectionArgs: Array<String>?
    ): String? {
        var cursor: Cursor? = null
        val column = "_data"
        val projection = arrayOf(
            column
        )
        try {
            cursor = context.contentResolver.query(
                uri!!, projection, selection, selectionArgs,
                null
            )
            if (cursor != null && cursor.moveToFirst()) {
                val column_index = cursor.getColumnIndexOrThrow(column)
                return cursor.getString(column_index)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            cursor?.close()
        }
        return "nodata"
    }

    fun isExternalStorageDocument(uri: Uri): Boolean {
        return "com.android.externalstorage.documents" == uri.authority
    }

    fun isDownloadsDocument(uri: Uri): Boolean {
        return "com.android.providers.downloads.documents" == uri.authority
    }

    fun isMediaDocument(uri: Uri): Boolean {
        return "com.android.providers.media.documents" == uri.authority
    }

    fun isGooglePhotosUri(uri: Uri): Boolean {
        return "com.google.android.apps.photos.content" == uri.authority
    }