parent
							
								
									440ad903d8
								
							
						
					
					
						commit
						75c99dbe7d
					
				@ -0,0 +1,173 @@ | 
				
			|||||||
 | 
					package io.legado.app.utils | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.annotation.SuppressLint | 
				
			||||||
 | 
					import android.content.ContentUris | 
				
			||||||
 | 
					import android.content.Context | 
				
			||||||
 | 
					import android.database.Cursor | 
				
			||||||
 | 
					import android.net.Uri | 
				
			||||||
 | 
					import android.os.Build | 
				
			||||||
 | 
					import android.os.Environment | 
				
			||||||
 | 
					import android.provider.DocumentsContract | 
				
			||||||
 | 
					import android.provider.MediaStore | 
				
			||||||
 | 
					import java.io.File | 
				
			||||||
 | 
					import java.io.FileInputStream | 
				
			||||||
 | 
					import java.io.FileOutputStream | 
				
			||||||
 | 
					import java.io.IOException | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Suppress("unused") | 
				
			||||||
 | 
					object RealPathUtil { | 
				
			||||||
 | 
					    /** | 
				
			||||||
 | 
					     * Method for return file path of Gallery image | 
				
			||||||
 | 
					     * @return path of the selected image file from gallery | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    private var filePathUri: Uri? = null | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Suppress("DEPRECATION") | 
				
			||||||
 | 
					    fun getPath( | 
				
			||||||
 | 
					        context: Context, | 
				
			||||||
 | 
					        uri: Uri | 
				
			||||||
 | 
					    ): String? { | 
				
			||||||
 | 
					        //check here to KITKAT or new version | 
				
			||||||
 | 
					        @SuppressLint("ObsoleteSdkInt") | 
				
			||||||
 | 
					        val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT | 
				
			||||||
 | 
					        filePathUri = uri | 
				
			||||||
 | 
					        // DocumentProvider | 
				
			||||||
 | 
					        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider | 
				
			||||||
 | 
					            if (isExternalStorageDocument(uri)) { | 
				
			||||||
 | 
					                val docId = DocumentsContract.getDocumentId(uri) | 
				
			||||||
 | 
					                val split = docId.split(":").toTypedArray() | 
				
			||||||
 | 
					                val type = split[0] | 
				
			||||||
 | 
					                if ("primary".equals(type, ignoreCase = true)) { | 
				
			||||||
 | 
					                    return Environment.getExternalStorageDirectory().toString() + "/" + split[1] | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } else if (isDownloadsDocument(uri)) { | 
				
			||||||
 | 
					                val id = DocumentsContract.getDocumentId(uri) | 
				
			||||||
 | 
					                val contentUri = ContentUris.withAppendedId( | 
				
			||||||
 | 
					                    Uri.parse("content://downloads/public_downloads"), | 
				
			||||||
 | 
					                    java.lang.Long.valueOf(id) | 
				
			||||||
 | 
					                ) | 
				
			||||||
 | 
					                //return getDataColumn(context, uri, null, null); | 
				
			||||||
 | 
					                return getDataColumn(context, contentUri, null, null) | 
				
			||||||
 | 
					            } 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 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** | 
				
			||||||
 | 
					     * Get the value of the data column for this Uri. This is useful for | 
				
			||||||
 | 
					     * MediaStore Uris, and other file-based ContentProviders. | 
				
			||||||
 | 
					     * | 
				
			||||||
 | 
					     * @param context The context. | 
				
			||||||
 | 
					     * @param uri The Uri to query. | 
				
			||||||
 | 
					     * @param selection (Optional) Filter used in the query. | 
				
			||||||
 | 
					     * @param selectionArgs (Optional) Selection arguments used in the query. | 
				
			||||||
 | 
					     * @return The value of the _data column, which is typically a file path. | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    private fun getDataColumn( | 
				
			||||||
 | 
					        context: Context, uri: Uri?, selection: String?, | 
				
			||||||
 | 
					        selectionArgs: Array<String>? | 
				
			||||||
 | 
					    ): String? { | 
				
			||||||
 | 
					        var cursor: Cursor? = null | 
				
			||||||
 | 
					        val column = "_data" | 
				
			||||||
 | 
					        val projection = arrayOf( | 
				
			||||||
 | 
					            column | 
				
			||||||
 | 
					        ) | 
				
			||||||
 | 
					        var input: FileInputStream? = null | 
				
			||||||
 | 
					        var output: FileOutputStream? = null | 
				
			||||||
 | 
					        try { | 
				
			||||||
 | 
					            cursor = | 
				
			||||||
 | 
					                context.contentResolver.query(uri!!, projection, selection, selectionArgs, null) | 
				
			||||||
 | 
					            if (cursor != null && cursor.moveToFirst()) { | 
				
			||||||
 | 
					                val index = cursor.getColumnIndexOrThrow(column) | 
				
			||||||
 | 
					                return cursor.getString(index) | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } catch (e: IllegalArgumentException) { | 
				
			||||||
 | 
					            e.printStackTrace() | 
				
			||||||
 | 
					            val file = File(context.cacheDir, "tmp") | 
				
			||||||
 | 
					            val filePath = file.absolutePath | 
				
			||||||
 | 
					            try { | 
				
			||||||
 | 
					                val pfd = | 
				
			||||||
 | 
					                    context.contentResolver.openFileDescriptor(filePathUri!!, "r") | 
				
			||||||
 | 
					                        ?: return null | 
				
			||||||
 | 
					                val fd = pfd.fileDescriptor | 
				
			||||||
 | 
					                input = FileInputStream(fd) | 
				
			||||||
 | 
					                output = FileOutputStream(filePath) | 
				
			||||||
 | 
					                var read: Int | 
				
			||||||
 | 
					                val bytes = ByteArray(4096) | 
				
			||||||
 | 
					                while (input.read(bytes).also { read = it } != -1) { | 
				
			||||||
 | 
					                    output.write(bytes, 0, read) | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                input.close() | 
				
			||||||
 | 
					                output.close() | 
				
			||||||
 | 
					                return File(filePath).absolutePath | 
				
			||||||
 | 
					            } catch (ignored: IOException) { | 
				
			||||||
 | 
					                ignored.printStackTrace() | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } finally { | 
				
			||||||
 | 
					            cursor?.close() | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return null | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** | 
				
			||||||
 | 
					     * @param uri The Uri to check. | 
				
			||||||
 | 
					     * @return Whether the Uri authority is ExternalStorageProvider. | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    private fun isExternalStorageDocument(uri: Uri): Boolean { | 
				
			||||||
 | 
					        return "com.android.externalstorage.documents" == uri.authority | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** | 
				
			||||||
 | 
					     * @param uri The Uri to check. | 
				
			||||||
 | 
					     * @return Whether the Uri authority is DownloadsProvider. | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    private fun isDownloadsDocument(uri: Uri): Boolean { | 
				
			||||||
 | 
					        return "com.android.providers.downloads.documents" == uri.authority | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** | 
				
			||||||
 | 
					     * @param uri The Uri to check. | 
				
			||||||
 | 
					     * @return Whether the Uri authority is MediaProvider. | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    private fun isMediaDocument(uri: Uri): Boolean { | 
				
			||||||
 | 
					        return "com.android.providers.media.documents" == uri.authority | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** | 
				
			||||||
 | 
					     * @param uri The Uri to check. | 
				
			||||||
 | 
					     * @return Whether the Uri authority is Google Photos. | 
				
			||||||
 | 
					     */ | 
				
			||||||
 | 
					    private fun isGooglePhotosUri(uri: Uri): Boolean { | 
				
			||||||
 | 
					        return "com.google.android.apps.photos.content" == uri.authority | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue