-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from Fleeym/flame-stuff
fix file utils, move them to a separate class
- Loading branch information
Showing
6 changed files
with
405 additions
and
232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
app/src/main/java/com/geode/launcher/activityresult/GeodeOpenFileActivityResult.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} | ||
|
53 changes: 53 additions & 0 deletions
53
app/src/main/java/com/geode/launcher/activityresult/GeodeOpenFilesActivityResult.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} | ||
|
33 changes: 33 additions & 0 deletions
33
app/src/main/java/com/geode/launcher/activityresult/GeodeSaveFileActivityResult.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} | ||
|
196 changes: 196 additions & 0 deletions
196
app/src/main/java/com/geode/launcher/utils/FileUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} | ||
} |
Oops, something went wrong.