Podgląd z aparatu

Uwaga: ta strona dotyczy pakietu Camera2. Jeśli Twoja aplikacja nie wymaga określonych funkcji niskiego poziomu z Camera2, zalecamy używanie CameraX. Zarówno CameraX, jak i Camera2 obsługują Androida 5.0 (poziom interfejsu API 21) i nowsze wersje.

Na urządzeniach z Androidem kamery i podglądy z nich nie zawsze są w tej samej orientacji.

Aparat jest umieszczony w stałym miejscu na urządzeniu, niezależnie od tego, czy jest to telefon, tablet czy komputer. Gdy zmienia się orientacja urządzenia, zmienia się też orientacja kamery.

W rezultacie aplikacje aparatu zwykle zakładają stałą zależność między orientacją urządzenia a formatem obrazu podglądu z aparatu. Gdy telefon jest w orientacji pionowej, podgląd z aparatu jest wyższy niż szerszy. Gdy telefon (i aparat) jest obrócony do orientacji poziomej, podgląd z aparatu powinien być szerszy niż wyższy.

Te założenia są jednak podważane przez nowe formaty, takie jak urządzenia składane, oraz tryby wyświetlania, takie jak tryb wielu okien i tryb wielu wyświetlaczy. Urządzenia składane zmieniają rozmiar wyświetlacza i format obrazu bez zmiany orientacji. Tryb wielu okien ogranicza aplikacje aparatu do części ekranu, skalując podgląd z aparatu niezależnie od orientacji urządzenia. Tryb wielu wyświetlaczy umożliwia korzystanie z dodatkowych wyświetlaczy, które mogą nie być w tej samej orientacji co wyświetlacz główny.

Orientacja aparatu

Definicja zgodności Androida określa, że czujnik obrazu aparatu „MUSI być zorientowany tak, aby dłuższy wymiar aparatu był zgodny z dłuższym wymiarem ekranu. Oznacza to, że gdy urządzenie jest trzymane w orientacji poziomej, aparaty MUSZĄ robić zdjęcia w orientacji poziomej. Dotyczy to wszystkich urządzeń, niezależnie od ich naturalnej orientacji, czyli zarówno urządzeń z orientacją poziomą, jak i pionową”.

Układ aparatu i ekranu maksymalizuje obszar wyświetlania wizjera aparatu w aplikacji aparatu. Ponadto czujniki obrazu zwykle generują dane w poziomym formacie obrazu, najczęściej 4:3.

Telefon i czujnik aparatu w orientacji pionowej.
Rysunek 1. Typowa relacja między orientacją telefonu i czujnika aparatu.

Naturalna orientacja czujnika aparatu to pozioma. Na rysunku 1 czujnik przedniego aparatu (aparatu skierowanego w tę samą stronę co wyświetlacz) jest obrócony o 270 stopni względem telefonu, aby spełniać wymagania definicji zgodności Androida.

Aby udostępnić aplikacjom informacje o obrocie czujnika, interfejs API camera2 zawiera stałą SENSOR_ORIENTATION. W przypadku większości telefonów i tabletów urządzenie zgłasza orientację czujnika 270 stopni w przypadku przednich aparatów i 90 stopni (punkt widzenia z tyłu urządzenia) w przypadku tylnych aparatów, co wyrównuje długą krawędź czujnika z długą krawędzią urządzenia. Kamery laptopów zwykle zgłaszają orientację czujnika wynoszącą 0 lub 180 stopni.

Czujniki obrazu aparatu generują dane (bufor obrazu) w naturalnej orientacji czujnika (poziomej), dlatego bufor obrazu musi zostać obrócony o liczbę stopni określoną przez SENSOR_ORIENTATION, aby podgląd z aparatu był wyświetlany w naturalnej orientacji urządzenia. W przypadku przednich aparatów obrót jest wykonywany w lewo, a w przypadku tylnych – w prawo.

Na przykład w przypadku przedniego aparatu na rysunku 1 bufor obrazu wygenerowany przez czujnik aparatu wygląda tak:

