O seletor de fotos incorporado: uma maneira mais fácil de solicitar fotos e vídeos de forma privada no seu app
Planeje e prepare-se para melhorar a experiência do usuário do seu app com uma nova maneira de usar o seletor de fotos do Android. O novo seletor de fotos integrado oferece uma maneira integrada e focada na privacidade para os usuários selecionarem fotos e vídeos diretamente na interface do app. Agora seu app pode aproveitar todos os mesmos benefícios disponíveis com o seletor de fotos, incluindo acesso ao conteúdo da nuvem, integrado diretamente à experiência do app.
Por que usar o Google Maps incorporado?
Entendemos que muitos apps querem oferecer uma experiência altamente integrada e simples para os usuários ao selecionar fotos ou vídeos. O seletor de fotos incorporado foi projetado para isso. Ele permite que os usuários acessem rapidamente as fotos recentes sem sair do seu app. Eles também podem explorar a biblioteca completa no provedor de mídia na nuvem preferido (por exemplo, Google Fotos), incluindo favoritos, álbuns e funcionalidade de pesquisa. Assim, os usuários não precisam alternar entre apps nem se preocupar se a foto que querem está armazenada localmente ou na nuvem.
Integração total, privacidade reforçada
Com o seletor de fotos incorporado, o app não precisa de acesso às fotos ou vídeos do usuário até que ele selecione algo. Isso significa mais privacidade para seus usuários e uma experiência mais simplificada. Além disso, o seletor de fotos incorporado oferece aos usuários acesso a toda a biblioteca de mídia baseada na nuvem, enquanto a permissão de fotos padrão é restrita apenas a arquivos locais.
O seletor de fotos incorporado no Google Mensagens
O Google Mensagens mostra o poder do seletor de fotos incorporado. Veja como eles fizeram a integração:
- Posicionamento intuitivo : o seletor de fotos fica logo abaixo do botão da câmera, dando aos usuários uma escolha clara entre capturar uma nova foto ou selecionar uma já existente.
- Visualização dinâmica:logo depois que um usuário toca em uma foto, uma visualização grande aparece, facilitando a confirmação da seleção. Se eles desmarcarem a foto, a prévia vai desaparecer, mantendo a experiência limpa e organizada.
- Expandir para mais conteúdo : a visualização inicial é simplificada, oferecendo acesso fácil às fotos recentes. No entanto, os usuários podem expandir facilmente o seletor de fotos para navegar e escolher entre todas as fotos e vídeos na biblioteca, incluindo conteúdo da nuvem do Google Fotos.
- Respeito às escolhas do usuário:o seletor de fotos incorporado só concede acesso às fotos ou vídeos específicos que o usuário seleciona. Isso significa que ele pode parar de solicitar as permissões de foto e vídeo. Isso também evita que o app Mensagens precise lidar com situações em que os usuários concedem apenas acesso limitado a fotos e vídeos.
Implementação
A integração do seletor de fotos incorporado é facilitada com a biblioteca Jetpack do seletor de fotos.
Jetpack Compose
Primeiro, inclua a biblioteca do seletor de fotos do Jetpack como uma dependência.
implementation("androidx.photopicker:photopicker-compose:1.0.0-alpha01")
A função combinável EmbeddedPhotoPicker oferece um mecanismo para incluir a interface do seletor de fotos incorporado diretamente na tela do Compose. Esse elemento combinável cria uma SurfaceView que hospeda a interface do seletor de fotos incorporado. Ele gerencia a conexão com o serviço EmbeddedPhotoPicker, lida com as interações do usuário e comunica os URIs de mídia selecionados ao aplicativo de chamada.
@Composable
fun EmbeddedPhotoPickerDemo() {
// We keep track of the list of selected attachments
var attachments by remember { mutableStateOf(emptyList<Uri>()) }
val coroutineScope = rememberCoroutineScope()
// We hide the bottom sheet by default but we show it when the user clicks on the button
val scaffoldState = rememberBottomSheetScaffoldState(
bottomSheetState = rememberStandardBottomSheetState(
initialValue = SheetValue.Hidden,
skipHiddenState = false
)
)
// Customize the embedded photo picker
val photoPickerInfo = EmbeddedPhotoPickerFeatureInfo
.Builder()
// Set limit the selection to 5 items
.setMaxSelectionLimit(5)
// Order the items selection (each item will have an index visible in the photo picker)
.setOrderedSelection(true)
// Set the accent color (red in this case, otherwise it follows the device's accent color)
.setAccentColor(0xFF0000)
.build()
// The embedded photo picker state will be stored in this variable
val photoPickerState = rememberEmbeddedPhotoPickerState(
onSelectionComplete = {
coroutineScope.launch {
// Hide the bottom sheet once the user has clicked on the done button inside the picker
scaffoldState.bottomSheetState.hide()
}
},
onUriPermissionGranted = {
// We update our list of attachments with the new Uris granted
attachments += it
},
onUriPermissionRevoked = {
// We update our list of attachments with the Uris revoked
attachments -= it
}
)
SideEffect {
val isExpanded = scaffoldState.bottomSheetState.targetValue == SheetValue.Expanded
// We show/hide the embedded photo picker to match the bottom sheet state
photoPickerState.setCurrentExpanded(isExpanded)
}
BottomSheetScaffold(
topBar = {
TopAppBar(title = { Text("Embedded Photo Picker demo") })
},
scaffoldState = scaffoldState,
sheetPeekHeight = if (scaffoldState.bottomSheetState.isVisible) 400.dp else 0.dp,
sheetContent = {
Column(Modifier.fillMaxWidth()) {
// We render the embedded photo picker inside the bottom sheet
EmbeddedPhotoPicker(
state = photoPickerState,
embeddedPhotoPickerFeatureInfo = photoPickerInfo
)
}
}
) { innerPadding ->
Column(Modifier.padding(innerPadding).fillMaxSize().padding(horizontal = 16.dp)) {
Button(onClick = {
coroutineScope.launch {
// We expand the bottom sheet, which will trigger the embedded picker to be shown
scaffoldState.bottomSheetState.partialExpand()
}
}) {
Text("Open photo picker")
}
LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 64.dp)) {
// We render the image using the Coil library
itemsIndexed(attachments) { index, uri ->
AsyncImage(
model = uri,
contentDescription = "Image ${index + 1}",
contentScale = ContentScale.Crop,
modifier = Modifier.clickable {
coroutineScope.launch {
// When the user clicks on the media from the app's UI, we deselect it
// from the embedded photo picker by calling the method deselectUri
photoPickerState.deselectUri(uri)
}
}
)
}
}
}
}
}
Visualizações
Primeiro, inclua a biblioteca do seletor de fotos do Jetpack como uma dependência.
implementation("androidx.photopicker:photopicker:1.0.0-alpha01")
Para adicionar o seletor de fotos incorporado, adicione uma entrada ao arquivo de layout.
<view class="androidx.photopicker.EmbeddedPhotoPickerView"
android:id="@+id/photopicker"
android:layout_width="match_parent"
android:layout_height="match_parent" />
e inicialize na sua atividade/fragmento.
// We keep track of the list of selected attachments
private val _attachments = MutableStateFlow(emptyList<Uri>())
val attachments = _attachments.asStateFlow()
private lateinit var picker: EmbeddedPhotoPickerView
private var openSession: EmbeddedPhotoPickerSession? = null
val pickerListener = object EmbeddedPhotoPickerStateChangeListener {
override fun onSessionOpened (newSession: EmbeddedPhotoPickerSession) {
openSession = newSession
}
override fun onSessionError (throwable: Throwable) {}
override fun onUriPermissionGranted(uris: List<Uri>) {
_attachments += uris
}
override fun onUriPermissionRevoked (uris: List<Uri>) {
_attachments -= uris
}
override fun onSelectionComplete() {
// Hide the embedded photo picker as the user is done with the photo/video selection
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_view)
//
// Add the embedded photo picker to a bottom sheet to allow the dragging to display the full photo library
//
picker = findViewById(R.id.photopicker)
picker.addEmbeddedPhotoPickerStateChangeListener(pickerListener)
picker.setEmbeddedPhotoPickerFeatureInfo(
// Set a custom accent color
EmbeddedPhotoPickerFeatureInfo.Builder().setAccentColor(0xFF0000).build()
)
}
É possível chamar diferentes métodos de EmbeddedPhotoPickerSession para interagir com o seletor incorporado.
// Notify the embedded picker of a configuration change openSession.notifyConfigurationChanged(newConfig) // Update the embedded picker to expand following a user interaction openSession.notifyPhotoPickerExpanded(/* expanded: */ true) // Resize the embedded picker openSession.notifyResized(/* width: */ 512, /* height: */ 256) // Show/hide the embedded picker (after a form has been submitted) openSession.notifyVisibilityChanged(/* visible: */ false) // Remove unselected media from the embedded picker after they have been // unselected from the host app's UI openSession.requestRevokeUriPermission(removedUris)
É importante observar que a experiência do seletor de fotos incorporado está disponível para usuários que usam o Android 14 (nível da API 34) ou versões mais recentes com as extensões do SDK 15 ou mais recentes. Leia mais sobre a disponibilidade do seletor de fotos em dispositivos.
Para aumentar a privacidade e a segurança do usuário, o sistema renderiza o seletor de fotos incorporado de forma a evitar qualquer desenho ou sobreposição. Essa escolha de design intencional significa que sua UX precisa considerar a área de exibição do seletor de fotos como um elemento distinto e dedicado, assim como você planeja um banner publicitário.
Se tiver feedback ou sugestões, envie tíquetes para nosso rastreador de problemas.
Continuar lendo
-
Notícias sobre produtos
A privacidade e o controle do usuário continuam sendo o foco da experiência do Android. Assim como o seletor de fotos tornou o compartilhamento de mídia seguro e fácil de implementar, agora estamos trazendo o mesmo nível de privacidade, simplicidade e ótima experiência do usuário para a seleção de contatos.
Roxanna Aliabadi Walker • Leitura de 4 minutos
-
Notícias sobre produtos
Se você é um desenvolvedor Android e quer implementar recursos inovadores de IA no seu app, lançamos recentemente novas atualizações poderosas.
Thomas Ezan • 3 min de leitura
-
Notícias sobre produtos
O Android 17 chegou ao Beta 4, o último beta programado deste ciclo de lançamento, um marco crítico para a compatibilidade de apps e a estabilidade da plataforma.
Daniel Galpin • Leitura de 4 minutos
Fique por dentro
Receba os insights mais recentes sobre desenvolvimento Android na sua caixa de entrada semanalmente.