Prepare to boost your app’s consumer expertise with an thrilling new approach to make use of the Android photograph picker! The brand new embedded photograph picker gives a seamless and privacy-focused approach for customers to pick out pictures and movies, proper inside your app’s interface. Now your app can get all the identical advantages obtainable with the photograph picker, together with entry to cloud content material, built-in immediately into your app’s expertise.
Why embedded?
We perceive that many apps need to present a extremely built-in and seamless expertise for customers when deciding on pictures or movies. The embedded photograph picker is designed to do exactly that, permitting customers to shortly entry their current pictures with out ever leaving your app. They will additionally discover their full library of their most popular cloud media supplier (e.g., Google Pictures), together with favorites, albums and search performance. This eliminates the necessity for customers to modify between apps or fear about whether or not the photograph they need is saved regionally or within the cloud.
Seamless integration, enhanced privateness
With the embedded photograph picker, your app does not want entry to the consumer’s pictures or movies till they really choose one thing. This implies better privateness to your customers and a extra streamlined expertise. Plus, the embedded photograph picker offers customers with entry to their whole cloud-based media library, whereas the usual photograph permission is restricted to native information solely.
The embedded photograph picker in Google Messages
Google Messages showcases the ability of the embedded photograph picker. This is how they’ve built-in it:
- Intuitive placement: The photograph picker sits proper under the digicam button, giving customers a transparent alternative between capturing a brand new photograph or deciding on an present one.
- Dynamic preview: Instantly after a consumer faucets a photograph, they see a big preview, making it simple to substantiate their choice. In the event that they deselect the photograph, the preview disappears, protecting the expertise clear and uncluttered.
- Broaden for extra content material: The preliminary view is simplified, providing easy accessibility to current pictures. Nonetheless, customers can simply broaden the photograph picker to browse and select from all pictures and movies of their library, together with cloud content material from Google Pictures.
- Respecting consumer decisions: The embedded photograph picker solely grants entry to the particular pictures or movies the consumer selects, that means they will cease requesting the photograph and video permissions altogether. This additionally saves the Messages from needing to deal with conditions the place customers solely grant restricted entry to pictures and movies.
Implementation
Integrating the embedded photograph picker is made simple with the Photograph Picker Jetpack library.
Jetpack Compose
First, embody the Jetpack Photograph Picker library as a dependency.implementation("androidx.photopicker:photopicker-compose:1.0.0-alpha01")
The EmbeddedPhotoPicker composable operate offers a mechanism to incorporate the embedded photograph picker UI immediately inside your Compose display screen. This composable creates a SurfaceView which hosts the embedded photograph picker UI. It manages the connection to the EmbeddedPhotoPicker service, handles consumer interactions, and communicates chosen media URIs to the calling utility.
@Composable enjoyable EmbeddedPhotoPickerDemo() { // We hold observe of the listing of chosen attachments var attachments by bear in mind { mutableStateOf(emptyList<Uri>()) } val coroutineScope = rememberCoroutineScope() // We conceal the underside sheet by default however we present it when the consumer clicks on the button val scaffoldState = rememberBottomSheetScaffoldState( bottomSheetState = rememberStandardBottomSheetState( initialValue = SheetValue.Hidden, skipHiddenState = false ) ) // Customise the embedded photograph picker val photoPickerInfo = EmbeddedPhotoPickerFeatureInfo .Builder() // Set restrict the choice to five gadgets .setMaxSelectionLimit(5) // Order the gadgets choice (every merchandise could have an index seen within the photograph picker) .setOrderedSelection(true) // Set the accent coloration (purple on this case, in any other case it follows the gadget's accent coloration) .setAccentColor(0xFF0000) .construct() // The embedded photograph picker state might be saved on this variable val photoPickerState = rememberEmbeddedPhotoPickerState( onSelectionComplete = { coroutineScope.launch { // Disguise the underside sheet as soon as the consumer has clicked on the carried out button contained in the picker scaffoldState.bottomSheetState.conceal() } }, onUriPermissionGranted = { // We replace our listing of attachments with the brand new Uris granted attachments += it }, onUriPermissionRevoked = { // We replace our listing of attachments with the Uris revoked attachments -= it } ) SideEffect { val isExpanded = scaffoldState.bottomSheetState.targetValue == SheetValue.Expanded // We present/conceal the embedded photograph picker to match the underside sheet state photoPickerState.setCurrentExpanded(isExpanded) } BottomSheetScaffold( topBar = { TopAppBar(title = { Textual content("Embedded Photograph Picker demo") }) }, scaffoldState = scaffoldState, sheetPeekHeight = if (scaffoldState.bottomSheetState.isVisible) 400.dp else 0.dp, sheetContent = { Column(Modifier.fillMaxWidth()) { // We render the embedded photograph picker inside the underside sheet EmbeddedPhotoPicker( state = photoPickerState, embeddedPhotoPickerFeatureInfo = photoPickerInfo ) } } ) { innerPadding -> Column(Modifier.padding(innerPadding).fillMaxSize().padding(horizontal = 16.dp)) { Button(onClick = { coroutineScope.launch { // We broaden the underside sheet, which is able to set off the embedded picker to be proven scaffoldState.bottomSheetState.partialExpand() } }) { Textual content("Open photograph picker") } LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 64.dp)) { // We render the picture utilizing the Coil library itemsIndexed(attachments) { index, uri -> AsyncImage( mannequin = uri, contentDescription = "Picture ${index + 1}", contentScale = ContentScale.Crop, modifier = Modifier.clickable { coroutineScope.launch { // When the consumer clicks on the media from the app's UI, we deselect it // from the embedded photograph picker by calling the strategy deselectUri photoPickerState.deselectUri(uri) } } ) } } } } }
Views
implementation("androidx.photopicker:photopicker:1.0.0-alpha01")
So as to add the embedded photograph picker, that you must add an entry to your structure file.
<view class="androidx.photopicker.EmbeddedPhotoPickerView" android:id="@+id/photopicker" android:layout_width="match_parent" android:layout_height="match_parent" />
And initialize it in your exercise/fragment.
// We hold observe of the listing of chosen attachments non-public val _attachments = MutableStateFlow(emptyList<Uri>()) val attachments = _attachments.asStateFlow() non-public lateinit var picker: EmbeddedPhotoPickerView non-public var openSession: EmbeddedPhotoPickerSession? = null val pickerListener = object EmbeddedPhotoPickerStateChangeListener { override enjoyable onSessionOpened (newSession: EmbeddedPhotoPickerSession) { openSession = newSession } override enjoyable onSessionError (throwable: Throwable) {} override enjoyable onUriPermissionGranted(uris: Listing<Uri>) { _attachments += uris } override enjoyable onUriPermissionRevoked (uris: Listing<Uri>) { _attachments -= uris } override enjoyable onSelectionComplete() { // Disguise the embedded photograph picker because the consumer is completed with the photograph/video choice } } override enjoyable onCreate(savedInstanceState: Bundle?) { tremendous.onCreate(savedInstanceState) setContentView(R.structure.main_view) // // Add the embedded photograph picker to a backside sheet to permit the dragging to show the total photograph library // picker = findViewById(R.id.photopicker) picker.addEmbeddedPhotoPickerStateChangeListener(pickerListener) picker.setEmbeddedPhotoPickerFeatureInfo( // Set a customized accent coloration EmbeddedPhotoPickerFeatureInfo.Builder().setAccentColor(0xFF0000).construct() ) }
You possibly can name completely different strategies of EmbeddedPhotoPickerSession to work together with the embedded picker.
// Notify the embedded picker of a configuration change openSession.notifyConfigurationChanged(newConfig) // Replace the embedded picker to broaden following a consumer interplay openSession.notifyPhotoPickerExpanded(/* expanded: */ true) // Resize the embedded picker openSession.notifyResized(/* width: */ 512, /* top: */ 256) // Present/conceal the embedded picker (after a type has been submitted) openSession.notifyVisibilityChanged(/* seen: */ false) // Take away unselected media from the embedded picker after they've been // unselected from the host app's UI openSession.requestRevokeUriPermission(removedUris)
For enhanced consumer privateness and safety, the system renders the embedded photograph picker in a approach that forestalls any drawing or overlaying. This intentional design alternative implies that your UX ought to contemplate the photograph picker’s show space as a definite and devoted ingredient, very similar to you’d plan for an promoting banner.
When you have any suggestions or strategies, submit tickets to our
challenge tracker.

