fix file utils, move them to a separate class

This commit is contained in:
Fleeym authored and Fleeym committed 2024-01-24 04:45:09 +02:00
1 parent 498bbf4528
commit dcfab5e001
6 files changed
+405 -232

No files matched your search

+11 -2
View File
@@ -4,13 +4,22 @@
<queries> <queries>
<package android:name="com.robtopx.geometryjump" /> <package android:name="com.robtopx.geometryjump" />
<intent>
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.OPENABLE" />
</intent>
</queries> </queries>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-feature <uses-feature
android:name="android.hardware.wifi" android:name="android.hardware.wifi"
@@ -0,0 +1,34 @@
package com.geode.launcher.activityresult
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.DocumentsContract
import androidx.activity.result.contract.ActivityResultContract
open class GeodeOpenFileActivityResult : ActivityResultContract<GeodeOpenFileActivityResult.OpenFileParams, Uri?>() {
class OpenFileParams(val extraMimes: Array<String>, val defaultPath: Uri?) {}
override fun createIntent(context: Context, input: OpenFileParams): Intent {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
.putExtra(Intent.EXTRA_MIME_TYPES, input.extraMimes)
.setType("*/*")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (input.defaultPath != null) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, input.defaultPath)
}
}
return intent
}
final override fun getSynchronousResult(
context: Context,
input: OpenFileParams
): SynchronousResult<Uri?>? = null
final override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
return intent.takeIf { resultCode == Activity.RESULT_OK }?.data
}
}
@@ -0,0 +1,53 @@
package com.geode.launcher.activityresult
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.DocumentsContract
import androidx.activity.result.contract.ActivityResultContract
open class GeodeOpenFilesActivityResult : ActivityResultContract<GeodeOpenFilesActivityResult.OpenFileParams, List<@JvmSuppressWildcards Uri>>() {
class OpenFileParams(val extraMimes: Array<String>, val defaultPath: Uri?) {}
override fun createIntent(context: Context, input: OpenFileParams): Intent {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
.putExtra(Intent.EXTRA_MIME_TYPES, input.extraMimes)
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
.setType("*/*")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (input.defaultPath != null) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, input.defaultPath)
}
}
return intent
}
final override fun getSynchronousResult(
context: Context,
input: OpenFileParams
): SynchronousResult<List<@JvmSuppressWildcards Uri>>? = null
final override fun parseResult(resultCode: Int, intent: Intent?): List<Uri> {
// Gracefully stolen from ActivityResultContracts.Intent.getclipDataUris
val clipData = intent.takeIf {
resultCode == Activity.RESULT_OK
}?.clipData
val resultSet = LinkedHashSet<Uri>()
intent?.data?.let { data ->
resultSet.add(data)
}
if (clipData == null && resultSet.isEmpty()) {
return emptyList()
} else if (clipData != null) {
for (i in 0 until clipData.itemCount) {
val uri = clipData.getItemAt(i).uri
if (uri != null) {
resultSet.add(uri)
}
}
}
return ArrayList(resultSet)
}
}
@@ -0,0 +1,33 @@
package com.geode.launcher.activityresult
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.DocumentsContract
import androidx.activity.result.contract.ActivityResultContract
open class GeodeSaveFileActivityResult : ActivityResultContract<GeodeSaveFileActivityResult.SaveFileParams, Uri?>() {
class SaveFileParams(val mimeType: String?, val defaultPath: Uri?) {}
override fun createIntent(context: Context, input: SaveFileParams): Intent {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
.setType(input.mimeType ?: "*/*")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (input.defaultPath != null) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, input.defaultPath)
}
}
return intent
}
final override fun getSynchronousResult(
context: Context,
input: SaveFileParams
): SynchronousResult<Uri?>? = null
final override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
return intent.takeIf { resultCode == Activity.RESULT_OK }?.data
}
}
@@ -0,0 +1,196 @@
package com.geode.launcher.utils
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import java.io.File
class FileUtils {
// copied from https://stackoverflow.com/questions/17546101/get-real-path-for-uri-android
// i am actually very lazy to move this to a separate class
// hello zmx i moved it
companion object {
fun getRealPathFromURI(context: Context, uri: Uri): String? {
when {
// DocumentProvider
DocumentsContract.isDocumentUri(context, uri) -> {
when {
// ExternalStorageProvider
isExternalStorageDocument(uri) -> {
return handleExternalStorageDocument(context, uri)
}
isDownloadsDocument(uri) -> {
return handleDownloadsDocument(context, uri)
}
isMediaDocument(uri) -> {
return handleMediaDocument(context, uri)
}
// TODO: add the geode provider
}
}
"content".equals(uri.scheme, ignoreCase = true) -> {
// Return the remote address
if (isGooglePhotosUri(uri)) return uri.lastPathSegment
// This happened with a directory
if (isExternalStorageDocument(uri)) {
return handleExternalStorageDocument(context, uri)
}
return getDataColumn(context, uri, null, null)
}
"file".equals(uri.scheme, ignoreCase = true) -> {
return uri.path
}
}
return null
}
private fun handleMediaDocument(context: Context, uri: Uri): String? {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":").toTypedArray()
val type = split[0]
var contentUri: Uri? = null
when (type) {
"image" -> {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
"video" -> {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
}
"audio" -> {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
}
val selection = "_id=?"
val selectionArgs = arrayOf(split[1])
return getDataColumn(
context,
contentUri,
selection,
selectionArgs
)
}
private fun handleDownloadsDocument(context: Context, uri: Uri): String? {
val fileName = getFilePath(context, uri)
if (fileName != null) {
return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName
}
var id = DocumentsContract.getDocumentId(uri)
if (id.startsWith("raw:")) {
id = id.replaceFirst("raw:".toRegex(), "")
val file = File(id)
if (file.exists()) return id
}
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
return getDataColumn(context, contentUri, null, null)
}
private fun handleExternalStorageDocument(context: Context, uri: Uri): String {
val docId: String = if (DocumentsContract.isDocumentUri(context, uri)) {
DocumentsContract.getDocumentId(uri)
} else {
// please please please PLEASE let this be the only other case
DocumentsContract.getTreeDocumentId(uri)
}
val split = docId.split(":").toTypedArray()
val type = split[0]
// This is for checking Main Memory
return if ("primary".equals(type, ignoreCase = true)) {
if (split.size > 1) {
Environment.getExternalStorageDirectory().toString() + "/" + split[1]
} else {
Environment.getExternalStorageDirectory().toString() + "/"
}
// This is for checking SD Card
} else {
"storage" + "/" + docId.replace(":", "/")
}
}
private fun getFilePath(context: Context, uri: Uri?): String? {
var cursor: Cursor? = null
val projection = arrayOf(
MediaStore.MediaColumns.DISPLAY_NAME
)
try {
if (uri == null) return null
cursor = context.contentResolver.query(
uri, projection, null, null,
null
)
if (cursor != null && cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)
val data = cursor.getString(index)
cursor.close()
return data
}
} catch (e: Exception) {
cursor?.close()
} finally {
cursor?.close()
}
return null
}
private fun getDataColumn(context: Context, uri: Uri?, selection: String?,
selectionArgs: Array<String>?): String? {
var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(
column
)
try {
if (uri == null) return null
cursor = context.contentResolver.query(
uri, projection, selection, selectionArgs,
null
)
if (cursor != null && cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(column)
val data = cursor.getString(index)
cursor.close()
return data
}
} catch (e: Exception) {
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
}
}
}
@@ -1,69 +1,74 @@
package com.geode.launcher.utils package com.geode.launcher.utils
import android.app.Activity import android.content.ActivityNotFoundException
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.ContentUris
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.os.Environment
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.provider.MediaStore
import android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
import android.provider.OpenableColumns
import android.util.Log import android.util.Log
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.geode.launcher.activityresult.GeodeOpenFileActivityResult
import com.geode.launcher.activityresult.GeodeOpenFilesActivityResult
import com.geode.launcher.activityresult.GeodeSaveFileActivityResult
import java.io.File import java.io.File
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.net.URI
import kotlin.system.exitProcess import kotlin.system.exitProcess
@Suppress("unused") @Suppress("unused")
object GeodeUtils { object GeodeUtils {
private lateinit var activity: WeakReference<AppCompatActivity> private lateinit var activity: WeakReference<AppCompatActivity>
private lateinit var fileResultLauncher: ActivityResultLauncher<Intent> private lateinit var openFileResultLauncher: ActivityResultLauncher<GeodeOpenFileActivityResult.OpenFileParams>
private lateinit var filesResultLauncher: ActivityResultLauncher<Intent> private lateinit var openDirectoryResultLauncher: ActivityResultLauncher<Uri?>
private lateinit var openFilesResultLauncher: ActivityResultLauncher<GeodeOpenFilesActivityResult.OpenFileParams>
private lateinit var saveFileResultLauncher: ActivityResultLauncher<GeodeSaveFileActivityResult.SaveFileParams>
fun setContext(activity: AppCompatActivity) { fun setContext(activity: AppCompatActivity) {
this.activity = WeakReference(activity) this.activity = WeakReference(activity)
fileResultLauncher = activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> openFileResultLauncher = activity.registerForActivityResult(GeodeOpenFileActivityResult()) { uri ->
if (result.resultCode == Activity.RESULT_OK) { if (uri != null) {
val data = result.data val path = FileUtils.getRealPathFromURI(activity, uri)
if (data != null) { if (path != null) {
val uri = data.data selectFileCallback(path)
if (uri != null) { return@registerForActivityResult
val path = getRealPathFromURI(activity, uri)
if (path != null) {
selectFileCallback(path)
return@registerForActivityResult
}
}
} }
} }
failedCallback() failedCallback()
} }
filesResultLauncher = activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> openDirectoryResultLauncher = activity.registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
if (result.resultCode == Activity.RESULT_OK) { if (it != null) {
val data = result.data val path = FileUtils.getRealPathFromURI(activity, it)
if (data != null) { if (path != null)
val clipData = data.clipData selectFileCallback(path)
if (clipData != null) { return@registerForActivityResult
val paths = Array(clipData.itemCount) { "" } }
for (i in 0 until clipData.itemCount) { failedCallback()
val path = getRealPathFromURI(activity, clipData.getItemAt(i).uri) }
if (path != null) { openFilesResultLauncher = activity.registerForActivityResult(GeodeOpenFilesActivityResult()) { result ->
paths[i] = path if (result.isEmpty()) {
} failedCallback()
} return@registerForActivityResult
selectFilesCallback(paths) }
return@registerForActivityResult val paths: Array<String> = Array(result.size) {"n = $it"}
} for (i in result.indices) {
val path = FileUtils.getRealPathFromURI(activity, result[i])
if (path != null) {
paths[i] = path
}
}
selectFilesCallback(paths)
return@registerForActivityResult
}
saveFileResultLauncher = activity.registerForActivityResult(GeodeSaveFileActivityResult()) { uri ->
if (uri != null) {
val path = FileUtils.getRealPathFromURI(activity, uri)
if (path != null) {
selectFileCallback(path)
return@registerForActivityResult
} }
} }
failedCallback() failedCallback()
@@ -72,16 +77,13 @@ object GeodeUtils {
@JvmStatic @JvmStatic
fun getLogcatCrashBuffer(): String { fun getLogcatCrashBuffer(): String {
try { return try {
val logcatProcess = Runtime.getRuntime().exec("logcat -v brief -b crash -d") val logcatProcess = Runtime.getRuntime().exec("logcat -v brief -b crash -d")
val logcatOutput = logcatProcess.inputStream.bufferedReader().readText() logcatProcess.inputStream.bufferedReader().readText()
} catch (e: Exception) {
return logcatOutput
}
catch (e: Exception) {
Log.e("Geode", "Failed to get logcat crash buffer", e) Log.e("Geode", "Failed to get logcat crash buffer", e)
return "" ""
} }
} }
@@ -111,18 +113,19 @@ object GeodeUtils {
activity.get()?.run { activity.get()?.run {
packageManager.getLaunchIntentForPackage(packageName)?.also { packageManager.getLaunchIntentForPackage(packageName)?.also {
val mainIntent = Intent.makeRestartActivityTask(it.component) val mainIntent = Intent.makeRestartActivityTask(it.component)
mainIntent.putExtra("restarted", true); mainIntent.putExtra("restarted", true)
startActivity(mainIntent) startActivity(mainIntent)
exitProcess(0) exitProcess(0)
} }
} }
} }
// TODO As of now this is unused
@JvmStatic @JvmStatic
fun openFolder(path: String): Boolean { fun openFolder(path: String): Boolean {
activity.get()?.run { activity.get()?.run {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addCategory(Intent.CATEGORY_OPENABLE) intent.addCategory(Intent.CATEGORY_OPENABLE)
DocumentFile.fromFile(File(path)).also { DocumentFile.fromFile(File(path)).also {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, it.uri) intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, it.uri)
@@ -137,28 +140,27 @@ object GeodeUtils {
return false return false
} }
@Suppress("KotlinJniMissingFunction")
external fun selectFileCallback(path: String) external fun selectFileCallback(path: String)
@Suppress("KotlinJniMissingFunction")
external fun selectFilesCallback(paths: Array<String>) external fun selectFilesCallback(paths: Array<String>)
@Suppress("KotlinJniMissingFunction")
external fun failedCallback() external fun failedCallback()
@JvmStatic @JvmStatic
fun selectFile(path: String): Boolean { fun selectFile(path: String): Boolean {
activity.get()?.run { activity.get()?.run {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) var uri: Uri?
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_OPENABLE)
DocumentFile.fromFile(File(path)).also { DocumentFile.fromFile(File(path)).also {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, it.uri) uri = it.uri
} }
intent.setType("*/*") try {
openFileResultLauncher.launch(GeodeOpenFileActivityResult.OpenFileParams(arrayOf("*/*"), uri))
if (intent.resolveActivity(packageManager) != null) {
print("Geode Selectfile")
fileResultLauncher.launch(intent)
print("Geode launched ")
return true return true
} catch (e: ActivityNotFoundException) {
return false
} }
} }
return false return false
@@ -167,18 +169,15 @@ object GeodeUtils {
@JvmStatic @JvmStatic
fun selectFiles(path: String): Boolean { fun selectFiles(path: String): Boolean {
activity.get()?.run { activity.get()?.run {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) var uri: Uri?
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_OPENABLE)
DocumentFile.fromFile(File(path)).also { DocumentFile.fromFile(File(path)).also {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, it.uri) uri = it.uri
} }
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true) try {
intent.setType("*/*") openFilesResultLauncher.launch(GeodeOpenFilesActivityResult.OpenFileParams(arrayOf("*/*"), uri))
if (intent.resolveActivity(packageManager) != null) {
filesResultLauncher.launch(intent)
return true return true
} catch (e: ActivityNotFoundException) {
return false
} }
} }
return false return false
@@ -187,17 +186,15 @@ object GeodeUtils {
@JvmStatic @JvmStatic
fun selectFolder(path: String): Boolean { fun selectFolder(path: String): Boolean {
activity.get()?.run { activity.get()?.run {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) var uri: Uri?
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_OPENABLE)
DocumentFile.fromFile(File(path)).also { DocumentFile.fromFile(File(path)).also {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, it.uri) uri = it.uri
} }
intent.setType("*/*") try {
openDirectoryResultLauncher.launch(uri)
if (intent.resolveActivity(packageManager) != null) {
fileResultLauncher.launch(intent)
return true return true
} catch (e: ActivityNotFoundException) {
return false
} }
} }
return false return false
@@ -206,17 +203,16 @@ object GeodeUtils {
@JvmStatic @JvmStatic
fun createFile(path: String): Boolean { fun createFile(path: String): Boolean {
activity.get()?.run { activity.get()?.run {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT) var uri: Uri?
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_OPENABLE)
DocumentFile.fromFile(File(path)).also { DocumentFile.fromFile(File(path)).also {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, it.uri) uri = it.uri
} }
intent.setType("*/*")
if (intent.resolveActivity(packageManager) != null) { try {
fileResultLauncher.launch(intent) saveFileResultLauncher.launch(GeodeSaveFileActivityResult.SaveFileParams(null, uri))
return true return true
} catch (e: ActivityNotFoundException) {
return false
} }
} }
return false return false
@@ -250,154 +246,6 @@ object GeodeUtils {
return "" return ""
} }
// copied from https://stackoverflow.com/questions/17546101/get-real-path-for-uri-android
// i am actually very lazy to move this to a separate class
fun getRealPathFromURI(context: Context, uri: Uri): String? {
when {
// DocumentProvider
DocumentsContract.isDocumentUri(context, uri) -> {
when {
// ExternalStorageProvider
isExternalStorageDocument(uri) -> {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":").toTypedArray()
val type = split[0]
// This is for checking Main Memory
return if ("primary".equals(type, ignoreCase = true)) {
if (split.size > 1) {
Environment.getExternalStorageDirectory().toString() + "/" + split[1]
} else {
Environment.getExternalStorageDirectory().toString() + "/"
}
// This is for checking SD Card
} else {
"storage" + "/" + docId.replace(":", "/")
}
}
isDownloadsDocument(uri) -> {
val fileName = getFilePath(context, uri)
if (fileName != null) {
return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName
}
var id = DocumentsContract.getDocumentId(uri)
if (id.startsWith("raw:")) {
id = id.replaceFirst("raw:".toRegex(), "")
val file = File(id)
if (file.exists()) return id
}
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
return getDataColumn(context, contentUri, null, null)
}
isMediaDocument(uri) -> {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":").toTypedArray()
val type = split[0]
var contentUri: Uri? = null
when (type) {
"image" -> {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
"video" -> {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
}
"audio" -> {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
}
val selection = "_id=?"
val selectionArgs = arrayOf(split[1])
return getDataColumn(context, contentUri, selection, selectionArgs)
}
// TODO: add the geode provider
}
}
"content".equals(uri.scheme, ignoreCase = true) -> {
// Return the remote address
if (isGooglePhotosUri(uri)) return uri.lastPathSegment
return getDataColumn(context, uri, null, null)
}
"file".equals(uri.scheme, ignoreCase = true) -> {
return uri.path
}
}
return null
}
fun getDataColumn(context: Context, uri: Uri?, selection: String?,
selectionArgs: Array<String>?): String? {
var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(
column
)
try {
if (uri == null) return null
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs,
null)
if (cursor != null && cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(index)
}
} finally {
cursor?.close()
}
return null
}
fun getFilePath(context: Context, uri: Uri?): String? {
var cursor: Cursor? = null
val projection = arrayOf(
MediaStore.MediaColumns.DISPLAY_NAME
)
try {
if (uri == null) return null
cursor = context.contentResolver.query(uri, projection, null, null,
null)
if (cursor != null && cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)
return cursor.getString(index)
}
} finally {
cursor?.close()
}
return null
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
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.
*/
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.
*/
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.
*/
fun isGooglePhotosUri(uri: Uri): Boolean {
return "com.google.android.apps.photos.content" == uri.authority
}
fun isGeodeUri(uri: Uri): Boolean { fun isGeodeUri(uri: Uri): Boolean {
return "com.geode.launcher.user" == uri.authority return "com.geode.launcher.user" == uri.authority
} }