Czujnik aparatu obrócony do orientacji poziomej z obrazem na boku, w lewym górnym rogu.
Rysunek 2. Bufor obrazu RAW z czujnika przedniego aparatu w naturalnej orientacji poziomej.

Obraz musi zostać obrócony o 270 stopni w lewo, aby orientacja podglądu była zgodna z orientacją urządzenia:

Czujnik aparatu w orientacji pionowej z obrazem w pionie.
Rysunek 3. Bufor obrazu z przedniego aparatu obrócony o 270 stopni w lewo, aby dopasować go do orientacji pionowej urządzenia.

Tylny aparat wygeneruje bufor obrazu o takiej samej orientacji jak poprzedni bufor, ale wartość SENSOR_ORIENTATION wynosi 90 stopni. W efekcie bufor jest obracany o 90 stopni w prawo.

Obracanie urządzenia

Obrót urządzenia to liczba stopni, o jaką urządzenie jest obrócone względem swojej naturalnej orientacji. Na przykład telefon w orientacji poziomej ma obrót urządzenia o 90 lub 270 stopni, w zależności od kierunku obrotu.

Bufor obrazu czujnika aparatu musi być obrócony o taką samą liczbę stopni jak urządzenie (oprócz stopni orientacji czujnika), aby podgląd z aparatu był wyświetlany w pionie.

Obliczanie orientacji

Prawidłowa orientacja podglądu z aparatu uwzględnia orientację czujnika i obrót urządzenia.

Ogólny obrót bufora obrazu czujnika można obliczyć za pomocą tego wzoru:

rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360

gdzie sign to 1 w przypadku przednich aparatów i -1 w przypadku tylnych aparatów.

W przypadku aparatów przednich bufor obrazu jest obracany w lewo (od naturalnej orientacji czujnika). W przypadku tylnych aparatów bufor obrazu czujnika jest obracany zgodnie z ruchem wskazówek zegara.

Wyrażenie deviceOrientationDegrees * sign + 360 konwertuje obrót urządzenia z ruchu przeciwnego do ruchu wskazówek zegara na ruch zgodny z ruchem wskazówek zegara w przypadku aparatów tylnych (np. konwertuje 270 stopni przeciwnie do ruchu wskazówek zegara na 90 stopni zgodnie z ruchem wskazówek zegara). Operacja modulo skaluje wynik do wartości mniejszej niż 360 stopni (np. skaluje obrót o 540 stopni do 180 stopni).

Różne interfejsy API raportują obrót urządzenia w różny sposób:

  • Display#getRotation() określa obrót urządzenia w kierunku przeciwnym do ruchu wskazówek zegara (z punktu widzenia użytkownika). Ta wartość jest wstawiana do wcześniejszego wzoru w niezmienionej postaci.
  • OrientationEventListener#onOrientationChanged() zwraca obrót urządzenia w prawo (z punktu widzenia użytkownika). Zaneguj wartość, aby użyć jej we wcześniejszej formule.

Przednie aparaty

Podgląd z aparatu i czujnik w orientacji poziomej, czujnik jest ustawiony prawidłowo.
Rysunek 4. Podgląd z kamery i czujnik z telefonem obróconym o 90 stopni do orientacji poziomej.

Oto bufor obrazu wygenerowany przez czujnik aparatu na rysunku 4:

Czujnik aparatu w orientacji poziomej z obrazem w pionie.
Rysunek 5. Bufor obrazu utworzony przez czujnik przedniego aparatu, gdy telefon jest obrócony o 90 stopni w lewo.

Bufor musi zostać obrócony o 270 stopni w lewo, aby dostosować go do orientacji czujnika (patrz Orientacja aparatu powyżej):

Czujnik aparatu obrócony do orientacji pionowej z obrazem bokiem, w prawym górnym rogu.
Rysunek 6. Bufor obrazu został obrócony o 270 stopni w lewo, aby dostosować go do orientacji czujnika.

Następnie bufor jest obracany o kolejne 90 stopni w lewo, aby uwzględnić obrót urządzenia, co daje prawidłową orientację podglądu z kamery na rysunku 4:

