0

I have a server, in which I should download a file in BASE64 (don't ask why I have this). And now I'm working on a pdf uploading. Currently, I'm trying to get a file path from a device and than parse it to base64. And its works, but its doen't work when I'm trying to get file not from a device (for example, Google Photo). What is the best way to do it?

@SuppressLint("NewApi")
@Throws(URISyntaxException::class)
fun getFilePath(context: Context, uri: Uri): String? {
    var uri = uri
    var selection: String? = null
    var selectionArgs: Array<String>? = null
    // Uri is different in versions after KITKAT (Android 4.4), we need to
    if (Build.VERSION.SDK_INT < 28 && DocumentsContract.isDocumentUri(context.applicationContext, uri)) {
        if (isExternalStorageDocument(uri)) {
            val docId = DocumentsContract.getDocumentId(uri)
            val split =
                docId.split(":".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
            return Environment.getExternalStorageDirectory().path + "/" + split[1]
        } else if (isDownloadsDocument(uri)) {
            val id = DocumentsContract.getDocumentId(uri)
            uri = ContentUris.withAppendedId(
                Uri.parse("content://downloads/public_downloads"),
                java.lang.Long.valueOf(id)
            )
        } else if (isMediaDocument(uri)) {
            val docId = DocumentsContract.getDocumentId(uri)
            val split =
                docId.split(":".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
            val type = split[0]
            if ("image" == type) {
                uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
            } else if ("video" == type) {
                uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
            } else if ("audio" == type) {
                uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
            }
            selection = "_id=?"
            selectionArgs = arrayOf(split[1])
        } else if (isGooglePhotosUri(uri)) {

        }
    } else if (Build.VERSION.SDK_INT >= 28) {
        return uri.path.split(":")[1]
    }
    if ("content".equals(uri.getScheme(), ignoreCase = true)) {
        val projection = arrayOf<String>(MediaStore.Images.Media.DATA)
        var cursor: Cursor? = null
        try {
            cursor = context.contentResolver
                .query(uri, projection, selection, selectionArgs, null)
            val column_index = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
            if (cursor!!.moveToFirst()) {
                return cursor!!.getString(column_index)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    } else if ("file".equals(uri.getScheme(), ignoreCase = true)) {
        return uri.getPath()
    }
    return null
}

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

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

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

fun isGooglePhotosUri(uri: Uri): Boolean {
    return uri.authority.contains("com.google.android.apps")
}
Hitrene
  • 331
  • 1
  • 4
  • 18
  • 2
    you have input `Uri` - use it for reading the content - for more see `ContentResolver` official documentation – pskink Sep 14 '19 at 10:42
  • Thanks. It helped. And how I can get a name of this file (I mean real name, not a "document/99")? – Hitrene Sep 14 '19 at 10:54
  • you cannot get a `File` - all you can get its `InputStream` for content reading – pskink Sep 14 '19 at 10:57
  • 1
    You are welcome to try `DocumentFile.fromSingleUri()`, then call `getName()` on the resulting `DocumentFile`. This may or may not work, depending on how you are getting the `Uri`. – CommonsWare Sep 14 '19 at 11:07

0 Answers0