Podgląd z aparatu

Uwaga: ta strona dotyczy pakietu Aparat2. Jeśli Twoja aplikacja nie wymaga konkretnych, niskopoziomowych funkcji z Aparatu 2, zalecamy używanie AparatuX. Aparaty CameraX i Aparat 2 obsługują Androida 5.0 (poziom interfejsu API 21) i nowsze wersje.

Podglądy aparatów i aparatów nie zawsze mają tę samą orientację na Androidzie urządzenia.

Kamera na urządzeniu jest w stałym położeniu niezależnie od tego, czy to telefon, tablet lub komputer. Gdy orientacja urządzenia ulegnie zmianie, zmiany orientacji aparatu.

W związku z tym aplikacje aparatu zwykle przyjmują stałą relację między od orientacji urządzenia i formatu obrazu podglądu z aparatu. Gdy telefonu jest w orientacji pionowej, podgląd aparatu zakłada, że jest wyższy. niż ma szerokość. Gdy telefon (i aparat) ustawisz poziomo, obraz z aparatu powinien być szerszy niż wyższy.

Te założenia podważają jednak nowe formaty, takie jak urządzenia składane urządzeń i trybów wyświetlania na przykład wiele okien oraz Wiele ekranów. Urządzenia składane zmieniają rozmiar wyświetlacza i format obrazu bez zmian orientacji ekranu. Tryb wielu okien ogranicza aplikacje aparatu do części na ekranie, skalując podgląd z aparatu niezależnie od orientacji urządzenia. Tryb wielu wyświetlaczy umożliwia korzystanie z ekranów dodatkowych, które mogą nie musi mieć tę samą orientację co główny wyświetlacz.

Orientacja aparatu

Definicja zgodności z Androidem określa, że czujnik obrazu „MUSI być zorientowany tak, aby długi i długości ekranu. Oznacza to, że gdy urządzenie jest ustawione poziomo, aparat MUSI robić zdjęcia do orientacji poziomej. Działa to niezależnie od naturalnych ustawień, orientacja; Dotyczy to zarówno urządzeń w orientacji poziomej, w orientacji pionowej.

Układ kamery i ekranu maksymalizuje obszar wyświetlania kamery wizjer w aplikacji aparatu. Ponadto czujniki obrazu zwykle zapisują dane w format obrazu w orientacji poziomej, gdzie najczęściej jest używany format 4:3.

Czujnik telefonu i aparatu są w orientacji pionowej.
Rysunek 1. Typowy związek między czujnikiem telefonu i aparatu orientacji ekranu.

Czujnik aparatu ma naturalną orientację poziomą. Na ilustracji 1 czujnik przedniego aparatu (skieruj aparat w tym samym kierunku co wyświetlacza) jest obracany o 270 stopni względem telefonu, aby zapewnić Definicja zgodności z Androidem.

Aby ujawnić obrót czujnika aplikacjom, Interfejs API camera2 obejmuje SENSOR_ORIENTATION. jest stała. W przypadku większości telefonów i tabletów urządzenie zgłasza orientację czujnika. 270 stopni dla przedniego aparatu i 90 stopni dla tylnej części urządzenia, aby zapewnić jej dłuższą krawędź. przylegaj do dłuższej krawędzi urządzenia. Laptopy zazwyczaj zgłaszają od 0 do 180 stopni.

Czujniki obrazu z aparatu zapisują dane (bufor obrazu) w w naturalnej orientacji czujnika (poziomo), bufor obrazu należy obracać liczba stopni określonej przez SENSOR_ORIENTATION na podgląd z aparatu wyświetlają się pionowo w naturalnej orientacji. W przypadku aparatów przednich obraca się w lewo; dla aparatów z tyłu, w prawo.

Na przykład w przypadku przedniego aparatu na ilustracji 1 buforowanie obrazu generowany przez czujnik aparatu wygląda tak:

Czujnik aparatu został obrócony do orientacji poziomej ze zdjęciem
            bokiem w lewym górnym rogu.

Obraz musi być obrócony o 270 stopni w lewo, aby podgląd orientacja odpowiada orientacji urządzenia:

Czujnik aparatu w orientacji pionowej z obrazem pionowo.

Tylny aparat mógłby wygenerować bufor obrazu w tej samej orientacji. jako bufor powyżej, ale SENSOR_ORIENTATION ma 90 stopni. W rezultacie bufor jest obrócony o 90 stopni w prawo.

Obracanie urządzenia

