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