Czujnik aparatu obrócony do orientacji poziomej z obrazem w pionie.
Rysunek 7. Bufor obrazu po dodatkowym obrocie o 90 stopni w lewo w celu dostosowania do orientacji urządzenia.

Oto aparat obrócony w prawo do orientacji poziomej:

Podgląd z aparatu i czujnik są w orientacji poziomej, ale czujnik jest odwrócony do góry nogami.
Rysunek 8. Podgląd z aparatu i czujnik po obróceniu telefonu o 270 stopni (lub -90 stopni) do orientacji poziomej.

Oto bufor obrazu:

Czujnik aparatu obrócony do orientacji poziomej z obrazem do góry nogami.
Rysunek 9. Bufor obrazu utworzony przez czujnik przedniego aparatu, gdy telefon jest obrócony o 270 stopni w lewo.

Bufor musi zostać obrócony o 270 stopni w lewo, aby dostosować go do orientacji czujnika:

Czujnik aparatu obrócony do orientacji pionowej z obrazem z boku, w lewym górnym rogu.
Rysunek 10. Bufor obrazu został obrócony o 270 stopni w lewo, aby dostosować go do orientacji czujnika.

Następnie bufor jest obracany o kolejne 270 stopni w kierunku przeciwnym do ruchu wskazówek zegara, aby uwzględnić obrót urządzenia:

Czujnik aparatu obrócony do orientacji poziomej z obrazem w pionie.
Rysunek 11. Bufor obrazu po dodatkowym obrocie o 270 stopni w lewo w celu dostosowania do orientacji urządzenia.

Tylne aparaty

Tylne aparaty mają zwykle orientację czujnika wynoszącą 90 stopni (patrząc od tyłu urządzenia). Podczas orientowania podglądu z aparatu bufor obrazu z czujnika jest obracany zgodnie z ruchem wskazówek zegara o wartość obrotu czujnika (a nie przeciwnie do ruchu wskazówek zegara, jak w przypadku aparatów przednich), a następnie bufor obrazu jest obracany przeciwnie do ruchu wskazówek zegara o wartość obrotu urządzenia.

Podgląd z aparatu i czujnik są w orientacji poziomej, ale czujnik jest odwrócony do góry nogami.
Rysunek 12. Telefon z tylnym aparatem w orientacji poziomej (obrócony o 270 lub -90 stopni).

Oto bufor obrazu z czujnika aparatu na rysunku 12:

Czujnik aparatu obrócony do orientacji poziomej z obrazem do góry nogami.
Rysunek 13. Bufor obrazu utworzony przez czujnik tylnego aparatu, gdy telefon jest w orientacji poziomej.

Bufor musi zostać obrócony o 90 stopni w prawo, aby dostosować go do orientacji czujnika:

Czujnik aparatu obrócony do orientacji pionowej z obrazem z boku, w lewym górnym rogu.
Rysunek 14. Bufor obrazu obrócony o 90 stopni w prawo, aby dostosować go do orientacji czujnika tylnego.

Następnie bufor jest obracany o 270 stopni w lewo, aby uwzględnić obrót urządzenia:

Czujnik aparatu obrócony do orientacji poziomej z obrazem w pionie.
Rysunek 15. Bufor obrazu po obróceniu o 270 stopni w lewo w celu dostosowania do orientacji urządzenia.

Format obrazu

Format obrazu zmienia się, gdy zmienia się orientacja urządzenia, ale także gdy urządzenia składane są składane i rozkładane, gdy zmienia się rozmiar okien w środowiskach z wieloma oknami i gdy aplikacje otwierają się na dodatkowych wyświetlaczach.

Bufor obrazu czujnika aparatu musi być zorientowany i skalowany tak, aby odpowiadał orientacji i formatowi obrazu elementu interfejsu wizjera, gdy interfejs dynamicznie zmienia orientację – niezależnie od tego, czy urządzenie zmienia orientację.

