Poza pojedynczymi funkcjami: gwarantowanie kombinacji funkcji w CameraX 1.5
Czas czytania: 6 min
Nowoczesne aplikacje do obsługi aparatu charakteryzują się zaawansowanymi, nakładającymi się na siebie funkcjami. Użytkownicy oczekują, że będą mogli nagrywać filmy w oszałamiającym trybie HDR, rejestrować płynne ruchy w 60 klatkach na sekundę i uzyskiwać płynne materiały dzięki stabilizacji podglądu – często jednocześnie.
Jako deweloperzy wiemy, że rzeczywistość jest bardziej skomplikowana. Jak możesz mieć pewność, że dane urządzenie obsługuje daną kombinację? Do tej pory włączanie wielu funkcji często było ryzykowne. Możesz sprawdzić obsługę poszczególnych funkcji, ale ich połączenie może prowadzić do niezdefiniowanego zachowania lub, co gorsza, do nieudanej sesji aparatu. Ta niepewność zmusza deweloperów do zachowawczości, co uniemożliwia użytkownikom korzystającym z wydajnych urządzeń uzyskanie najlepszych możliwych wrażeń.
Na przykład bardzo niewiele urządzeń premium obsługuje jednocześnie HDR i 60 klatek na sekundę. Dlatego większość aplikacji unika włączania obu tych funkcji jednocześnie, aby zapobiec pogorszeniu komfortu użytkowania na większości telefonów.
Aby rozwiązać ten problem, wprowadzamy grupę funkcji w CameraX – nowy interfejs API, który eliminuje zgadywanie. Możesz teraz sprawdzić, czy określona kombinacja funkcji jest obsługiwana przed skonfigurowaniem aparatu, lub po prostu poinformować CameraX o swoich priorytetach i pozwolić jej włączyć najlepiej obsługiwaną kombinację.
Dla osób, które dopiero zaczynają korzystać z CameraX
Zanim przejdziemy do nowego interfejsu Feature Group API, przypomnijmy sobie, czym jest CameraX. CameraX to biblioteka pomocy Jetpack, która ułatwia tworzenie aplikacji aparatu. Zapewnia spójny i łatwy w użyciu interfejs API, który działa na większości urządzeń z Androidem i jest wstecznie zgodny z Androidem 6.0 (poziom interfejsu API 23). Jeśli dopiero zaczynasz korzystać z CameraX, zapoznaj się z oficjalną dokumentacją i wypróbuj warsztaty programistyczne.
Co możesz tworzyć za pomocą interfejsu Feature Group API
Nie musisz już ryzykować, dobierając kombinacje funkcji. Możesz mieć pewność, że zapewnisz najlepsze możliwe wrażenia podczas korzystania z aparatu, np. nagrywanie filmów w HDR i 60 kl./s na odpowiednim sprzęcie (np. Pixel 10 Pro), a jednocześnie unikniesz błędów na urządzeniach, które nie obsługują takiej kombinacji.
Za pomocą interfejsu Feature Group API możesz:
- Twórz inteligentniejsze, dynamiczne interfejsy: inteligentnie włączaj i wyłączaj ustawienia w interfejsie na podstawie obsługi sprzętu w czasie rzeczywistym. Jeśli na przykład użytkownik włączy HDR, możesz natychmiast wyszarzyć i wyłączyć opcję 60 kl./s, jeśli ta kombinacja nie jest obsługiwana na danym urządzeniu.
- Zapewnij niezawodny tryb „Wysoka jakość”: skonfiguruj kamerę, korzystając z listy priorytetowych funkcji. CameraX automatycznie wyszukuje i włącza najlepiej obsługiwaną kombinację dla danego urządzenia, zapewniając doskonały efekt bez skomplikowanej logiki specyficznej dla urządzenia.
- Zapobieganie niepowodzeniom sesji aparatu: dzięki wcześniejszemu sprawdzeniu obsługi zapobiegasz próbom skonfigurowania przez aparat nieobsługiwanej kombinacji, co eliminuje częste źródło awarii i zapewnia płynne działanie.
Jak to działa: podstawowe komponenty
Nowy interfejs API koncentruje się na kluczowych dodatkach do klas SessionConfig i CameraInfo.
- GroupableFeature: ten interfejs API wprowadza zestaw predefiniowanych funkcji, które można grupować, takich jak HDR_HLG10, FPS_60, PREVIEW_STABILIZATION i IMAGE_ULTRA_HDR. Ze względu na ograniczenia obliczeniowe tylko określony zestaw funkcji można grupować z wysokim stopniem niezawodności, jaki zapewnia ten interfejs API. Pracujemy nad rozszerzeniem tej listy i w przyszłych wersjach wprowadzimy obsługę kolejnych funkcji.
- Nowe parametry SessionConfig: ta klasa, używana do rozpoczynania sesji aparatu, akceptuje teraz 2 nowe parametry:
requiredFeatureGroup: używaj tej opcji w przypadku funkcji, które muszą być obsługiwane, aby konfiguracja się powiodła. Jest to idealne rozwiązanie w przypadku funkcji, które użytkownik włącza wprost, np. przełącznika „HDR”. Aby zapewnić deterministyczne i spójne działanie, wywołaniebindToLifecyclezwróci błądIllegalArgumentException, jeśli żądana kombinacja nie jest obsługiwana, zamiast cicho ignorować prośbę o funkcję. Aby wcześniej sprawdzić ten wynik, użyj interfejsuCameraInfo#isFeatureGroupSupportedAPI (szczegóły poniżej).preferredFeatureGroup: używaj tego ustawienia w przypadku funkcji, które są pożądane, ale opcjonalne, np. gdy chcesz wdrożyć domyślny tryb „Wysoka jakość”. Podajesz listę wybranych funkcji uporządkowaną według priorytetów, a CameraX automatycznie włącza kombinację o najwyższym priorytecie, która jest obsługiwana przez urządzenie.
- CameraInfo#isFeatureGroupSupported(): to podstawowa metoda sprawdzania, czy grupa funkcji jest obsługiwana. Jest ona odpowiednia do udostępniania użytkownikom w interfejsie aplikacji tylko obsługiwanych opcji funkcji. Przekazujesz do niego wartość
SessionConfig, a on zwraca wartość logiczną wskazującą, czy ta kombinacja jest obsługiwana. Jeśli zamierzasz powiązaćSessionConfigz wymaganymi funkcjami, najpierw użyj tego interfejsu API, aby sprawdzić, czy jest on obsługiwany.
Wdrożenie w praktyce
Przyjrzyjmy się, jak wykorzystać te komponenty, aby ulepszyć działanie aparatu.
Scenariusz 1. Tryb wysokiej jakości „najlepsze oszacowanie”
Jeśli chcesz domyślnie włączać najlepsze funkcje, możesz przekazać do preferredFeatureGroup listę uszeregowaną według priorytetu. W tym przykładzie informujemy CameraX, że ma priorytetowo traktować HDR, następnie 60 kl./s, a na końcu stabilizację podglądu. CameraX zajmuje się złożonym procesem sprawdzania wszystkich możliwych kombinacji i wybierania najlepszej z nich, która jest obsługiwana przez urządzenie.
Jeśli na przykład urządzenie obsługuje HDR i 60 kl./s, ale nie stabilizację podglądu, CameraX włączy pierwsze 2 funkcje i odrzuci trzecią. Dzięki temu możesz zapewnić użytkownikom jak najlepsze wrażenia bez konieczności pisania skomplikowanych testów dla poszczególnych urządzeń.
cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
SessionConfig(
useCases = listOf(preview, videoCapture),
// The order of features in this list determines their priority.
// CameraX will enable the best-supported combination based on these
// priorities: HDR_HLG10 > FPS_60 > Preview Stabilization.
preferredFeatureGroup =
listOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION),
).apply {
// (Optional) Get a callback with the enabled features
// to update your UI.
setFeatureSelectionListener { selectedFeatures ->
updateUiIndicators(selectedFeatures)
}
}
)W przypadku tego fragmentu kodu CameraX spróbuje włączyć kombinacje funkcji w tej kolejności priorytetów, wybierając pierwszą, którą urządzenie w pełni obsługuje:
- HDR + 60 kl./s + stabilizacja podglądu
- HDR + 60 kl./s
- Stabilizacja podglądu HDR+
- HDR
- 60 kl./s + stabilizacja podglądu
- 60 kl./s
- Podgląd stabilizacji
- Żadna z powyższych funkcji
Scenariusz 2. Tworzenie reaktywnego interfejsu
Aby utworzyć interfejs, który reaguje na wybory użytkownika i uniemożliwia mu wybieranie nieobsługiwanych kombinacji funkcji, możesz bezpośrednio wysyłać zapytania o obsługę. Funkcja poniżej sprawdza, które funkcje są niezgodne z bieżącymi wyborami użytkownika, co pozwala wyłączyć odpowiednie elementy interfejsu.
/**
* Returns a list of features that are NOT supported in combination
* with the currently selected features.
*/
fun getUnsupportedFeatures(
currentFeatures: Set<GroupableFeature>
): Set<GroupableFeature> {
val unsupportedFeatures = mutableSetOf<GroupableFeature>()
val appFeatureOptions = setOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION)
// Iterate over every available feature option in your app.
appFeatureOptions.forEach { featureOption ->
// Skip features the user has already selected.
if (currentFeatures.contains(featureOption)) return@forEach
// Check if adding this new feature is supported.
val isSupported = cameraInfo.isFeatureGroupSupported(
SessionConfig(
useCases = useCases,
// Check the new feature on top of existing ones.
requiredFeatureGroup = currentFeatures + featureOption
)
)
if (!isSupported) {
unsupportedFeatures.add(featureOption)
}
}
return unsupportedFeatures
}Następnie możesz połączyć tę logikę z elementem ViewModel lub kontrolerem interfejsu, aby reagować na dane wejściowe użytkownika i ponownie powiązać kamerę z konfiguracją, która na pewno będzie działać.
// Invoked when user turns some feature on/off.
fun onFeatureChange(currentFeatures: Set<GroupableFeature>) {
// Identify features that are unsupported with the current selection.
val unsupportedFeatures = getUnsupportedFeatures(currentFeatures)
// Update app UI so that users can't enable them.
updateDisabledFeatures(unsupportedFeatures)
// Since the UI now only allows selecting supported feature combinations,
// `currentFeatures` is always valid. This allows setting
// `requiredFeatureGroup` directly, without needing to re-check for
// support or set a feature selection listener.
cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
SessionConfig(
useCases = listOf(preview, videoCapture),
requiredFeatureGroup = currentFeatures,
)
)
}Aby zobaczyć te koncepcje w działającej aplikacji, możesz zapoznać się z naszą wewnętrzną aplikacją testową. Zawiera ona pełną implementację obu opisanych powyżej scenariuszy „najlepsze wyniki” i „reaktywny interfejs”.
Uwaga: jest to aplikacja testowa, a nie oficjalnie obsługiwany przykład. Jest to świetny materiał referencyjny dotyczący interfejsu Feature Group API, ale nie został on dopracowany pod kątem użytku produkcyjnego.
Rozpocznij już dziś
Interfejs Feature Group API usuwa niejednoznaczność związaną z korzystaniem z zaawansowanych funkcji aparatu. Dzięki deterministycznemu sposobowi sprawdzania obsługi funkcji możesz tworzyć bardziej zaawansowane i niezawodne aplikacje aparatu.
Interfejs API jest dostępny w wersji eksperymentalnej w CameraX 1.5, a w wersji 1.6 ma stać się w pełni stabilny. W przyszłości planujemy dodać więcej funkcji i ulepszeń.
Więcej informacji znajdziesz w oficjalnej dokumentacji. Nie możemy się doczekać Twoich kreacji i opinii. Podziel się wrażeniami i zgłoś wszelkie problemy, korzystając z tych kanałów:
-
Wiadomości o usługachZ przyjemnością ogłaszamy stabilną wersję bibliotek AndroidX Security State 1.1.0 i Security State Provider 1.0.0.
Maunik Shah, Alec Garcia, Joseph Yong • Czas czytania: 4 minuty -
Wiadomości o usługachDziś udostępniamy pierwszy zestaw zadań długoterminowych (LHT), czyli bardzo złożonych zadań, których wykonanie zajmuje inżynierowi kilka dni, a nawet tydzień. Wprowadzamy też ocenę agentów, zaczynając od agentów od odpowiednich dostawców modeli.
Matthew McCullough • Czas czytania: 3 minuty -
Wiadomości o usługachDebugowanie bezprzewodowe na Androidzie jest teraz szybsze, bardziej niezawodne i łatwiejsze w konfiguracji niż kiedykolwiek. W przypadku ADB Wi-Fi 2.0 wprowadziliśmy nowy stos serwerów i inteligentniejsze zarządzanie siecią, aby bezpośrednio uwzględnić opinie deweloperów dotyczące luk w zakresie użyteczności.
Steven Jenkins, Sherif Eid, Fabien Sanglard • Czas czytania: 1 minuta
Otrzymuj co tydzień najnowsze informacje o tworzeniu aplikacji na Androida na swoją skrzynkę odbiorczą.