Obrót urządzenia to liczba stopni obrócenia urządzenia orientacji ekranu. Na przykład telefon w orientacji poziomej 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 obrotu urządzenia (oprócz stopni pochylenia czujnika) w by podgląd z aparatu był ustawiony pionowo.

Obliczanie orientacji

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

Ogólny obrót bufora obrazu czujnika można obliczyć za pomocą funkcji następujący wzór:

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

gdzie sign to 1 – przednie aparaty, -1 – aparat tylny.

W przypadku aparatów przednich bufor obrazu jest obracany w lewo (od naturalnej orientacji czujnika). W przypadku aparatów tylnych bufor obrazu jest obrócony w prawo.

Wyrażenie deviceOrientationDegrees * sign + 360 konwertuje obrót urządzenia z tyłu na przeciwnie do ruchu wskazówek zegara dla aparatów z tyłu (na przykład możesz zmienić 270 stopni w lewo na 90 stopni w prawo). Modulo skaluje wynik do 360 stopni (na przykład skalowanie do 540 stopni) stopni obrotu do 180 stopni).

Różne interfejsy API raportują rotację urządzeń w różny sposób:

Przednie aparaty

Podgląd z aparatu i czujnik w orientacji poziomej, czujnik
            jest od prawej do góry.
Rysunek 2. Podgląd z aparatu i czujnik z telefonem obróconym o 90 stopni w w orientacji poziomej.

Na ilustracji 2 pokazujemy bufor obrazu wygenerowany przez czujnik aparatu:

Czujnik aparatu w orientacji poziomej z obrazem pionowo.

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

Czujnik aparatu został obrócony do orientacji pionowej z obrazem obróconym poziomo.
            w prawym górnym rogu.

Następnie bufor jest obrócony o dodatkowe 90 stopni w lewo, biorąc pod uwagę obrót urządzenia, co spowoduje uzyskanie prawidłowej orientacji podgląd aparatu na ilustracji 2:

Czujnik aparatu został obrócony do orientacji poziomej ze zdjęciem
            pionowo.

Oto obraz obrócony w prawo i poziomo:

Podgląd z aparatu i czujnik są w orientacji poziomej, ale
            jest do góry nogami.
Rysunek 3. Podgląd z aparatu i czujnik z telefonem o 270 stopniach (lub -90 stopni) do orientacji poziomej.

Bufor obrazu:

Czujnik aparatu został obrócony do orientacji poziomej z obrazem do góry
            w dół.

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

Czujnik aparatu w orientacji pionowej z obrazem bokiem
            w lewym górnym rogu.

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

Czujnik aparatu został obrócony do orientacji poziomej ze zdjęciem
            pionowo.

Tylne kamery

Tylne aparaty mają zazwyczaj orientację 90 stopni widoczne z tyłu urządzenia). Podczas ustawiania podglądu z aparatu funkcja bufor obrazu czujnika jest obrócony w prawo zgodnie z intensywnością obrotu czujnika (a nie w lewo, jak w przypadku przednich aparatów), a następnie obraz bufor jest obrócony w lewo zgodnie z obrotem urządzenia.

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

Na ilustracji 4 widać bufor obrazu z czujnika aparatu:

Czujnik aparatu został obrócony do orientacji poziomej z obrazem do góry
            w dół.

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

Czujnik aparatu w orientacji pionowej z obrazem bokiem
            w lewym górnym rogu.

Następnie bufor obraca się o 270 stopni w lewo, by uwzględnić rotacja:

Czujnik aparatu został obrócony do orientacji poziomej ze zdjęciem
            pionowo.

Format obrazu

Współczynnik proporcji wyświetlacza zmienia się wraz ze zmianą orientacji urządzenia, ale także wtedy, gdy urządzenia składane można składać i rozwijać, gdy rozmiar okien zmienia się w trybie wielu okien. i otwierają się na dodatkowych ekranach.

Bufor obrazu z czujnika aparatu musi być zorientowany i przeskalowany tak, aby orientacja i współczynnik proporcji elementu interfejsu wizjera. dynamicznie zmienia orientację – niezależnie od tego, czy zmienia się urządzenie orientacji ekranu.

W przypadku nowych formatów, trybów z wieloma oknami i różnymi wyświetlaczami, jeśli aplikacja przyjmuje, że podgląd z aparatu ma taką samą orientację jak urządzenie (pionowej lub poziomej) podgląd może mieć nieprawidłową orientację lub przeskalowanie nieprawidłowo lub jedno i drugie.

Rozłożone urządzenie składane z włączonym podglądem aparatu w orientacji pionowej
            obrócone.
Rysunek 5. Urządzenie składane zmienia orientację z pionowej na poziomą. ma format obrazu, ale czujnik w aparacie jest w orientacji pionowej.

