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