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 64cba6a9c..fb18fd93d 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt @@ -183,45 +183,45 @@ class MainActivity : FlutterActivity() { private fun extractIntentData(intent: Intent?): MutableMap { when (intent?.action) { Intent.ACTION_MAIN -> { - intent.getStringExtra("page")?.let { page -> - var filters = intent.getStringArrayExtra("filters")?.toList() + intent.getStringExtra(SHORTCUT_KEY_PAGE)?.let { page -> + var filters = intent.getStringArrayExtra(SHORTCUT_KEY_FILTERS_ARRAY)?.toList() if (filters == null) { // fallback for shortcuts created on API < 26 - val filterString = intent.getStringExtra("filtersString") + val filterString = intent.getStringExtra(SHORTCUT_KEY_FILTERS_STRING) if (filterString != null) { filters = filterString.split(EXTRA_STRING_ARRAY_SEPARATOR) } } return hashMapOf( - "page" to page, - "filters" to filters, + INTENT_DATA_KEY_PAGE to page, + INTENT_DATA_KEY_FILTERS to filters, ) } } Intent.ACTION_VIEW, Intent.ACTION_SEND, "com.android.camera.action.REVIEW" -> { (intent.data ?: (intent.getParcelableExtra(Intent.EXTRA_STREAM) as? Uri))?.let { uri -> return hashMapOf( - "action" to "view", - "uri" to uri.toString(), - "mimeType" to intent.type, // MIME type is optional + INTENT_DATA_KEY_ACTION to INTENT_ACTION_VIEW, + INTENT_DATA_KEY_MIME_TYPE to intent.type, // MIME type is optional + INTENT_DATA_KEY_URI to uri.toString(), ) } } Intent.ACTION_GET_CONTENT, Intent.ACTION_PICK -> { return hashMapOf( - "action" to "pick", - "mimeType" to intent.type, + INTENT_DATA_KEY_ACTION to INTENT_ACTION_PICK, + INTENT_DATA_KEY_MIME_TYPE to intent.type, ) } Intent.ACTION_SEARCH -> { val viewUri = intent.dataString return if (viewUri != null) hashMapOf( - "action" to "view", - "uri" to viewUri, - "mimeType" to intent.getStringExtra(SearchManager.EXTRA_DATA_KEY), + INTENT_DATA_KEY_ACTION to INTENT_ACTION_VIEW, + INTENT_DATA_KEY_MIME_TYPE to intent.getStringExtra(SearchManager.EXTRA_DATA_KEY), + INTENT_DATA_KEY_URI to viewUri, ) else hashMapOf( - "action" to "search", - "query" to intent.getStringExtra(SearchManager.QUERY), + INTENT_DATA_KEY_ACTION to INTENT_ACTION_SEARCH, + INTENT_DATA_KEY_QUERY to intent.getStringExtra(SearchManager.QUERY), ) } Intent.ACTION_RUN -> { @@ -261,7 +261,7 @@ class MainActivity : FlutterActivity() { .setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_search else R.drawable.ic_shortcut_search)) .setIntent( Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java) - .putExtra("page", "/search") + .putExtra(SHORTCUT_KEY_PAGE, "/search") ) .build() @@ -270,7 +270,7 @@ class MainActivity : FlutterActivity() { .setIcon(IconCompat.createWithResource(this, if (supportAdaptiveIcon) R.mipmap.ic_shortcut_movie else R.drawable.ic_shortcut_movie)) .setIntent( Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java) - .putExtra("page", "/collection") + .putExtra(SHORTCUT_KEY_PAGE, "/collection") .putExtra("filters", arrayOf("{\"type\":\"mime\",\"mime\":\"video/*\"}")) ) .build() @@ -294,6 +294,21 @@ class MainActivity : FlutterActivity() { const val DELETE_SINGLE_PERMISSION_REQUEST = 6 const val MEDIA_WRITE_BULK_PERMISSION_REQUEST = 7 + const val INTENT_DATA_KEY_ACTION = "action" + const val INTENT_DATA_KEY_FILTERS = "filters" + const val INTENT_DATA_KEY_MIME_TYPE = "mimeType" + const val INTENT_DATA_KEY_PAGE = "page" + const val INTENT_DATA_KEY_URI = "uri" + const val INTENT_DATA_KEY_QUERY = "query" + + const val INTENT_ACTION_PICK = "pick" + const val INTENT_ACTION_SEARCH = "search" + const val INTENT_ACTION_VIEW = "view" + + const val SHORTCUT_KEY_PAGE = "page" + const val SHORTCUT_KEY_FILTERS_ARRAY = "filters" + const val SHORTCUT_KEY_FILTERS_STRING = "filtersString" + // request code to pending runnable val pendingStorageAccessResultHandlers = ConcurrentHashMap() 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 2d8dfe057..8c7f0b9ad 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 @@ -18,6 +18,10 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.request.RequestOptions import deckers.thibault.aves.MainActivity +import deckers.thibault.aves.MainActivity.Companion.EXTRA_STRING_ARRAY_SEPARATOR +import deckers.thibault.aves.MainActivity.Companion.SHORTCUT_KEY_FILTERS_ARRAY +import deckers.thibault.aves.MainActivity.Companion.SHORTCUT_KEY_FILTERS_STRING +import deckers.thibault.aves.MainActivity.Companion.SHORTCUT_KEY_PAGE import deckers.thibault.aves.R import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend @@ -360,11 +364,11 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { val intent = when { uri != null -> Intent(Intent.ACTION_VIEW, uri, context, MainActivity::class.java) filters != null -> Intent(Intent.ACTION_MAIN, null, context, MainActivity::class.java) - .putExtra("page", "/collection") - .putExtra("filters", filters.toTypedArray()) + .putExtra(SHORTCUT_KEY_PAGE, "/collection") + .putExtra(SHORTCUT_KEY_FILTERS_ARRAY, filters.toTypedArray()) // on API 25, `String[]` or `ArrayList` extras are null when using the shortcut // so we use a joined `String` as fallback - .putExtra("filtersString", filters.joinToString(MainActivity.EXTRA_STRING_ARRAY_SEPARATOR)) + .putExtra(SHORTCUT_KEY_FILTERS_STRING, filters.joinToString(EXTRA_STRING_ARRAY_SEPARATOR)) else -> { result.error("pin-intent", "failed to build intent", null) return diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index bd533fb9b..f04182b61 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -79,7 +79,7 @@ class _HomePageState extends State { final intentData = widget.intentData ?? await ViewerService.getIntentData(); if (intentData.isNotEmpty) { final action = intentData['action']; - await reportService.log('Intent action=$action'); + await reportService.log('Intent data=$intentData'); switch (action) { case 'view': _viewerEntry = await _initViewerEntry( @@ -133,6 +133,10 @@ class _HomePageState extends State { } Future _initViewerEntry({required String uri, required String? mimeType}) async { + if (uri.startsWith('/')) { + // convert this file path to a proper URI + uri = Uri.file(uri).toString(); + } final entry = await mediaFileService.getEntry(uri, mimeType); if (entry != null) { // cataloguing is essential for coordinates and video rotation