Android opening a file with ACTION_GET_CONTENT results into different Uri's

前端 未结 4 751
不思量自难忘°
不思量自难忘° 2020-11-30 23:21

I am trying to open files by using Intent.ACTION_GET_CONTENT.

Dependent on the Android version/device brand the file browser opens and I get the follo

4条回答
  •  悲&欢浪女
    2020-11-30 23:27

    The accepted answer on kotlin

    @Suppress("SpellCheckingInspection")
    object PathCompat {
    
        @WorkerThread
        fun getFilePath(context: Context, uri: Uri): String? = context.run {
            return try {
                when {
                    Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT -> getDataColumn(uri, null, null)
                    else -> getPathKitkatPlus(uri)
                }
            } catch (e: Throwable) {
                Timber.e(e)
                null
            }
        }
    
        @Suppress("DEPRECATION")
        @SuppressLint("NewApi", "DefaultLocale")
        private fun Context.getPathKitkatPlus(uri: Uri): String? {
            when {
                DocumentsContract.isDocumentUri(applicationContext, uri) -> {
                    val docId = DocumentsContract.getDocumentId(uri)
                    when {
                        uri.isExternalStorageDocument -> {
                            val parts = docId.split(":")
                            if ("primary".equals(parts[0], true)) {
                                return "${Environment.getExternalStorageDirectory()}/${parts[1]}"
                            }
                        }
                        uri.isDownloadsDocument -> {
                            val contentUri = ContentUris.withAppendedId(
                                Uri.parse("content://downloads/public_downloads"),
                                docId.toLong()
                            )
                            return getDataColumn(contentUri, null, null)
                        }
                        uri.isMediaDocument -> {
                            val parts = docId.split(":")
                            val contentUri = when (parts[0].toLowerCase()) {
                                "image" -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                                "video" -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                                "audio" -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                                else -> return null
                            }
                            return getDataColumn(contentUri, "_id=?", arrayOf(parts[1]))
                        }
                    }
                }
                "content".equals(uri.scheme, true) -> {
                    return if (uri.isGooglePhotosUri) {
                        uri.lastPathSegment
                    } else {
                        getDataColumn(uri, null, null)
                    }
                }
                "file".equals(uri.scheme, true) -> {
                    return uri.path
                }
            }
            return null
        }
    
        private fun Context.getDataColumn(uri: Uri, selection: String?, args: Array?): String? {
            contentResolver?.query(uri, arrayOf("_data"), selection, args, null)?.use {
                if (it.moveToFirst()) {
                    return it.getString(it.getColumnIndexOrThrow("_data"))
                }
            }
            return null
        }
    
        private val Uri.isExternalStorageDocument: Boolean
            get() = authority == "com.android.externalstorage.documents"
    
        private val Uri.isDownloadsDocument: Boolean
            get() = authority == "com.android.providers.downloads.documents"
    
        private val Uri.isMediaDocument: Boolean
            get() = authority == "com.android.providers.media.documents"
    
        private val Uri.isGooglePhotosUri: Boolean
            get() = authority == "com.google.android.apps.photos.content"
    }
    

提交回复
热议问题