Встроенное окно выбора фотографий – более удобный способ запрашивать доступ к фото и видео в приложении
Улучшите удобство использования приложения с помощью нового способа использования окна выбора фотографий Android. Новое встроенное окно выбора фотографий позволяет пользователям выбирать фотографии и видео прямо в интерфейсе приложения, не беспокоясь о конфиденциальности. Теперь в вашем приложении доступны все преимущества инструмента выбора фотографий, в том числе доступ к облачному контенту.
Зачем встраивать видео?
Мы понимаем, что многие приложения стремятся обеспечить пользователям удобство и высокую степень интеграции при выборе фотографий и видео. Встроенный инструмент выбора фотографий позволяет пользователям быстро находить недавние снимки, не выходя из приложения. Кроме того, они могут просматривать всю библиотеку в облачном хранилище, например в Google Фото, включая избранное, альбомы и функцию поиска. Благодаря этому пользователям не нужно переключаться между приложениями или беспокоиться о том, где хранится нужная фотография – на устройстве или в облаке.
Простая интеграция и повышенная конфиденциальность
При использовании встроенного инструмента выбора фотографий приложению не нужен доступ к фотографиям и видео пользователя, пока он не выберет что-нибудь. Это означает, что конфиденциальность пользователей будет защищена лучше, а работа с сервисом станет удобнее. Кроме того, встроенный инструмент выбора фотографий предоставляет пользователям доступ ко всей их облачной медиатеке, тогда как стандартное разрешение на доступ к фотографиям ограничено только локальными файлами.
Встроенный инструмент выбора фотографий в Google Сообщениях
Google Сообщения демонстрируют возможности встроенного инструмента выбора фотографий. Вот как это было сделано:
- Интуитивно понятное размещение. Инструмент выбора фотографий находится прямо под кнопкой камеры, поэтому пользователям легко решить, что делать: сделать новый снимок или выбрать существующий.
- Динамический предпросмотр. Сразу после нажатия на фотографию пользователь видит ее в увеличенном размере, что позволяет ему убедиться в правильности выбора. Если отменить выбор фотографии, предпросмотр исчезнет, чтобы не загромождать экран.
- Разверните, чтобы увидеть больше контента. В начальном представлении показаны только недавние фотографии. Однако пользователи могут легко развернуть окно выбора фотографий, чтобы просмотреть и выбрать все фотографии и видео в своей библиотеке, включая облачный контент из Google Фото.
- Уважение к выбору пользователей. Встроенный инструмент выбора фотографий предоставляет доступ только к тем фото и видео, которые выбрал пользователь. Это значит, что приложения могут больше не запрашивать разрешения на доступ к фото и видео. Кроме того, Сообщениям не придется обрабатывать ситуации, когда пользователи предоставляют ограниченный доступ к фото и видео.
Реализация
Интегрировать встроенный инструмент выбора фотографий можно с помощью библиотеки Jetpack.
Jetpack Compose
Сначала добавьте библиотеку Jetpack Photo Picker в качестве зависимости.
implementation("androidx.photopicker:photopicker-compose:1.0.0-alpha01")
Функция EmbeddedPhotoPicker позволяет встроить интерфейс выбора фотографий прямо в экран Compose. Эта composable-функция создает SurfaceView, в котором размещается интерфейс встроенного инструмента выбора фотографий. Он управляет подключением к сервису EmbeddedPhotoPicker, обрабатывает действия пользователя и передает URI выбранных медиафайлов вызывающему приложению.
@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)
}
}
)
}
}
}
}
}Просмотры
Сначала добавьте библиотеку Jetpack Photo Picker в качестве зависимости.
implementation("androidx.photopicker:photopicker:1.0.0-alpha01")
Чтобы добавить встроенный инструмент выбора фотографий, добавьте запись в файл макета.
<view class="androidx.photopicker.EmbeddedPhotoPickerView"
android:id="@+id/photopicker"
android:layout_width="match_parent"
android:layout_height="match_parent" />и инициализируйте его в своем действии или фрагменте.
// 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()
)
}Вы можете вызывать разные методы EmbeddedPhotoPickerSession для взаимодействия со встроенным инструментом выбора.
// 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)
Обратите внимание, что встроенный инструмент выбора фотографий доступен пользователям Android 14 (уровень API 34) или более поздней версии с SDK Extensions 15 или выше. Подробнее о доступности инструмента выбора фотографий на устройствах…
Чтобы повысить конфиденциальность пользователя и безопасность, система отрисовывает встроенный инструмент выбора фотографий так, чтобы предотвратить рисование или наложение. Это сделано намеренно, чтобы вы могли учитывать область выбора фотографий как отдельный элемент, например рекламный баннер.
Если у вас есть отзывы или предложения, отправьте их через систему отслеживания ошибок.
-
Новости о продуктахПриложения, предназначенные для предстоящего выпуска Android, больше не смогут напрямую записывать данные в контакты с помощью разрешения WRITE_CONTACTS.
Roxanna Aliabadi Walker • Время на чтение: 6 минут -
Новости о продуктахКонфиденциальность и управление данными остаются в центре внимания Android. Окно выбора фотографий сделало обмен медиафайлами безопасным и простым в реализации. Теперь мы хотим обеспечить такой же уровень конфиденциальности, простоты и удобства для выбора контактов.
Roxanna Aliabadi Walker • Время на чтение: 4 минуты -
Новости о продуктахПо мере развития агентных технологий разработка для Android выходит на новый уровень: от вспомогательного автозаполнения кода до агентов, выполняющих сквозные задачи под вашим руководством. Вы можете выбирать любые модели и агентов.
Jason Buchel • Время на чтение: 3 минуты
Получайте еженедельную рассылку с последними новостями о разработке для Android.