[HTML payload içeriği buraya]
29.3 C
Jakarta
Monday, May 11, 2026

Android Builders Weblog: The Embedded Picture Picker


The Embedded Picture Picker: A extra seamless strategy to privately request photographs and movies in your app

Prepare to reinforce your app’s person expertise with an thrilling new approach to make use of the Android photograph picker! The brand new embedded photograph picker presents a seamless and privacy-focused approach for customers to pick out photographs and movies, proper inside your app’s interface. Now your app can get all the identical advantages out there 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 photographs or movies. The embedded photograph picker is designed to do exactly that, permitting customers to shortly entry their latest photographs with out ever leaving your app. They will additionally discover their full library of their most popular cloud media supplier (e.g., Google Photographs), together with favorites, albums and search performance. This eliminates the necessity for customers to change between apps or fear about whether or not the photograph they need is saved domestically or within the cloud.

Seamless integration, enhanced privateness

With the embedded photograph picker, your app does not want entry to the person’s photographs or movies till they really choose one thing. This implies better privateness on your customers and a extra streamlined expertise. Plus, the embedded photograph picker supplies customers with entry to their complete cloud-based media library, whereas the usual photograph permission is restricted to native recordsdata solely.

The embedded photograph picker in Google Messages

Google Messages showcases the ability of the embedded photograph picker. Here 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 person faucets a photograph, they see a big preview, making it straightforward to substantiate their choice. In the event that they deselect the photograph, the preview disappears, holding the expertise clear and uncluttered.
  • Develop for extra content material: The preliminary view is simplified, providing quick access to latest photographs. Nevertheless, customers can simply increase the photograph picker to browse and select from all photographs and movies of their library, together with cloud content material from Google Photographs.
  • Respecting person decisions: The embedded photograph picker solely grants entry to the precise photographs or movies the person selects, which means they’ll 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 photographs and movies.

Implementation

Integrating the embedded photograph picker is made straightforward with the Picture Picker Jetpack library.  

Jetpack Compose

First, embrace the Jetpack Picture Picker library as a dependency.

implementation("androidx.photopicker:photopicker-compose:1.0.0-alpha01")

The EmbeddedPhotoPicker composable perform supplies a mechanism to incorporate the embedded photograph picker UI immediately inside your Compose display. This composable creates a SurfaceView which hosts the embedded photograph picker UI. It manages the connection to the EmbeddedPhotoPicker service, handles person interactions, and communicates chosen media URIs to the calling utility. 

@Composable
enjoyable EmbeddedPhotoPickerDemo() {
    // We hold monitor of the record of chosen attachments
    var attachments by keep in mind { mutableStateOf(emptyList<Uri>()) }

    val coroutineScope = rememberCoroutineScope()
    // We cover the underside sheet by default however we present it when the person 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 colour (purple on this case, in any other case it follows the machine's accent colour)
        .setAccentColor(0xFF0000)
        .construct()

    // The embedded photograph picker state will likely be saved on this variable
    val photoPickerState = rememberEmbeddedPhotoPickerState(
        onSelectionComplete = {
            coroutineScope.launch {
                // Cover the underside sheet as soon as the person has clicked on the achieved button contained in the picker
                scaffoldState.bottomSheetState.cover()
            }
        },
        onUriPermissionGranted = {
            // We replace our record of attachments with the brand new Uris granted
            attachments += it
        },
        onUriPermissionRevoked = {
            // We replace our record of attachments with the Uris revoked
            attachments -= it
        }
    )

       SideEffect {
        val isExpanded = scaffoldState.bottomSheetState.targetValue == SheetValue.Expanded

        // We present/cover the embedded photograph picker to match the underside sheet state
        photoPickerState.setCurrentExpanded(isExpanded)
    }

    BottomSheetScaffold(
        topBar = {
            TopAppBar(title = { Textual content("Embedded Picture 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 increase 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 person clicks on the media from the app's UI, we deselect it
                                // from the embedded photograph picker by calling the tactic deselectUri
                                photoPickerState.deselectUri(uri)
                            }
                        }
                    )
                }
            }
        }
    }
}

Views

First, embrace the Jetpack Picture Picker library as a dependency.

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 monitor of the record 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: Checklist<Uri>) {
        _attachments += uris
    }

    override enjoyable onUriPermissionRevoked (uris: Checklist<Uri>) {
        _attachments -= uris
    }

    override enjoyable onSelectionComplete() {
        // Cover the embedded photograph picker because the person 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 colour
        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 increase following a person interplay
openSession.notifyPhotoPickerExpanded(/* expanded: */ true)

// Resize the embedded picker
openSession.notifyResized(/* width: */ 512, /* peak: */ 256)

// Present/cover the embedded picker (after a kind 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 person privateness and safety, the system renders the embedded photograph picker in a approach that stops any drawing or overlaying. This intentional design alternative implies that your UX ought to think about the photograph picker’s show space as a definite and devoted component, very like you’d plan for an promoting banner.

In case you have any suggestions or solutions, submit tickets to our

subject tracker.


Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles