diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt index 103a27901..4464594b5 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt @@ -8,7 +8,6 @@ import android.content.Intent import android.content.res.Configuration import android.content.res.Resources import android.graphics.Bitmap -import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Handler @@ -16,6 +15,7 @@ import android.os.Looper import android.util.Log import android.util.SizeF import android.widget.RemoteViews +import androidx.core.net.toUri import app.loup.streams_channel.StreamsChannel import deckers.thibault.aves.channel.AvesByteSendingMethodCodec import deckers.thibault.aves.channel.calls.DeviceHandler @@ -260,7 +260,7 @@ class HomeWidgetProvider : AppWidgetProvider() { } 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)) return PendingIntent.getBroadcast( @@ -277,7 +277,7 @@ class HomeWidgetProvider : AppWidgetProvider() { 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 - 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) return PendingIntent.getActivity( diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt index aa65da1c0..a0ef419ae 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt @@ -69,6 +69,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import java.util.concurrent.CompletableFuture import java.util.concurrent.ConcurrentHashMap +import androidx.core.net.toUri // `FlutterFragmentActivity` because of local auth plugin open class MainActivity : FlutterFragmentActivity() { @@ -442,7 +443,7 @@ open class MainActivity : FlutterFragmentActivity() { 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 firstUri = toUri(pickedUris.first()) if (pickedUris.size == 1) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/WallpaperActivity.kt b/android/app/src/main/kotlin/deckers/thibault/aves/WallpaperActivity.kt index 067ee8e34..c1d634fcc 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/WallpaperActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/WallpaperActivity.kt @@ -7,6 +7,7 @@ import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.utils.getParcelableExtraCompat import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel +import androidx.core.net.toUri class WallpaperActivity : MainActivity() { private var originalIntent: String? = null @@ -39,7 +40,7 @@ class WallpaperActivity : MainActivity() { if (originalIntent != null) { val pickedUris = call.argument>("uris") 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 { action = originalIntent data = toUri(pickedUris.first()) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt index 7825e084f..577711d68 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt @@ -19,6 +19,7 @@ import androidx.core.content.FileProvider import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.IconCompat +import androidx.core.net.toUri import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat 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) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val label = call.argument("label") if (uri == 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) { val title = call.argument("title") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val mimeType = call.argument("mimeType") val forceChooser = call.argument("forceChooser") if (uri == null || forceChooser == null) { @@ -236,7 +237,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { } private fun openMap(call: MethodCall, result: MethodChannel.Result) { - val geoUri = call.argument("geoUri")?.let { Uri.parse(it) } + val geoUri = call.argument("geoUri")?.toUri() if (geoUri == null) { result.error("openMap-args", "missing arguments", null) return @@ -250,7 +251,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { private fun setAs(call: MethodCall, result: MethodChannel.Result) { val title = call.argument("title") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val mimeType = call.argument("mimeType") if (uri == null) { result.error("setAs-args", "missing arguments", null) @@ -273,7 +274,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { 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() // 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 val filters = call.argument>("filters") val explorerPath = call.argument("path") - val viewUri = call.argument("viewUri")?.let { Uri.parse(it) } - val geoUri = call.argument("geoUri")?.let { Uri.parse(it) } + val viewUri = call.argument("viewUri")?.toUri() + val geoUri = call.argument("geoUri")?.toUri() if (label == null || route == null) { result.error("pin-args", "missing arguments", null) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt index ab8e20783..9282ba2be 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt @@ -12,6 +12,7 @@ import android.os.Handler import android.os.Looper import android.provider.MediaStore import android.util.Log +import androidx.core.net.toUri import com.drew.metadata.file.FileTypeDirectory import deckers.thibault.aves.channel.calls.Coresult.Companion.safe 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) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() if (uri == null) { result.error("getBitmapDecoderInfo-args", "missing arguments", null) return @@ -156,7 +157,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler { private fun getContentResolverMetadata(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() if (mimeType == null || uri == null) { result.error("getContentResolverMetadata-args", "missing arguments", null) return @@ -212,7 +213,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler { private fun getExifInterfaceMetadata(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == 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) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() if (uri == null) { result.error("getMediaMetadataRetrieverMetadata-args", "missing arguments", null) return @@ -264,7 +265,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler { private fun getMetadataExtractorSummary(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() if (mimeType == null || uri == null) { result.error("getMp4ParserDump-args", "missing arguments", null) return @@ -338,7 +339,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler { private fun getPixyMetadata(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() if (mimeType == null || uri == null) { result.error("getPixyMetadata-args", "missing arguments", null) return @@ -359,7 +360,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler { } private fun getTiffStructure(call: MethodCall, result: MethodChannel.Result) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() if (uri == null) { result.error("getTiffStructure-args", "missing arguments", null) return diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt index e6130d087..e34031033 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt @@ -6,12 +6,12 @@ import android.content.Context import android.content.Intent import android.content.res.Resources import android.location.Geocoder -import android.net.Uri import android.os.Build import android.os.LocaleList import android.provider.MediaStore import android.provider.Settings import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.net.toUri import com.google.android.material.color.DynamicColors import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.model.FieldMap @@ -129,7 +129,7 @@ class DeviceHandler(private val context: Context) : MethodCallHandler { 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) result.success(true) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt index 5ac512f91..a78187539 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt @@ -1,9 +1,9 @@ package deckers.thibault.aves.channel.calls import android.content.Context -import android.net.Uri import android.util.Log import androidx.core.content.FileProvider +import androidx.core.net.toUri import androidx.exifinterface.media.ExifInterface import com.adobe.internal.xmp.XMPException 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val displayName = call.argument("displayName") val dataUri = call.argument("dataUri") @@ -143,7 +143,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { private fun extractJpegMpfItem(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val displayName = call.argument("displayName") val id = call.argument("id") @@ -177,7 +177,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { private fun extractMotionPhotoImage(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val displayName = call.argument("displayName") 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val displayName = call.argument("displayName") 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) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val displayName = call.argument("displayName") if (uri == 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val displayName = call.argument("displayName") val dataProp = call.argument>("propPath") diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt index 9e40b4199..4f48d7383 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt @@ -1,8 +1,8 @@ package deckers.thibault.aves.channel.calls import android.content.ContextWrapper -import android.net.Uri 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.safeSuspend 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) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val desiredName = call.argument("desiredName") val exifFields = call.argument("exif") ?: HashMap() val bytes = call.argument("bytes") diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchBytesHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchBytesHandler.kt index 8012e7d7a..70daf5c04 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchBytesHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchBytesHandler.kt @@ -2,7 +2,7 @@ package deckers.thibault.aves.channel.calls import android.content.Context 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.fetchers.RegionFetcher 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) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val mimeType = call.argument("mimeType") val pageId = call.argument("pageId") val sizeBytes = call.argument("sizeBytes")?.toLong() diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt index be5696a03..4f0a501f8 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt @@ -1,7 +1,7 @@ package deckers.thibault.aves.channel.calls import android.content.Context -import android.net.Uri +import androidx.core.net.toUri import com.bumptech.glide.Glide import deckers.thibault.aves.channel.calls.Coresult.Companion.safe 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) { val mimeType = call.argument("mimeType") // MIME type is optional - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val allowUnsized = call.argument("allowUnsized") ?: false if (uri == null) { result.error("getEntry-args", "missing arguments", null) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaSessionHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaSessionHandler.kt index e336cd28f..8c42f646c 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaSessionHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaSessionHandler.kt @@ -7,10 +7,10 @@ import android.content.Intent import android.content.IntentFilter import android.media.AudioManager import android.media.session.PlaybackState -import android.net.Uri import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.PlaybackStateCompat +import androidx.core.net.toUri import androidx.media.session.MediaButtonReceiver import deckers.thibault.aves.channel.calls.Coresult.Companion.safe 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) { - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val title = call.argument("title") ?: uri?.toString() val durationMillis = call.argument("durationMillis")?.toLong() val stateString = call.argument("state") diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt index 36ac14ff2..470fc200c 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt @@ -1,7 +1,7 @@ package deckers.thibault.aves.channel.calls 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.metadata.Mp4TooLargeException import deckers.thibault.aves.model.ExifOrientationOp @@ -54,7 +54,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa 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 mimeType = entryMap["mimeType"] as String? if (uri == null || path == null || mimeType == null) { @@ -82,7 +82,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa 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 mimeType = entryMap["mimeType"] as String? if (uri == null || path == null || mimeType == null) { @@ -109,7 +109,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa 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 mimeType = entryMap["mimeType"] as String? if (uri == null || path == null || mimeType == null) { @@ -134,7 +134,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa 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 mimeType = entryMap["mimeType"] as String? if (uri == null || path == null || mimeType == null) { @@ -160,7 +160,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa 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 mimeType = entryMap["mimeType"] as String? if (uri == null || path == null || mimeType == null) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt index 98de3e4e0..27aed4bab 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt @@ -107,6 +107,7 @@ import java.util.Locale import kotlin.math.roundToInt import kotlin.math.roundToLong import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface +import androidx.core.net.toUri class MetadataFetchHandler(private val context: Context) : MethodCallHandler { 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == null) { result.error("getAllMetadata-args", "missing arguments", null) @@ -516,7 +517,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { // - XMP / MicrosoftPhoto:Rating private fun getCatalogMetadata(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val path = call.argument("path") val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == null) { @@ -869,7 +870,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { private fun getOverlayMetadata(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val fields = call.argument>("fields") 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val isMotionPhoto = call.argument("isMotionPhoto") 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() if (mimeType == null || uri == null) { result.error("getIptc-args", "missing arguments", null) return @@ -1146,7 +1147,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { // return an empty list if there is no XMP private fun getXmp(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() if (mimeType == null || uri == 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val prop = call.argument("prop") if (mimeType == null || uri == null || prop == 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val field = call.argument("field") 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) { val mimeType = call.argument("mimeType") - val uri = call.argument("uri")?.let { Uri.parse(it) } + val uri = call.argument("uri")?.toUri() val sizeBytes = call.argument("sizeBytes")?.toLong() val fields = call.argument>("fields") if (mimeType == null || uri == null || fields == null) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt index 3d57f38fc..5d7c4e6b6 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt @@ -24,6 +24,7 @@ import deckers.thibault.aves.utils.MimeTypes.needRotationAfterGlide import deckers.thibault.aves.utils.StorageUtils import deckers.thibault.aves.utils.UriUtils.tryParseId import io.flutter.plugin.common.MethodChannel +import androidx.core.net.toUri class ThumbnailFetcher internal constructor( private val context: Context, @@ -39,7 +40,7 @@ class ThumbnailFetcher internal constructor( private val quality: Int, 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 height: Int = if (height?.takeIf { it > 0 } != null) height else defaultSize private val svgFetch = mimeType == SVG diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt index 29005f9ae..7fcc607f7 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt @@ -7,6 +7,7 @@ import android.os.Build import android.os.Handler import android.os.Looper import android.util.Log +import androidx.core.net.toUri import deckers.thibault.aves.MainActivity import deckers.thibault.aves.PendingStorageAccessResultHandler import deckers.thibault.aves.channel.calls.AppAdapterHandler @@ -71,7 +72,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any } 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 } if (uris.isNullOrEmpty() || mimeTypes == null || mimeTypes.size != uris.size) { error("requestMediaFileAccess-args", "missing arguments", null) @@ -190,7 +191,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any val intent = Intent(Intent.ACTION_EDIT) .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) { error("edit-resolve", "cannot resolve activity for this intent for uri=$uri mimeType=$mimeType", null) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt index a0b033c3c..33ec694b1 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt @@ -5,6 +5,7 @@ import android.net.Uri import android.os.Handler import android.os.Looper import android.util.Log +import androidx.core.net.toUri import com.bumptech.glide.Glide import deckers.thibault.aves.decoder.AvesAppGlideModule 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 uri = (arguments["uri"] as String?)?.let { Uri.parse(it) } + val uri = (arguments["uri"] as String?)?.toUri() val sizeBytes = (arguments["sizeBytes"] as Number?)?.toLong() val rotationDegrees = arguments["rotationDegrees"] as Int val isFlipped = arguments["isFlipped"] as Boolean diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/AvesEntry.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/AvesEntry.kt index 8d41846ab..61adec2a4 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/AvesEntry.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/AvesEntry.kt @@ -1,9 +1,10 @@ package deckers.thibault.aves.model import android.net.Uri +import androidx.core.net.toUri 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 pageId = map["pageId"] as Int? // null means the main entry val mimeType = map["mimeType"] as String diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt index 37c49accd..7ebe01d36 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt @@ -29,6 +29,7 @@ import deckers.thibault.aves.utils.UriUtils.tryParseId import org.beyka.tiffbitmapfactory.TiffBitmapFactory import java.io.IOException import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface +import androidx.core.net.toUri class SourceEntry { private val origin: Int @@ -55,7 +56,7 @@ class SourceEntry { constructor(map: FieldMap) { origin = map["origin"] as Int - uri = Uri.parse(map["uri"] as String) + uri = (map["uri"] as String).toUri() path = map["path"] as String? sourceMimeType = map["sourceMimeType"] as String width = map["width"] as Int? diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt index c05ab4808..2aff05cea 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt @@ -29,6 +29,8 @@ import java.io.InputStream import java.io.OutputStream import java.util.Locale import java.util.regex.Pattern +import androidx.core.net.toUri +import androidx.core.text.isDigitsOnly object StorageUtils { private val LOG_TAG = LogUtils.createTag() @@ -228,7 +230,7 @@ object StorageUtils { // Device has emulated storage; external storage paths should have userId burned into them. // /storage/emulated/[0,1,2,...]/ 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()) { paths.add(rawEmulatedStorageTarget) } else { @@ -637,7 +639,7 @@ object StorageUtils { // strip user info, if any // 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? { val effectiveUri = getOriginalUri(context, uri) diff --git a/lib/model/entry/extensions/keys.dart b/lib/model/entry/extensions/keys.dart new file mode 100644 index 000000000..e69de29bb