From 695ad7f77cd828cbc5d72117a4c2493d5696a23c Mon Sep 17 00:00:00 2001 From: Dereck Bridie Date: Thu, 2 Oct 2025 14:44:12 +0200 Subject: [PATCH] Fix exception when attempting to load launch a PickVisualMediaRequest with no applicable activities --- .../androidify/creation/CreationScreen.kt | 9 +++++---- .../androidify/creation/CreationViewModel.kt | 18 ++++++++++++++++++ .../androidify/creation/EditScreen.kt | 3 +-- .../androidify/creation/EditScreenCompact.kt | 7 ++----- .../androidify/creation/EditScreenMedium.kt | 7 ++----- .../creation/xr/EditScreenSpatial.kt | 7 ++----- .../creation/src/main/res/values/strings.xml | 1 + 7 files changed, 31 insertions(+), 21 deletions(-) diff --git a/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationScreen.kt b/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationScreen.kt index 20bcb055..be7d6c8d 100644 --- a/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationScreen.kt +++ b/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationScreen.kt @@ -25,7 +25,6 @@ package com.android.developers.androidify.creation import android.net.Uri import androidx.activity.compose.BackHandler import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.foundation.layout.ExperimentalLayoutApi @@ -52,12 +51,12 @@ fun CreationScreen( ) { creationViewModel.onBackPress() } - val pickMedia = rememberLauncherForActivityResult(PickVisualMedia()) { uri -> + val snackbarHostState by creationViewModel.snackbarHostState.collectAsStateWithLifecycle() + val launcher = rememberLauncherForActivityResult(PickVisualMedia()) { uri -> if (uri != null) { creationViewModel.onImageSelected(uri) } } - val snackbarHostState by creationViewModel.snackbarHostState.collectAsStateWithLifecycle() LaunchedEffect(uiState.resultBitmapUri) { uiState.resultBitmapUri?.let { resultBitmapUri -> @@ -84,7 +83,9 @@ fun CreationScreen( onBackPressed = onBackPressed, onAboutPressed = onAboutPressed, uiState = uiState, - onChooseImageClicked = { pickMedia.launch(PickVisualMediaRequest(it)) }, + onChooseImageClicked = { + creationViewModel.launchImageChooser(launcher) + }, onPromptOptionSelected = creationViewModel::onSelectedPromptOptionChanged, onUndoPressed = creationViewModel::onUndoPressed, onPromptGenerationPressed = creationViewModel::onPromptGenerationClicked, diff --git a/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationViewModel.kt b/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationViewModel.kt index 22532bb2..966c7428 100644 --- a/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationViewModel.kt +++ b/feature/creation/src/main/java/com/android/developers/androidify/creation/CreationViewModel.kt @@ -17,6 +17,9 @@ package com.android.developers.androidify.creation import android.content.Context import android.net.Uri +import androidx.activity.compose.ManagedActivityResultLauncher +import androidx.activity.result.PickVisualMediaRequest +import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.material3.SnackbarHostState import androidx.compose.ui.graphics.Color @@ -93,6 +96,15 @@ class CreationViewModel @AssistedInject constructor( } } + fun launchImageChooser(launcher: ManagedActivityResultLauncher) { + try { + launcher.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly)) + } catch (exception: Exception) { + Timber.e(exception, "Failed to open the visual media picker") + displayOpenImageChooserError() + } + } + fun onBotColorChanged(botColor: BotColor) { _uiState.update { it.copy(botColor = botColor) @@ -132,6 +144,12 @@ class CreationViewModel @AssistedInject constructor( } } + fun displayOpenImageChooserError() { + viewModelScope.launch { + _snackbarHostState.value.showSnackbar(context.getString(R.string.error_open_visual_media_picker)) + } + } + fun startClicked() { imageGenerationJob?.cancel() imageGenerationJob = viewModelScope.launch { diff --git a/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreen.kt b/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreen.kt index 333caee1..b6b92691 100644 --- a/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreen.kt +++ b/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreen.kt @@ -24,7 +24,6 @@ package com.android.developers.androidify.creation import android.net.Uri import androidx.activity.ComponentActivity -import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.ExperimentalLayoutApi @@ -67,7 +66,7 @@ fun EditScreen( onBackPressed: () -> Unit, onAboutPressed: () -> Unit, uiState: CreationState, - onChooseImageClicked: (PickVisualMedia.VisualMediaType) -> Unit, + onChooseImageClicked: () -> Unit, onPromptOptionSelected: (PromptType) -> Unit, onUndoPressed: () -> Unit, onPromptGenerationPressed: () -> Unit, diff --git a/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenCompact.kt b/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenCompact.kt index dd11a2d8..4f4dac65 100644 --- a/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenCompact.kt +++ b/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenCompact.kt @@ -23,7 +23,6 @@ package com.android.developers.androidify.creation import android.net.Uri -import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement @@ -71,7 +70,7 @@ fun EditScreenContentsCompact( dropBehaviourFactory: DropBehaviourFactory, onCameraPressed: () -> Unit, uiState: CreationState, - onChooseImageClicked: (PickVisualMedia.VisualMediaType) -> Unit, + onChooseImageClicked: () -> Unit, onPromptOptionSelected: (PromptType) -> Unit, onUndoPressed: () -> Unit, onPromptGenerationPressed: () -> Unit, @@ -97,9 +96,7 @@ fun EditScreenContentsCompact( dropBehaviourFactory = dropBehaviourFactory, modifier = Modifier.weight(1f), onCameraPressed = onCameraPressed, - onChooseImageClicked = { - onChooseImageClicked(PickVisualMedia.ImageOnly) - }, + onChooseImageClicked = onChooseImageClicked, onUndoPressed = onUndoPressed, onPromptGenerationPressed = onPromptGenerationPressed, onSelectedPromptOptionChanged = onPromptOptionSelected, diff --git a/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenMedium.kt b/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenMedium.kt index 6c6e9c64..623cbc16 100644 --- a/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenMedium.kt +++ b/feature/creation/src/main/java/com/android/developers/androidify/creation/EditScreenMedium.kt @@ -23,7 +23,6 @@ package com.android.developers.androidify.creation import android.net.Uri -import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -56,7 +55,7 @@ fun EditScreenContentsMedium( dropBehaviourFactory: DropBehaviourFactory, onCameraPressed: () -> Unit, uiState: CreationState, - onChooseImageClicked: (PickVisualMedia.VisualMediaType) -> Unit, + onChooseImageClicked: () -> Unit, onPromptOptionSelected: (PromptType) -> Unit, onUndoPressed: () -> Unit, onPromptGenerationPressed: () -> Unit, @@ -79,9 +78,7 @@ fun EditScreenContentsMedium( dropBehaviourFactory = dropBehaviourFactory, modifier = Modifier.weight(.6f), onCameraPressed = onCameraPressed, - onChooseImageClicked = { - onChooseImageClicked(PickVisualMedia.ImageOnly) - }, + onChooseImageClicked = onChooseImageClicked, onUndoPressed = onUndoPressed, onPromptGenerationPressed = onPromptGenerationPressed, onSelectedPromptOptionChanged = onPromptOptionSelected, diff --git a/feature/creation/src/main/java/com/android/developers/androidify/creation/xr/EditScreenSpatial.kt b/feature/creation/src/main/java/com/android/developers/androidify/creation/xr/EditScreenSpatial.kt index 6eaa5be9..46f13167 100644 --- a/feature/creation/src/main/java/com/android/developers/androidify/creation/xr/EditScreenSpatial.kt +++ b/feature/creation/src/main/java/com/android/developers/androidify/creation/xr/EditScreenSpatial.kt @@ -16,7 +16,6 @@ package com.android.developers.androidify.creation.xr import android.net.Uri -import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -66,7 +65,7 @@ fun EditScreenSpatial( onAboutPressed: () -> Unit, uiState: CreationState, snackbarHostState: SnackbarHostState, - onChooseImageClicked: (PickVisualMedia.VisualMediaType) -> Unit, + onChooseImageClicked: () -> Unit, onPromptOptionSelected: (PromptType) -> Unit, onUndoPressed: () -> Unit, onPromptGenerationPressed: () -> Unit, @@ -131,9 +130,7 @@ fun EditScreenSpatial( uiState = uiState, dropBehaviourFactory = dropBehaviourFactory, onCameraPressed = onCameraPressed, - onChooseImageClicked = { - onChooseImageClicked(PickVisualMedia.ImageOnly) - }, + onChooseImageClicked = onChooseImageClicked, onUndoPressed = onUndoPressed, onPromptGenerationPressed = onPromptGenerationPressed, onSelectedPromptOptionChanged = onPromptOptionSelected, diff --git a/feature/creation/src/main/res/values/strings.xml b/feature/creation/src/main/res/values/strings.xml index 2b9d12b0..c98eeb9f 100644 --- a/feature/creation/src/main/res/values/strings.xml +++ b/feature/creation/src/main/res/values/strings.xml @@ -77,6 +77,7 @@ An error occurred whilst uploading, try again later. The image is not a valid picture of a person. Choose an image or use a prompt instead. + An error occurred whilst opening the media picker. Oh, this one is going to be nice… Now… onto the spray paint