Jeśli w przypadku nowych formatów lub środowisk z wieloma oknami lub wyświetlaczami aplikacja zakłada, że podgląd z aparatu ma taką samą orientację jak urządzenie (pionową lub poziomą), podgląd może być nieprawidłowo zorientowany lub przeskalowany.

Rozłożone urządzenie składane z podglądem z aparatu w orientacji pionowej obróconym na bok.
Rysunek 16. Urządzenie składane przechodzi z orientacji pionowej do poziomej, ale czujnik aparatu pozostaje w orientacji pionowej.

Na rysunku 16 aplikacja błędnie założyła, że urządzenie zostało obrócone o 90 stopni w lewo, i obróciła podgląd o tę samą wartość.

Rozłożone urządzenie składane z podglądem z aparatu w orientacji pionowej, ale ściśniętym z powodu nieprawidłowego skalowania.
Rysunek 17. Urządzenie składane przechodzi z orientacji pionowej do poziomej z nieprawidłowo przeskalowanym podglądem z aparatu.

Na rysunku 17 aplikacja nie dostosowała formatu obrazu bufora, aby umożliwić prawidłowe skalowanie do nowych wymiarów elementu interfejsu podglądu z aparatu.

Aplikacje do obsługi aparatu o stałej orientacji zwykle mają problemy na urządzeniach składanych i innych urządzeniach z dużym ekranem, takich jak laptopy:

Podgląd z aparatu na laptopie jest w pionie, ale interfejs aplikacji jest obrócony.
Rysunek 18. Aplikacja w orientacji pionowej na laptopie.

Na rysunku 18 interfejs aplikacji aparatu jest obrócony, ponieważ orientacja aplikacji jest ograniczona do pionowej. Obraz w wizjerze jest prawidłowo zorientowany względem matrycy aparatu.

Tryb portretowy wstawki

Aplikacje do obsługi aparatu, które nie obsługują trybu wielu okien (resizeableActivity="false") i ograniczają orientację (screenOrientation="portrait" lub screenOrientation="landscape"), można umieścić w trybie portretowym na urządzeniach z dużym ekranem, aby prawidłowo ustawić podgląd z aparatu.

Wstawiony tryb portretowy wyświetla aplikacje tylko w orientacji pionowej, nawet jeśli format obrazu jest poziomy. Aplikacje działające tylko w orientacji poziomej są wyświetlane w trybie letterbox w orientacji poziomej, mimo że format obrazu wyświetlacza jest pionowy. Obraz z kamery jest obracany, aby dopasować go do interfejsu aplikacji, przycinany do formatu obrazu podglądu z kamery, a następnie skalowany, aby wypełnić podgląd.

Tryb portretowy z wstawką jest aktywowany, gdy format obrazu czujnika obrazu aparatu i format obrazu głównej aktywności aplikacji nie są zgodne.

Podgląd z aparatu i interfejs aplikacji w prawidłowej orientacji pionowej na laptopie.
            Szeroki obraz podglądu jest skalowany i przycinany, aby pasował do orientacji pionowej.
Rysunek 19. Aplikacja w orientacji pionowej o stałej orientacji w trybie portretowym na laptopie.

Na rysunku 19 aplikacja aparatu, która działa tylko w orientacji pionowej, została obrócona, aby interfejs był wyświetlany na ekranie laptopa w orientacji pionowej. Aplikacja jest wyświetlana w formacie letterbox ze względu na różnicę w formacie obrazu między aplikacją w orientacji pionowej a wyświetlaczem w orientacji poziomej. Obraz podglądu z aparatu został obrócony, aby skompensować obrót interfejsu aplikacji (z powodu trybu portretowego), a obraz został przycięty i przeskalowany, aby pasował do orientacji pionowej, co zmniejszyło pole widzenia.

Obracanie, przycinanie, skalowanie

Tryb portretowy w ramce jest wywoływany w przypadku aplikacji aparatu działającej tylko w trybie portretowym na wyświetlaczu o poziomym formacie obrazu:

Podgląd z aparatu na laptopie jest w pionie, ale interfejs aplikacji jest obrócony.
Rysunek 20. Aplikacja w orientacji pionowej na laptopie.

