This commit is contained in:
Thibault Deckers 2025-02-04 18:56:12 +01:00
parent ffa23f445d
commit cdfd7808dd
20 changed files with 75 additions and 63 deletions

View file

@ -8,7 +8,6 @@ import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -16,6 +15,7 @@ import android.os.Looper
import android.util.Log import android.util.Log
import android.util.SizeF import android.util.SizeF
import android.widget.RemoteViews import android.widget.RemoteViews
import androidx.core.net.toUri
import app.loup.streams_channel.StreamsChannel import app.loup.streams_channel.StreamsChannel
import deckers.thibault.aves.channel.AvesByteSendingMethodCodec import deckers.thibault.aves.channel.AvesByteSendingMethodCodec
import deckers.thibault.aves.channel.calls.DeviceHandler import deckers.thibault.aves.channel.calls.DeviceHandler
@ -260,7 +260,7 @@ class HomeWidgetProvider : AppWidgetProvider() {
} }
private fun buildUpdateIntent(context: Context, widgetId: Int): PendingIntent { private fun buildUpdateIntent(context: Context, widgetId: Int): PendingIntent {
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, Uri.parse("widget://$widgetId"), context, HomeWidgetProvider::class.java) val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, "widget://$widgetId".toUri(), context, HomeWidgetProvider::class.java)
.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(widgetId)) .putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(widgetId))
return PendingIntent.getBroadcast( return PendingIntent.getBroadcast(
@ -277,7 +277,7 @@ class HomeWidgetProvider : AppWidgetProvider() {
private fun buildOpenAppIntent(context: Context, widgetId: Int): PendingIntent { private fun buildOpenAppIntent(context: Context, widgetId: Int): PendingIntent {
// set a unique URI to prevent the intent (and its extras) from being shared by different widgets // set a unique URI to prevent the intent (and its extras) from being shared by different widgets
val intent = Intent(MainActivity.INTENT_ACTION_WIDGET_OPEN, Uri.parse("widget://$widgetId"), context, MainActivity::class.java) val intent = Intent(MainActivity.INTENT_ACTION_WIDGET_OPEN, "widget://$widgetId".toUri(), context, MainActivity::class.java)
.putExtra(MainActivity.EXTRA_KEY_WIDGET_ID, widgetId) .putExtra(MainActivity.EXTRA_KEY_WIDGET_ID, widgetId)
return PendingIntent.getActivity( return PendingIntent.getActivity(

View file

@ -69,6 +69,7 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import androidx.core.net.toUri
// `FlutterFragmentActivity` because of local auth plugin // `FlutterFragmentActivity` because of local auth plugin
open class MainActivity : FlutterFragmentActivity() { open class MainActivity : FlutterFragmentActivity() {
@ -442,7 +443,7 @@ open class MainActivity : FlutterFragmentActivity() {
return return
} }
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, Uri.parse(uriString)) } val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this@MainActivity, uriString.toUri()) }
val intent = Intent().apply { val intent = Intent().apply {
val firstUri = toUri(pickedUris.first()) val firstUri = toUri(pickedUris.first())
if (pickedUris.size == 1) { if (pickedUris.size == 1) {

View file

@ -7,6 +7,7 @@ import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.utils.getParcelableExtraCompat import deckers.thibault.aves.utils.getParcelableExtraCompat
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import androidx.core.net.toUri
class WallpaperActivity : MainActivity() { class WallpaperActivity : MainActivity() {
private var originalIntent: String? = null private var originalIntent: String? = null
@ -39,7 +40,7 @@ class WallpaperActivity : MainActivity() {
if (originalIntent != null) { if (originalIntent != null) {
val pickedUris = call.argument<List<String>>("uris") val pickedUris = call.argument<List<String>>("uris")
if (!pickedUris.isNullOrEmpty()) { if (!pickedUris.isNullOrEmpty()) {
val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this, Uri.parse(uriString)) } val toUri = { uriString: String -> AppAdapterHandler.getShareableUri(this, uriString.toUri()) }
onNewIntent(Intent().apply { onNewIntent(Intent().apply {
action = originalIntent action = originalIntent
data = toUri(pickedUris.first()) data = toUri(pickedUris.first())

View file

@ -19,6 +19,7 @@ import androidx.core.content.FileProvider
import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat import androidx.core.graphics.drawable.IconCompat
import androidx.core.net.toUri
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
@ -192,7 +193,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
} }
private fun copyToClipboard(call: MethodCall, result: MethodChannel.Result) { private fun copyToClipboard(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val label = call.argument<String>("label") val label = call.argument<String>("label")
if (uri == null) { if (uri == null) {
result.error("copyToClipboard-args", "missing arguments", null) result.error("copyToClipboard-args", "missing arguments", null)
@ -219,7 +220,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
private fun open(call: MethodCall, result: MethodChannel.Result) { private fun open(call: MethodCall, result: MethodChannel.Result) {
val title = call.argument<String>("title") val title = call.argument<String>("title")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val forceChooser = call.argument<Boolean>("forceChooser") val forceChooser = call.argument<Boolean>("forceChooser")
if (uri == null || forceChooser == null) { if (uri == null || forceChooser == null) {
@ -236,7 +237,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
} }
private fun openMap(call: MethodCall, result: MethodChannel.Result) { private fun openMap(call: MethodCall, result: MethodChannel.Result) {
val geoUri = call.argument<String>("geoUri")?.let { Uri.parse(it) } val geoUri = call.argument<String>("geoUri")?.toUri()
if (geoUri == null) { if (geoUri == null) {
result.error("openMap-args", "missing arguments", null) result.error("openMap-args", "missing arguments", null)
return return
@ -250,7 +251,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
private fun setAs(call: MethodCall, result: MethodChannel.Result) { private fun setAs(call: MethodCall, result: MethodChannel.Result) {
val title = call.argument<String>("title") val title = call.argument<String>("title")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
if (uri == null) { if (uri == null) {
result.error("setAs-args", "missing arguments", null) result.error("setAs-args", "missing arguments", null)
@ -273,7 +274,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
return return
} }
val uriList = ArrayList(urisByMimeType.values.flatten().mapNotNull { getShareableUri(context, Uri.parse(it)) }) val uriList = ArrayList(urisByMimeType.values.flatten().mapNotNull { getShareableUri(context, it.toUri()) })
val mimeTypes = urisByMimeType.keys.toTypedArray() val mimeTypes = urisByMimeType.keys.toTypedArray()
// simplify share intent for a single item, as some apps can handle one item but not more // simplify share intent for a single item, as some apps can handle one item but not more
@ -366,8 +367,8 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
// route dependent arguments // route dependent arguments
val filters = call.argument<List<String>>("filters") val filters = call.argument<List<String>>("filters")
val explorerPath = call.argument<String>("path") val explorerPath = call.argument<String>("path")
val viewUri = call.argument<String>("viewUri")?.let { Uri.parse(it) } val viewUri = call.argument<String>("viewUri")?.toUri()
val geoUri = call.argument<String>("geoUri")?.let { Uri.parse(it) } val geoUri = call.argument<String>("geoUri")?.toUri()
if (label == null || route == null) { if (label == null || route == null) {
result.error("pin-args", "missing arguments", null) result.error("pin-args", "missing arguments", null)

View file

@ -12,6 +12,7 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
import androidx.core.net.toUri
import com.drew.metadata.file.FileTypeDirectory import com.drew.metadata.file.FileTypeDirectory
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.metadata.ExifInterfaceHelper import deckers.thibault.aves.metadata.ExifInterfaceHelper
@ -127,7 +128,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
} }
private fun getBitmapFactoryInfo(call: MethodCall, result: MethodChannel.Result) { private fun getBitmapFactoryInfo(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
if (uri == null) { if (uri == null) {
result.error("getBitmapDecoderInfo-args", "missing arguments", null) result.error("getBitmapDecoderInfo-args", "missing arguments", null)
return return
@ -156,7 +157,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
private fun getContentResolverMetadata(call: MethodCall, result: MethodChannel.Result) { private fun getContentResolverMetadata(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getContentResolverMetadata-args", "missing arguments", null) result.error("getContentResolverMetadata-args", "missing arguments", null)
return return
@ -212,7 +213,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
private fun getExifInterfaceMetadata(call: MethodCall, result: MethodChannel.Result) { private fun getExifInterfaceMetadata(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getExifInterfaceMetadata-args", "missing arguments", null) result.error("getExifInterfaceMetadata-args", "missing arguments", null)
@ -239,7 +240,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
} }
private fun getMediaMetadataRetrieverMetadata(call: MethodCall, result: MethodChannel.Result) { private fun getMediaMetadataRetrieverMetadata(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
if (uri == null) { if (uri == null) {
result.error("getMediaMetadataRetrieverMetadata-args", "missing arguments", null) result.error("getMediaMetadataRetrieverMetadata-args", "missing arguments", null)
return return
@ -264,7 +265,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
private fun getMetadataExtractorSummary(call: MethodCall, result: MethodChannel.Result) { private fun getMetadataExtractorSummary(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getMetadataExtractorSummary-args", "missing arguments", null) result.error("getMetadataExtractorSummary-args", "missing arguments", null)
@ -308,7 +309,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
private fun getMp4ParserDump(call: MethodCall, result: MethodChannel.Result) { private fun getMp4ParserDump(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getMp4ParserDump-args", "missing arguments", null) result.error("getMp4ParserDump-args", "missing arguments", null)
return return
@ -338,7 +339,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
private fun getPixyMetadata(call: MethodCall, result: MethodChannel.Result) { private fun getPixyMetadata(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getPixyMetadata-args", "missing arguments", null) result.error("getPixyMetadata-args", "missing arguments", null)
return return
@ -359,7 +360,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
} }
private fun getTiffStructure(call: MethodCall, result: MethodChannel.Result) { private fun getTiffStructure(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
if (uri == null) { if (uri == null) {
result.error("getTiffStructure-args", "missing arguments", null) result.error("getTiffStructure-args", "missing arguments", null)
return return

View file

@ -6,12 +6,12 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.Resources import android.content.res.Resources
import android.location.Geocoder import android.location.Geocoder
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.LocaleList import android.os.LocaleList
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.Settings import android.provider.Settings
import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.net.toUri
import com.google.android.material.color.DynamicColors import com.google.android.material.color.DynamicColors
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.model.FieldMap
@ -129,7 +129,7 @@ class DeviceHandler(private val context: Context) : MethodCallHandler {
return return
} }
val intent = Intent(Settings.ACTION_REQUEST_MANAGE_MEDIA, Uri.parse("package:${context.packageName}")) val intent = Intent(Settings.ACTION_REQUEST_MANAGE_MEDIA, "package:${context.packageName}".toUri())
context.startActivity(intent) context.startActivity(intent)
result.success(true) result.success(true)
} }

View file

@ -1,9 +1,9 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.content.Context import android.content.Context
import android.net.Uri
import android.util.Log import android.util.Log
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import com.adobe.internal.xmp.XMPException import com.adobe.internal.xmp.XMPException
import com.adobe.internal.xmp.XMPUtils import com.adobe.internal.xmp.XMPUtils
@ -59,7 +59,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
private suspend fun getExifThumbnails(call: MethodCall, result: MethodChannel.Result) { private suspend fun getExifThumbnails(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getExifThumbnails-args", "missing arguments", null) result.error("getExifThumbnails-args", "missing arguments", null)
@ -88,7 +88,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
private fun extractGoogleDeviceItem(call: MethodCall, result: MethodChannel.Result) { private fun extractGoogleDeviceItem(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val displayName = call.argument<String>("displayName") val displayName = call.argument<String>("displayName")
val dataUri = call.argument<String>("dataUri") val dataUri = call.argument<String>("dataUri")
@ -143,7 +143,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
private fun extractJpegMpfItem(call: MethodCall, result: MethodChannel.Result) { private fun extractJpegMpfItem(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val displayName = call.argument<String>("displayName") val displayName = call.argument<String>("displayName")
val id = call.argument<Int>("id") val id = call.argument<Int>("id")
@ -177,7 +177,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
private fun extractMotionPhotoImage(call: MethodCall, result: MethodChannel.Result) { private fun extractMotionPhotoImage(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val displayName = call.argument<String>("displayName") val displayName = call.argument<String>("displayName")
if (mimeType == null || uri == null || sizeBytes == null) { if (mimeType == null || uri == null || sizeBytes == null) {
@ -198,7 +198,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
private fun extractMotionPhotoVideo(call: MethodCall, result: MethodChannel.Result) { private fun extractMotionPhotoVideo(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val displayName = call.argument<String>("displayName") val displayName = call.argument<String>("displayName")
if (mimeType == null || uri == null || sizeBytes == null) { if (mimeType == null || uri == null || sizeBytes == null) {
@ -219,7 +219,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
} }
private fun extractVideoEmbeddedPicture(call: MethodCall, result: MethodChannel.Result) { private fun extractVideoEmbeddedPicture(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val displayName = call.argument<String>("displayName") val displayName = call.argument<String>("displayName")
if (uri == null) { if (uri == null) {
result.error("extractVideoEmbeddedPicture-args", "missing arguments", null) result.error("extractVideoEmbeddedPicture-args", "missing arguments", null)
@ -251,7 +251,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
private fun extractXmpDataProp(call: MethodCall, result: MethodChannel.Result) { private fun extractXmpDataProp(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val displayName = call.argument<String>("displayName") val displayName = call.argument<String>("displayName")
val dataProp = call.argument<List<Any>>("propPath") val dataProp = call.argument<List<Any>>("propPath")

View file

@ -1,8 +1,8 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.content.ContextWrapper import android.content.ContextWrapper
import android.net.Uri
import android.util.Log import android.util.Log
import androidx.core.net.toUri
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend
import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.model.FieldMap
@ -44,7 +44,7 @@ class MediaEditHandler(private val contextWrapper: ContextWrapper) : MethodCallH
} }
private suspend fun captureFrame(call: MethodCall, result: MethodChannel.Result) { private suspend fun captureFrame(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val desiredName = call.argument<String>("desiredName") val desiredName = call.argument<String>("desiredName")
val exifFields = call.argument<FieldMap>("exif") ?: HashMap() val exifFields = call.argument<FieldMap>("exif") ?: HashMap()
val bytes = call.argument<ByteArray>("bytes") val bytes = call.argument<ByteArray>("bytes")

View file

@ -2,7 +2,7 @@ package deckers.thibault.aves.channel.calls
import android.content.Context import android.content.Context
import android.graphics.Rect import android.graphics.Rect
import android.net.Uri import androidx.core.net.toUri
import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend
import deckers.thibault.aves.channel.calls.fetchers.RegionFetcher import deckers.thibault.aves.channel.calls.fetchers.RegionFetcher
import deckers.thibault.aves.channel.calls.fetchers.SvgRegionFetcher import deckers.thibault.aves.channel.calls.fetchers.SvgRegionFetcher
@ -68,7 +68,7 @@ class MediaFetchBytesHandler(private val context: Context) : MethodCallHandler {
} }
private suspend fun getRegion(call: MethodCall, result: MethodChannel.Result) { private suspend fun getRegion(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val pageId = call.argument<Int>("pageId") val pageId = call.argument<Int>("pageId")
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()

View file

@ -1,7 +1,7 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.content.Context import android.content.Context
import android.net.Uri import androidx.core.net.toUri
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.model.FieldMap
@ -28,7 +28,7 @@ class MediaFetchObjectHandler(private val context: Context) : MethodCallHandler
private fun getEntry(call: MethodCall, result: MethodChannel.Result) { private fun getEntry(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") // MIME type is optional val mimeType = call.argument<String>("mimeType") // MIME type is optional
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val allowUnsized = call.argument<Boolean>("allowUnsized") ?: false val allowUnsized = call.argument<Boolean>("allowUnsized") ?: false
if (uri == null) { if (uri == null) {
result.error("getEntry-args", "missing arguments", null) result.error("getEntry-args", "missing arguments", null)

View file

@ -7,10 +7,10 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.media.AudioManager import android.media.AudioManager
import android.media.session.PlaybackState import android.media.session.PlaybackState
import android.net.Uri
import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat import android.support.v4.media.session.PlaybackStateCompat
import androidx.core.net.toUri
import androidx.media.session.MediaButtonReceiver import androidx.media.session.MediaButtonReceiver
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend
@ -63,7 +63,7 @@ class MediaSessionHandler(private val context: Context, private val mediaCommand
} }
private suspend fun updateSession(call: MethodCall, result: MethodChannel.Result) { private suspend fun updateSession(call: MethodCall, result: MethodChannel.Result) {
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val title = call.argument<String>("title") ?: uri?.toString() val title = call.argument<String>("title") ?: uri?.toString()
val durationMillis = call.argument<Number>("durationMillis")?.toLong() val durationMillis = call.argument<Number>("durationMillis")?.toLong()
val stateString = call.argument<String>("state") val stateString = call.argument<String>("state")

View file

@ -1,7 +1,7 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.content.ContextWrapper import android.content.ContextWrapper
import android.net.Uri import androidx.core.net.toUri
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.metadata.Mp4TooLargeException import deckers.thibault.aves.metadata.Mp4TooLargeException
import deckers.thibault.aves.model.ExifOrientationOp import deckers.thibault.aves.model.ExifOrientationOp
@ -54,7 +54,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa
return return
} }
val uri = (entryMap["uri"] as String?)?.let { Uri.parse(it) } val uri = (entryMap["uri"] as String?)?.toUri()
val path = entryMap["path"] as String? val path = entryMap["path"] as String?
val mimeType = entryMap["mimeType"] as String? val mimeType = entryMap["mimeType"] as String?
if (uri == null || path == null || mimeType == null) { if (uri == null || path == null || mimeType == null) {
@ -82,7 +82,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa
return return
} }
val uri = (entryMap["uri"] as String?)?.let { Uri.parse(it) } val uri = (entryMap["uri"] as String?)?.toUri()
val path = entryMap["path"] as String? val path = entryMap["path"] as String?
val mimeType = entryMap["mimeType"] as String? val mimeType = entryMap["mimeType"] as String?
if (uri == null || path == null || mimeType == null) { if (uri == null || path == null || mimeType == null) {
@ -109,7 +109,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa
return return
} }
val uri = (entryMap["uri"] as String?)?.let { Uri.parse(it) } val uri = (entryMap["uri"] as String?)?.toUri()
val path = entryMap["path"] as String? val path = entryMap["path"] as String?
val mimeType = entryMap["mimeType"] as String? val mimeType = entryMap["mimeType"] as String?
if (uri == null || path == null || mimeType == null) { if (uri == null || path == null || mimeType == null) {
@ -134,7 +134,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa
return return
} }
val uri = (entryMap["uri"] as String?)?.let { Uri.parse(it) } val uri = (entryMap["uri"] as String?)?.toUri()
val path = entryMap["path"] as String? val path = entryMap["path"] as String?
val mimeType = entryMap["mimeType"] as String? val mimeType = entryMap["mimeType"] as String?
if (uri == null || path == null || mimeType == null) { if (uri == null || path == null || mimeType == null) {
@ -160,7 +160,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa
return return
} }
val uri = (entryMap["uri"] as String?)?.let { Uri.parse(it) } val uri = (entryMap["uri"] as String?)?.toUri()
val path = entryMap["path"] as String? val path = entryMap["path"] as String?
val mimeType = entryMap["mimeType"] as String? val mimeType = entryMap["mimeType"] as String?
if (uri == null || path == null || mimeType == null) { if (uri == null || path == null || mimeType == null) {

View file

@ -107,6 +107,7 @@ import java.util.Locale
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.math.roundToLong import kotlin.math.roundToLong
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
import androidx.core.net.toUri
class MetadataFetchHandler(private val context: Context) : MethodCallHandler { class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
@ -131,7 +132,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getAllMetadata(call: MethodCall, result: MethodChannel.Result) { private fun getAllMetadata(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getAllMetadata-args", "missing arguments", null) result.error("getAllMetadata-args", "missing arguments", null)
@ -516,7 +517,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
// - XMP / MicrosoftPhoto:Rating // - XMP / MicrosoftPhoto:Rating
private fun getCatalogMetadata(call: MethodCall, result: MethodChannel.Result) { private fun getCatalogMetadata(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val path = call.argument<String>("path") val path = call.argument<String>("path")
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
@ -869,7 +870,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getOverlayMetadata(call: MethodCall, result: MethodChannel.Result) { private fun getOverlayMetadata(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val fields = call.argument<List<String>>("fields") val fields = call.argument<List<String>>("fields")
if (mimeType == null || uri == null || fields == null) { if (mimeType == null || uri == null || fields == null) {
@ -1000,7 +1001,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getGeoTiffInfo(call: MethodCall, result: MethodChannel.Result) { private fun getGeoTiffInfo(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getGeoTiffInfo-args", "missing arguments", null) result.error("getGeoTiffInfo-args", "missing arguments", null)
@ -1041,7 +1042,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getMultiPageInfo(call: MethodCall, result: MethodChannel.Result) { private fun getMultiPageInfo(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val isMotionPhoto = call.argument<Boolean>("isMotionPhoto") val isMotionPhoto = call.argument<Boolean>("isMotionPhoto")
if (mimeType == null || uri == null || sizeBytes == null || isMotionPhoto == null) { if (mimeType == null || uri == null || sizeBytes == null || isMotionPhoto == null) {
@ -1068,7 +1069,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getPanoramaInfo(call: MethodCall, result: MethodChannel.Result) { private fun getPanoramaInfo(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getPanoramaInfo-args", "missing arguments", null) result.error("getPanoramaInfo-args", "missing arguments", null)
@ -1120,7 +1121,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getIptc(call: MethodCall, result: MethodChannel.Result) { private fun getIptc(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getIptc-args", "missing arguments", null) result.error("getIptc-args", "missing arguments", null)
return return
@ -1146,7 +1147,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
// return an empty list if there is no XMP // return an empty list if there is no XMP
private fun getXmp(call: MethodCall, result: MethodChannel.Result) { private fun getXmp(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
if (mimeType == null || uri == null) { if (mimeType == null || uri == null) {
result.error("getXmp-args", "missing arguments", null) result.error("getXmp-args", "missing arguments", null)
@ -1218,7 +1219,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getContentPropValue(call: MethodCall, result: MethodChannel.Result) { private fun getContentPropValue(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val prop = call.argument<String>("prop") val prop = call.argument<String>("prop")
if (mimeType == null || uri == null || prop == null) { if (mimeType == null || uri == null || prop == null) {
result.error("getContentPropValue-args", "missing arguments", null) result.error("getContentPropValue-args", "missing arguments", null)
@ -1235,7 +1236,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getDate(call: MethodCall, result: MethodChannel.Result) { private fun getDate(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val field = call.argument<String>("field") val field = call.argument<String>("field")
if (mimeType == null || uri == null || field == null) { if (mimeType == null || uri == null || field == null) {
@ -1304,7 +1305,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
private fun getFields(call: MethodCall, result: MethodChannel.Result) { private fun getFields(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
val uri = call.argument<String>("uri")?.let { Uri.parse(it) } val uri = call.argument<String>("uri")?.toUri()
val sizeBytes = call.argument<Number>("sizeBytes")?.toLong() val sizeBytes = call.argument<Number>("sizeBytes")?.toLong()
val fields = call.argument<List<String>>("fields") val fields = call.argument<List<String>>("fields")
if (mimeType == null || uri == null || fields == null) { if (mimeType == null || uri == null || fields == null) {

View file

@ -24,6 +24,7 @@ import deckers.thibault.aves.utils.MimeTypes.needRotationAfterGlide
import deckers.thibault.aves.utils.StorageUtils import deckers.thibault.aves.utils.StorageUtils
import deckers.thibault.aves.utils.UriUtils.tryParseId import deckers.thibault.aves.utils.UriUtils.tryParseId
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import androidx.core.net.toUri
class ThumbnailFetcher internal constructor( class ThumbnailFetcher internal constructor(
private val context: Context, private val context: Context,
@ -39,7 +40,7 @@ class ThumbnailFetcher internal constructor(
private val quality: Int, private val quality: Int,
private val result: MethodChannel.Result, private val result: MethodChannel.Result,
) { ) {
private val uri: Uri = Uri.parse(uri) private val uri: Uri = uri.toUri()
private val width: Int = if (width?.takeIf { it > 0 } != null) width else defaultSize private val width: Int = if (width?.takeIf { it > 0 } != null) width else defaultSize
private val height: Int = if (height?.takeIf { it > 0 } != null) height else defaultSize private val height: Int = if (height?.takeIf { it > 0 } != null) height else defaultSize
private val svgFetch = mimeType == SVG private val svgFetch = mimeType == SVG

View file

@ -7,6 +7,7 @@ import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import androidx.core.net.toUri
import deckers.thibault.aves.MainActivity import deckers.thibault.aves.MainActivity
import deckers.thibault.aves.PendingStorageAccessResultHandler import deckers.thibault.aves.PendingStorageAccessResultHandler
import deckers.thibault.aves.channel.calls.AppAdapterHandler import deckers.thibault.aves.channel.calls.AppAdapterHandler
@ -71,7 +72,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
} }
private fun requestMediaFileAccess() { private fun requestMediaFileAccess() {
val uris = (args["uris"] as List<*>?)?.mapNotNull { if (it is String) Uri.parse(it) else null } val uris = (args["uris"] as List<*>?)?.mapNotNull { if (it is String) it.toUri() else null }
val mimeTypes = (args["mimeTypes"] as List<*>?)?.mapNotNull { if (it is String) it else null } val mimeTypes = (args["mimeTypes"] as List<*>?)?.mapNotNull { if (it is String) it else null }
if (uris.isNullOrEmpty() || mimeTypes == null || mimeTypes.size != uris.size) { if (uris.isNullOrEmpty() || mimeTypes == null || mimeTypes.size != uris.size) {
error("requestMediaFileAccess-args", "missing arguments", null) error("requestMediaFileAccess-args", "missing arguments", null)
@ -190,7 +191,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
val intent = Intent(Intent.ACTION_EDIT) val intent = Intent(Intent.ACTION_EDIT)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
.setDataAndType(AppAdapterHandler.getShareableUri(activity, Uri.parse(uri)), mimeType) .setDataAndType(AppAdapterHandler.getShareableUri(activity, uri.toUri()), mimeType)
if (intent.resolveActivity(activity.packageManager) == null) { if (intent.resolveActivity(activity.packageManager) == null) {
error("edit-resolve", "cannot resolve activity for this intent for uri=$uri mimeType=$mimeType", null) error("edit-resolve", "cannot resolve activity for this intent for uri=$uri mimeType=$mimeType", null)

View file

@ -5,6 +5,7 @@ import android.net.Uri
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import androidx.core.net.toUri
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import deckers.thibault.aves.decoder.AvesAppGlideModule import deckers.thibault.aves.decoder.AvesAppGlideModule
import deckers.thibault.aves.utils.BitmapUtils.applyExifOrientation import deckers.thibault.aves.utils.BitmapUtils.applyExifOrientation
@ -80,7 +81,7 @@ class ImageByteStreamHandler(private val context: Context, private val arguments
} }
val mimeType = arguments["mimeType"] as String? val mimeType = arguments["mimeType"] as String?
val uri = (arguments["uri"] as String?)?.let { Uri.parse(it) } val uri = (arguments["uri"] as String?)?.toUri()
val sizeBytes = (arguments["sizeBytes"] as Number?)?.toLong() val sizeBytes = (arguments["sizeBytes"] as Number?)?.toLong()
val rotationDegrees = arguments["rotationDegrees"] as Int val rotationDegrees = arguments["rotationDegrees"] as Int
val isFlipped = arguments["isFlipped"] as Boolean val isFlipped = arguments["isFlipped"] as Boolean

View file

@ -1,9 +1,10 @@
package deckers.thibault.aves.model package deckers.thibault.aves.model
import android.net.Uri import android.net.Uri
import androidx.core.net.toUri
class AvesEntry(map: FieldMap) { class AvesEntry(map: FieldMap) {
val uri: Uri = Uri.parse(map["uri"] as String) // content or file URI val uri: Uri = (map["uri"] as String).toUri() // content or file URI
val path = map["path"] as String? // best effort to get local path val path = map["path"] as String? // best effort to get local path
val pageId = map["pageId"] as Int? // null means the main entry val pageId = map["pageId"] as Int? // null means the main entry
val mimeType = map["mimeType"] as String val mimeType = map["mimeType"] as String

View file

@ -29,6 +29,7 @@ import deckers.thibault.aves.utils.UriUtils.tryParseId
import org.beyka.tiffbitmapfactory.TiffBitmapFactory import org.beyka.tiffbitmapfactory.TiffBitmapFactory
import java.io.IOException import java.io.IOException
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
import androidx.core.net.toUri
class SourceEntry { class SourceEntry {
private val origin: Int private val origin: Int
@ -55,7 +56,7 @@ class SourceEntry {
constructor(map: FieldMap) { constructor(map: FieldMap) {
origin = map["origin"] as Int origin = map["origin"] as Int
uri = Uri.parse(map["uri"] as String) uri = (map["uri"] as String).toUri()
path = map["path"] as String? path = map["path"] as String?
sourceMimeType = map["sourceMimeType"] as String sourceMimeType = map["sourceMimeType"] as String
width = map["width"] as Int? width = map["width"] as Int?

View file

@ -29,6 +29,8 @@ import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.util.Locale import java.util.Locale
import java.util.regex.Pattern import java.util.regex.Pattern
import androidx.core.net.toUri
import androidx.core.text.isDigitsOnly
object StorageUtils { object StorageUtils {
private val LOG_TAG = LogUtils.createTag<StorageUtils>() private val LOG_TAG = LogUtils.createTag<StorageUtils>()
@ -228,7 +230,7 @@ object StorageUtils {
// Device has emulated storage; external storage paths should have userId burned into them. // Device has emulated storage; external storage paths should have userId burned into them.
// /storage/emulated/[0,1,2,...]/ // /storage/emulated/[0,1,2,...]/
val path = getPrimaryVolumePath(context) val path = getPrimaryVolumePath(context)
val rawUserId = path.split(File.separator).lastOrNull(String::isNotEmpty)?.takeIf { TextUtils.isDigitsOnly(it) } ?: "" val rawUserId = path.split(File.separator).lastOrNull(String::isNotEmpty)?.takeIf { it.isDigitsOnly() } ?: ""
if (rawUserId.isEmpty()) { if (rawUserId.isEmpty()) {
paths.add(rawEmulatedStorageTarget) paths.add(rawEmulatedStorageTarget)
} else { } else {
@ -637,7 +639,7 @@ object StorageUtils {
// strip user info, if any // strip user info, if any
// e.g. `content://0@media/...` // e.g. `content://0@media/...`
private fun stripMediaUriUserInfo(uri: Uri) = Uri.parse(uri.toString().replaceFirst("${uri.userInfo}@", "")) private fun stripMediaUriUserInfo(uri: Uri) = uri.toString().replaceFirst("${uri.userInfo}@", "").toUri()
fun openInputStream(context: Context, uri: Uri): InputStream? { fun openInputStream(context: Context, uri: Uri): InputStream? {
val effectiveUri = getOriginalUri(context, uri) val effectiveUri = getOriginalUri(context, uri)

View file