Na ilustracji 5 aplikacja błędnie uznała, że urządzenie zostało obrócone o 90 stopni. stopni w lewo; więc aplikacja obróciła podgląd tyle samo.

Rozłożone, składane urządzenie z podglądem aparatu pionowo, ale ściśnięte
            z powodu nieprawidłowego skalowania.
Rysunek 6. Urządzenie składane zmienia orientację z pionowej na poziomą. ma format obrazu, ale czujnik w aparacie jest w orientacji pionowej.

Na ilustracji 6 aplikacja nie dostosowała formatu obrazu bufora do włącz jego odpowiednie skalowanie, aby pasowało do nowych wymiarów interfejsu podglądu aparatu. .

W aplikacjach o stałej orientacji ekranu zazwyczaj występują problemy na urządzeniach składanych i na innych urządzeniach z dużym ekranem, takich jak laptopy:

Podgląd z aparatu na laptopie jest ustawiony pionowo, ale interfejs aplikacji jest obrócony.
Rysunek 7. Aplikacja do orientacji pionowej na laptopie.

Na ilustracji 7 interfejs aplikacji aparatu jest obrócony, ponieważ orientacja aplikacji jest ograniczona tylko do orientacji pionowej. Obraz w wizjerze ma prawidłową orientację względem czujnika aparatu.

Tryb wstawki w orientacji pionowej

aplikacje aparatu, które nie obsługują trybu wielu okien; (resizeableActivity="false") i ograniczyć orientację, (screenOrientation="portrait") lub screenOrientation="landscape") można umieścić w orientacji pionowej na urządzeniach z dużym ekranem, aby zapewnić ich odpowiednią orientację podgląd z aparatu.

Aplikacje tylko w orientacji pionowej w trybie pionowym nawet jeśli jest ustawiony w orientacji poziomej. W przypadku aplikacji tylko w orientacji poziomej są wyświetlane czarne pasy, mimo że format obrazu jest pionowy. Obraz z aparatu jest obrócony w celu wyrównania z interfejsem aplikacji, przycięte tak, aby pasowały do formatu obrazu podglądu z aparatu, a następnie przeskalowany, by wypełnić podgląd.

Tryb wstawienia obrazu pionowego jest wyzwalany po wybraniu formatu obrazu z aparatu z czujnikiem i współczynnikiem proporcji głównej aktywności aplikacji nie są zgodne.

Podgląd z aparatu i interfejs aplikacji na laptopie w prawidłowej orientacji pionowej.
            Szeroki obraz podglądu jest skalowany i przycięty, aby pasował do orientacji pionowej
            orientacji ekranu.
Rysunek 8. Aplikacja do orientacji pionowej w orientacji pionowej i włączona laptopa.

Na ilustracji 8 obrócono aplikację aparatu w orientacji pionowej, aby wyświetlić interfejs. pionowo na wyświetlaczu laptopa. W aplikacji pojawiają się czarne pasy z powodu różnicy proporcje między aplikacją w orientacji pionowej a ekranem w orientacji poziomej. Aparat obraz podglądu został obrócony w celu skompensowania obrócenia interfejsu aplikacji (w wyniku w trybie pionowym), a obraz został przycięty i przeskalowany do orientacji pionowej, co zmniejszy pole widzenia.

Obracanie, przycinanie, skalowanie

Tryb wstawki w orientacji pionowej jest wywoływany w przypadku aplikacji aparatu przeznaczonego tylko do wyświetlania w orientacji pionowej na ekranie w orientacji poziomej:

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

Aplikacja ma poziome pasy w orientacji pionowej:

Aplikacja została obrócona do orientacji pionowej z czarnymi pasami. Obraz to
            od prawej do lewej.

Obraz z kamery jest obrócony o 90 stopni, aby dostosować aplikacja:

Obraz z czujnika został obrócony o 90 stopni, aby ustawić go pionowo.

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

Przycięty obraz z aparatu został przeskalowany, aby wypełnić podgląd z aparatu.

W przypadku urządzeń składanych czujnik może być w orientacji pionowej. a wyświetlacz jest w orientacji poziomej:

Podgląd z aparatu i interfejs aplikacji obrócone na boki na szerokim, rozłożonym wyświetlaczu.
Rysunek 10. Rozłożone urządzenie z aplikacją do obsługi kamery tylko w orientacji pionowej w różnych proporcjach obrazu czujnika i wyświetlacza.