Aplikacja jest wyświetlana w orientacji pionowej z czarnymi pasami:

Aplikacja została obrócona do orientacji pionowej i wyświetlona w formacie letterbox. Obraz jest obrócony na bok, góra jest po prawej stronie.
Rysunek 21. Aplikacja działająca tylko w orientacji pionowej obrócona i wyświetlana w formacie letterbox na ekranie poziomym przed obrotem obrazu z czujnika.

Obraz z kamery jest obracany o 90 stopni, aby dostosować go do zmiany orientacji aplikacji:

Obraz z czujnika obrócony o 90 stopni, aby był w pionie.
Rysunek 22. Obraz z kamery obrócony o 90 stopni, aby dopasować go do interfejsu aplikacji.

Obraz jest przycinany do formatu obrazu podglądu z aparatu, a następnie skalowany, aby wypełnić podgląd (pole widzenia jest zmniejszone):

Przycięty obraz z kamery przeskalowany tak, aby wypełniał podgląd.
Rysunek 23. Obraz z aparatu jest przycięty i przeskalowany, aby wypełnić podgląd z aparatu w orientacji pionowej.

Na urządzeniach składanych czujnik aparatu może być ustawiony w orientacji pionowej, podczas gdy format obrazu wyświetlacza jest poziomy:

Podgląd z aparatu i interfejs aplikacji obrócone na bok na szerokim, rozłożonym wyświetlaczu.
Rysunek 24. Rozłożone urządzenie z aplikacją aparatu działającą tylko w orientacji pionowej i różnymi formatami obrazu czujnika aparatu i wyświetlacza.

Podgląd z aparatu jest obracany, aby dostosować go do orientacji czujnika, więc obraz w wizjerze jest prawidłowo zorientowany, ale aplikacja działająca tylko w trybie pionowym jest obrócona na bok.

W trybie portretowym z wstawką wystarczy dodać pasy do aplikacji w orientacji pionowej, aby prawidłowo ustawić aplikację i podgląd z aparatu:

Aplikacja w formacie letterbox w orientacji pionowej z podglądem z aparatu w orientacji pionowej na urządzeniu składanym.
Rysunek 25. Aplikacja działająca tylko w trybie portretowym wyświetlana w trybie letterbox w trybie portretowym na rozłożonym urządzeniu składanym.

Interfejs API

Od Androida 12 (poziom API 31) aplikacje mogą też bezpośrednio kontrolować tryb portretowy z wcięciem za pomocą właściwości SCALER_ROTATE_AND_CROP klasy CaptureRequest.

Wartością domyślną jest SCALER_ROTATE_AND_CROP_AUTO, co umożliwia systemowi wywoływanie trybu portretowego w ramce. SCALER_ROTATE_AND_CROP_90 to zachowanie trybu portretowego z obrazem wstawionym, opisane wcześniej.

Nie wszystkie urządzenia obsługują wszystkie wartości SCALER_ROTATE_AND_CROP. Listę obsługiwanych wartości znajdziesz w CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES.

CameraX

Biblioteka Jetpack CameraX ułatwia tworzenie wizjera aparatu, który dostosowuje się do orientacji czujnika i obrotu urządzenia.

Element układu PreviewView tworzy podgląd z kamery, automatycznie dostosowując orientację czujnika, obrót urządzenia i skalowanie. PreviewView zachowuje format obrazu z kamery, stosując typ skalowania FILL_CENTER, który wyśrodkowuje obraz, ale może go przyciąć, aby dopasować go do wymiarów PreviewView. Aby dodać czarne pasy do obrazu z kamery, ustaw typ skali na FIT_CENTER.

Aby poznać podstawy tworzenia podglądu z kamery za pomocą PreviewView, przeczytaj artykuł Implementowanie podglądu.

Pełną przykładową implementację znajdziesz w repozytorium CameraXBasic na GitHubie.

CameraViewfinder

Podobnie jak w przypadku podglądu biblioteka CameraViewfinder udostępnia zestaw narzędzi, które upraszczają tworzenie podglądu z aparatu. Nie zależy od CameraX Core, dzięki czemu można go bezproblemowo zintegrować z istniejącą bazą kodu Camera2.