Podgląd z aparatu jest obracany w celu dostosowania się do orientacji czujnika, Zdjęcie jest właściwie zorientowane w wizjerze, ale aplikacja tylko do wyświetlania w orientacji pionowej jest obrócone.

Wbudowany tryb pionowy wymaga tylko dodania czarnych pasów do aplikacji w orientacji pionowej aby zapewnić prawidłową orientację aplikacji i podglądu z aparatu:

Aplikacja Letterbox w orientacji pionowej z podglądem z aparatu
            pionowo na urządzeniu składanym.

Interfejs API

Od Androida 12 (poziom interfejsu API 31) aplikacje mogą też bezpośrednio sterować obrazem w orientacji pionowej za pomocą SCALER_ROTATE_AND_CROP właściwość CaptureRequest zajęcia.

Wartość domyślna to SCALER_ROTATE_AND_CROP_AUTO który umożliwia systemowi wywoływanie trybu wstawienia w pionie. SCALER_ROTATE_AND_CROP_90 jak działa wbudowana orientacja pionowa.

Nie wszystkie urządzenia obsługują wszystkie wartości SCALER_ROTATE_AND_CROP. Aby uzyskać listę obsługiwanych wartości, odwołanie CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES

Aparat X

biblioteka Jetpack CameraX, umożliwia stworzenie wizjera aparatu pasującego do orientacji czujnika to proste zadanie.

Element układu PreviewView tworzy podgląd z aparatu, automatycznie dostosowując się do orientacji czujnika, obrót i skalowanie urządzenia. PreviewView zachowuje format obrazu i obrazu z aparatu, stosując FILL_CENTER typ skali, który wyśrodkowuje obraz, ale może go przyciąć w celu dopasowania do wymiarów PreviewView. Aby obraz z aparatu był w formie czarnych pasów, ustaw typ skali na FIT_CENTER

Podstawowe informacje na temat tworzenia podglądu z kamery w PreviewView znajdziesz w tych artykułach: Zaimplementuj podgląd.

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

Wizjer aparatu

Podobnie jak w przypadku użycia funkcji Podgląd, wizjer aparatu. biblioteka udostępnia zestaw narzędzi ułatwiających tworzenie podglądu z aparatu. Nie wymaga ona modelu CameraX Core, więc możesz płynnie zintegrować go istniejącą bazę kodu Camera2.

Zamiast używać atrybutu Surface bezpośrednio, możesz użyć funkcji CameraViewfinder widżet do wyświetlania obrazu z kamery Aparat2.

Funkcja CameraViewfinder wewnętrznie używa TextureView lub SurfaceView aby wyświetlić obraz z kamery i zastosować wymagane przekształcenia poprawnie wyświetlać wizjer. Wiąże się to z skorygowaniem formatu obrazu, skali i obrotu.

Aby poprosić o powierzchnię z obiektu CameraViewfinder, musisz utwórz element ViewfinderSurfaceRequest.

To żądanie zawiera wymagania dotyczące rozdzielczości powierzchni i aparatu informacje z: CameraCharacteristics.

Dzwonię pod numer requestSurfaceAsync() wysyła żądanie do dostawcy powierzchni, którym jest TextureView lub SurfaceView i otrzymuje ListenableFuture o wartości Surface.

Dzwonię pod numer markSurfaceSafeToRelease() powiadamia dostawcę powierzchni, że nie jest ona potrzebna i jest powiązana zasobów, które można zwolnić.

Kotlin


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))
}

Java


    void startCamera(){
        Size previewResolution = new Size(width, height);
        ViewfinderSurfaceRequest viewfinderSurfaceRequest =
                new ViewfinderSurfaceRequest(previewResolution, characteristics);
        ListenableFuture<Surface> surfaceListenableFuture =
                cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest);

        Futures.addCallback(surfaceListenableFuture, new FutureCallback<Surface>() {
            @Override
            public void onSuccess(Surface result) {
                /* create a CaptureSession using this surface as usual */
            }
            @Override public void onFailure(Throwable t) { /* something went wrong */}
        },  ContextCompat.getMainExecutor(context));
    }

SurfaceView

SurfaceView to do podglądu z aparatu, jeśli podgląd wymagają przetworzenia i nie jest animowany.

SurfaceView automatycznie obraca bufor obrazu z czujnika aparatu, aby dopasować orientacji wyświetlacza, uwzględniając zarówno orientację czujnika, i rotacji. Bufor obrazu jest jednak skalowany tak, aby pasował do: SurfaceView bez uwzględniania formatu obrazu.

Musisz się upewnić, że format bufora obrazu jest zgodny z formatem współczynnika SurfaceView, którą można uzyskać, skalując zawartość z SurfaceView w komponencie onMeasure() :