Zamiast używać bezpośrednio Surface, możesz użyć widżetu CameraViewfinder, aby wyświetlić przekaz z kamery w Camera2.

CameraViewfinder wewnętrznie używa TextureView lub SurfaceView do wyświetlania przekazu z kamery i stosuje do nich wymagane przekształcenia, aby prawidłowo wyświetlać wizjer. Obejmuje to korektę formatu obrazu, skali i obrotu.

Aby poprosić o powierzchnię z obiektu CameraViewfinder, musisz utworzyć ViewfinderSurfaceRequest.

To żądanie zawiera wymagania dotyczące rozdzielczości powierzchni i informacje o urządzeniu z aparatem z CameraCharacteristics.

Wywołanie requestSurfaceAsync() wysyła żądanie do dostawcy platformy, którym jest TextureView lub SurfaceView, i otrzymuje ListenableFuture Surface.

Wywołanie metody markSurfaceSafeToRelease() powiadamia dostawcę powierzchni, że powierzchnia nie jest potrzebna i powiązane zasoby można zwolnić.

fun startCamera() {
    val previewResolution = Size(width, height)
    val viewfinderSurfaceRequest =
        ViewfinderSurfaceRequest(previewResolution, characteristics)
    val surfaceListenableFuture =
        cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest)

    Futures.addCallback(surfaceListenableFuture, object : FutureCallback<Surface> {
        override fun onSuccess(surface: Surface) {
            /* create a CaptureSession using this surface as usual */
        }
        override fun onFailure(t: Throwable) { /* something went wrong */ }
    }, ContextCompat.getMainExecutor(context))
}

SurfaceView

SurfaceView to proste podejście do tworzenia podglądu z kamery, jeśli nie wymaga on przetwarzania i nie jest animowany.

SurfaceView automatycznie obraca bufor obrazu czujnika aparatu, aby dopasować go do orientacji wyświetlacza, uwzględniając zarówno orientację czujnika, jak i obrót urządzenia. Jednak bufor obrazu jest skalowany tak, aby pasował do wymiarów SurfaceView bez uwzględniania formatu obrazu.

Musisz się upewnić, że format obrazu bufora obrazu jest zgodny z formatem obrazu SurfaceView. Możesz to zrobić, skalując zawartość SurfaceView w metodzie onMeasure() komponentu:

(Kod źródłowy computeRelativeRotation() znajduje się poniżej w sekcji Względny obrót).

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    val width = MeasureSpec.getSize(widthMeasureSpec)
    val height = MeasureSpec.getSize(heightMeasureSpec)

    val relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees)

    if (previewWidth > 0f && previewHeight > 0f) {
        /* Scale factor required to scale the preview to its original size on the x-axis. */
        val scaleX =
            if (relativeRotation % 180 == 0) {
                width.toFloat() / previewWidth
            } else {
                width.toFloat() / previewHeight
            }
        /* Scale factor required to scale the preview to its original size on the y-axis. */
        val scaleY =
            if (relativeRotation % 180 == 0) {
                height.toFloat() / previewHeight
            } else {
                height.toFloat() / previewWidth
            }

        /* Scale factor required to fit the preview to the SurfaceView size. */
        val finalScale = min(scaleX, scaleY)

        setScaleX(1 / scaleX * finalScale)
        setScaleY(1 / scaleY * finalScale)
    }
    setMeasuredDimension(width, height)
}

Więcej informacji o implementowaniu SurfaceView jako podglądu z kamery znajdziesz w artykule o orientacjach kamery.

TextureView

TextureView jest mniej wydajny niż SurfaceView i wymaga więcej pracy, ale TextureView zapewnia maksymalną kontrolę nad podglądem z kamery.

TextureView obraca bufor obrazu czujnika na podstawie orientacji czujnika, ale nie obsługuje obracania urządzenia ani skalowania podglądu.

Skalowanie i obrót można zakodować w przekształceniu Matrix. Aby dowiedzieć się, jak prawidłowo skalować i obracać TextureView, przeczytaj artykuł o obsłudze powierzchni o zmiennym rozmiarze w aplikacji aparatu.

Obrót względny

Względny obrót czujnika aparatu to stopień obrotu wymagany do wyrównania obrazu z czujnika aparatu z orientacją urządzenia.

Względny obrót jest używany przez komponenty takie jak SurfaceView i TextureView do określania współczynników skalowania x i y obrazu podglądu. Służy też do określania obrotu bufora obrazu czujnika.

Klasy CameraCharacteristics i Surface umożliwiają obliczenie względnego obrotu czujnika aparatu:

/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public fun computeRelativeRotation(
    characteristics: CameraCharacteristics,
    surfaceRotationDegrees: Int
): Int {
    val sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0

    // Reverse device orientation for back-facing cameras.
    val sign = if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT
    ) 1 else -1

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360
}

Dane dotyczące okna

Rozmiar ekranu nie powinien być używany do określania wymiarów wizjera aparatu. Aplikacja aparatu może działać na części ekranu, w trybie wielu okien na urządzeniach mobilnych lub w trybie swobodnym w ChromeOS.

WindowManager#getCurrentWindowMetrics() (dodana na poziomie API 30) zwraca rozmiar okna aplikacji, a nie rozmiar ekranu. Metody biblioteki Jetpack WindowManager WindowMetricsCalculator#computeCurrentWindowMetrics() i WindowInfoTracker#currentWindowMetrics() zapewniają podobną obsługę ze zgodnością wsteczną do poziomu interfejsu API 14.

Obrót o 180 stopni

Obrócenie urządzenia o 180 stopni (np. z orientacji naturalnej do orientacji naturalnej do góry nogami) nie wywołuje wywołania zwrotnego onConfigurationChanged(). W efekcie podgląd z aparatu może być odwrócony do góry nogami.

Aby wykryć obrót o 180 stopni, zaimplementuj DisplayListener i sprawdź obrót urządzenia, wywołując Display#getRotation() w wywołaniu zwrotnym onDisplayChanged().

Zasoby na wyłączność

Przed Androidem 10 tylko najwyższa widoczna aktywność w środowisku z wieloma oknami była w stanie RESUMED. Było to mylące dla użytkowników, ponieważ system nie wskazywał, która aktywność została wznowiona.

W Androidzie 10 (poziom API 29) wprowadzono jednoczesne wznowienie, w którym wszystkie widoczne aktywności są w stanie RESUMED. Widoczne aktywności mogą nadal przejść w stan PAUSED, jeśli na przykład nad aktywnością znajduje się aktywność przezroczysta lub aktywność nie może być aktywna, np. w trybie obrazu w obrazie (patrz Obsługa obrazu w obrazie).

Aplikacja korzystająca z kamery, mikrofonu lub dowolnego zasobu wyłącznego lub pojedynczego na poziomie API 29 lub wyższym musi obsługiwać jednoczesne wznowienie. Jeśli na przykład 3 wznowione aktywności chcą używać aparatu, tylko jedna z nich może uzyskać dostęp do tego zasobu na wyłączność. Każda aktywność musi implementować wywołanie zwrotne onDisconnected(), aby otrzymywać informacje o wywłaszczającym dostępie do aparatu przez aktywność o wyższym priorytecie.

Więcej informacji znajdziesz w artykule na temat jednoczesnego wznowienia.

Dodatkowe materiały

  • Przykład użycia Camera2 znajdziesz w aplikacji Camera2Basic na GitHubie.
  • Więcej informacji o przypadku użycia podglądu CameraX znajdziesz w artykule Implement a preview (Implementowanie podglądu) w CameraX.
  • Przykładową implementację podglądu z aparatu CameraX znajdziesz w repozytorium CameraXBasic na GitHubie.
  • Informacje o podglądzie z kamery w ChromeOS znajdziesz w artykule na temat orientacji kamery.
  • Więcej informacji o tworzeniu aplikacji na urządzenia składane znajdziesz w artykule Informacje o urządzeniach składanych.