(Kod źródłowy computeRelativeRotation() znajduje się w Rotacja względna poniżej).

Kotlin

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)
}

Java

@Override
void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    int relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees);

    if (previewWidth > 0f && previewHeight > 0f) {

        /* Scale factor required to scale the preview to its original size on the x-axis. */
        float scaleX = (relativeRotation % 180 == 0)
                       ? (float) width / previewWidth
                       : (float) width / previewHeight;

        /* Scale factor required to scale the preview to its original size on the y-axis. */
        float scaleY = (relativeRotation % 180 == 0)
                       ? (float) height / previewHeight
                       : (float) height / previewWidth;

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

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

Więcej informacji o implementowaniu funkcji SurfaceView w trybie podglądu aparatu znajdziesz tutaj: Orientacje aparatu.

Widok tekstury

TextureView jest mniej wydajny niż SurfaceView – i więcej pracy – ale TextureView daje Ci maksimum nad podglądem z aparatu.

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

Skalowanie i obrót można zakodować Transformacja matrycy. Aby dowiedzieć się, jak: poprawnie przeskalować i obrócić TextureView, patrz Obsługa powierzchni z możliwością zmiany rozmiaru w aplikacji Aparat

Rotacja względna

Względny obrót czujnika aparatu to wartość obrotu wymagana do dopasuj dane wyjściowe czujnika aparatu do orientacji urządzenia.

Obrót względny jest używany przez komponenty takie jak SurfaceView i TextureView w celu określenia współczynników skalowania x i y dla obrazu podglądu. Jest też używany do i określić obrót bufora obrazu czujnika.

CameraCharacteristics oraz Zajęcia Surface umożliwiają obliczenie: względna obrót czujnika aparatu:

Kotlin

/**
 * 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)!!

    // 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
}

Java

/**
 * 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 int computeRelativeRotation(
    CameraCharacteristics characteristics,
    int surfaceRotationDegrees
){
    Integer sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);

    // Reverse device orientation for back-facing cameras.
    int sign = characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT ? 1 : -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 okien

Rozmiar ekranu nie powinien być stosowany do określania wymiarów kamery wizjer; aplikacja aparatu może być uruchomiona na części ekranu w trybie wielu okien na urządzeniach mobilnych lub w trybie Free-from w ChromeOS.

WindowManager#getCurrentWindowMetrics() (dodane na poziomie interfejsu API 30) zwraca rozmiar okna aplikacji, a nie do rozmiaru ekranu. Metody biblioteki Jetpack WindowManager WindowMetricsCalculator#computeCurrentWindowMetrics() oraz WindowInfoTracker#currentWindowMetrics() zapewniają podobną pomoc dzięki zgodności wstecznej z interfejsem API poziomu 14.

Obrót o 180 stopni

Obrót urządzenia o 180 stopni (na przykład z orientacji naturalnej do naturalnej orientacji do góry nogami) nie powoduje onConfigurationChanged() oddzwanianie. W związku z tym podgląd z aparatu może być do góry nogami.

Aby wykryć obrót o 180 stopni, zaimplementuj funkcję DisplayListener i sprawdź obrót urządzenia, wysyłając wywołanie do Display#getRotation() w onDisplayChanged() oddzwanianie.

Wyjątkowe materiały

Przed Androidem 10 tylko najbardziej widoczna aktywność w trybie wielu okien środowisko było w stanie RESUMED. Było to mylące dla użytkowników, ponieważ system nie wskaże, która aktywność została wznowiona.

W Androidzie 10 (poziom interfejsu API 29) wprowadzono wielokrotne wznawianie, w których wszystkie widoczne działania są w stanie RESUMED. Widoczne aktywności nadal mogą trafiać do pola PAUSED jeśli na przykład nad działaniem znajduje się przezroczysta aktywność lub aktywności nie można zaznaczyć, na przykład w trybie obrazu w obrazie (patrz Obsługa funkcji obraz w obrazie).

Aplikacja używająca kamery, mikrofonu lub dowolnych bądź innych zasób singleton na poziomie API 29 lub wyższym musi obsługiwać wielokrotne wznawianie. Dla: Jeśli na przykład 3 wznowione działania chcą korzystać z kamery, tylko jedna z nich na dostęp do tego wyjątkowego zasobu. Każde działanie musi implementować onDisconnected() wywołanie zwrotne, aby zwracać uwagę na zapobiegawczy dostęp do kamery przez wyższy priorytet działania.

Więcej informacji: Wielokrotne wznowienie.

Dodatkowe materiały