Kameravorschau

Hinweis:Diese Seite bezieht sich auf das Camera2-Paket. Sofern für Ihre App keine spezifischen Low-Level-Funktionen von Camera2 erforderlich sind, empfehlen wir die Verwendung von CameraX. Sowohl CameraX als auch Camera2 unterstützen Android 5.0 (API-Level 21) und höher.

Kameras und Kameravorschauen sind auf Android-Geräten nicht immer gleich ausgerichtet. Geräte.

Eine Kamera befindet sich auf einem Gerät an einer festen Position, unabhängig davon, ob das Gerät ein Smartphone, Tablet oder Computer ist. Wenn sich die Ausrichtung des Geräts ändert, ändert sich die Kameraausrichtung.

Kamera-Apps gehen daher in der Regel von einer festen Beziehung zwischen den Ausrichtung des Geräts und das Seitenverhältnis der Kameravorschau. Wenn ein Smartphone im Hochformat angezeigt wird, wird für die Kameravorschau angenommen, dass sie größer ist. als breit ist. Wenn das Smartphone (und die Kamera) im Querformat gehalten wird, ist die Kameravorschau voraussichtlich breiter als hoch.

Allerdings werden diese Annahmen durch neue Formfaktoren wie faltbare Smartphones Geräte, und Anzeigemodi wie Mehrfenstermodus und Multi-Display Bei faltbaren Geräten ändern sich die Bildschirmgröße und das Seitenverhältnis, ohne dass sich die Ausrichtung ändert. Im Mehrfenstermodus sind Kamera-Apps auf einen Teil des Bildschirm und skaliert die Kameravorschau unabhängig von der Geräteausrichtung. Im Multi-Display-Modus können Sie sekundäre Displays verwenden, die sich möglicherweise nicht in derselben Ausrichtung wie das primäre Display befinden.

Kameraausrichtung

Gemäß der Android Compatibility Definition muss ein Kamerabildsensor so ausgerichtet sein, dass die lange Dimension der Kamera mit der langen Dimension des Bildschirms übereinstimmt. Das heißt, wenn das Gerät im Querformat gehalten wird, MÜSSEN die Kameras die Bilder Querformat verwenden. Dies gilt unabhängig vom natürlichen Verhalten des Geräts Ausrichtung; d. h. sie gilt für primäre Geräte im Querformat sowie für primäre Geräte im Hochformat“.

Durch die Anordnung der Kamera zum Display wird der Anzeigebereich des Kamerasuchers in einer Kamera-App maximiert. Außerdem geben Bildsensoren ihre Daten in der Regel im Querformat aus, wobei 4:3 am häufigsten ist.

Smartphone- und Kamerasensor im Hochformat.
Abbildung 1. Typische Beziehung zwischen Smartphone- und Kamerasensor Ausrichtung.

Die Standardausrichtung des Kamerasensors ist Querformat. In Abbildung 1 zeigt der Sensor der Frontkamera (die Kamera zeigt in die gleiche Richtung wie die Display) um 270 Grad relativ zum Telefon gedreht wird, um die Android-Kompatibilitätsdefinition

Um Apps die Sensorrotation zu ermöglichen, camera2-API enthält ein SENSOR_ORIENTATION konstant. Bei den meisten Smartphones und Tablets meldet das Gerät eine Sensorausrichtung von 270 Grad für Frontkameras und 90 Grad (Blickwinkel von der Rückseite des Geräts) für Rückkameras. Dabei ist die lange Kante des Sensors mit der langen Kante des Geräts ausgerichtet. Laptopkameras melden in der Regel eine Sensorausrichtung von 0 oder 180 Grad.

Da die Kamerabildsensoren ihre Daten (einen Bildpuffer) in der natürlichen Ausrichtung des Sensors (Querformat) ausgeben, muss der Bildpuffer um die von SENSOR_ORIENTATION angegebene Anzahl von Grad gedreht werden, damit die Kameravorschau in der natürlichen Ausrichtung des Geräts aufrecht angezeigt wird. Bei Frontkameras erfolgt die Drehung gegen den Uhrzeigersinn, bei Rückkameras im Uhrzeigersinn.

Bei der Frontkamera in Abbildung 1 sieht der vom Kamerasensor erzeugte Bildpuffer beispielsweise so aus:

Der Kamerasensor ist ins Querformat gedreht, das Bild ist seitlich, oben links.

Das Bild muss um 270 Grad gegen den Uhrzeigersinn gedreht werden, damit die Ausrichtung der Vorschau der Ausrichtung des Geräts entspricht:

Kamerasensor im Hochformat mit Bild aufrecht.

Eine Rückkamera würde einen Bildpuffer mit derselben Ausrichtung wie der obige Puffer erzeugen, aber SENSOR_ORIENTATION ist 90 Grad. Daher Der Puffer ist um 90 Grad im Uhrzeigersinn gedreht.

Bildschirm drehen

Die Gerätedrehung ist die Gradzahl, um die ein Gerät ausgehend von seinem natürlichen Wert Ausrichtung. Beispiel: Ein Smartphone im Querformat hat ein Gerät Drehung um 90 oder 270 Grad, je nach Drehrichtung.

Ein Kamerasensor-Bildpuffer muss um den gleichen Grad wie der Gerätedrehung (zusätzlich zu den Graden der Sensorausrichtung) für die Kameravorschau so, dass sie aufrecht angezeigt wird.

Ausrichtungsberechnung

Bei der richtigen Ausrichtung der Kameravorschau werden die Sensorausrichtung und die Gerätedrehung berücksichtigt.

Die Gesamtdrehung des Sensorbildpuffers kann mit der folgenden Formel berechnet werden:

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

Dabei ist sign = 1 für Frontkameras und -1 für Rückkameras.

Bei Frontkameras wird der Bildzwischenspeicher gegen den Uhrzeigersinn von der natürlichen Ausrichtung des Sensors). Bei Rückkameras wird der Sensorbildpuffer im Uhrzeigersinn gedreht.

Der Ausdruck deviceOrientationDegrees * sign + 360 wandelt die Gerätedrehung bei Rückkameras von rückwärts (gegen den Uhrzeigersinn) nach vorwärts (im Uhrzeigersinn) um, z. B. 270 Grad rückwärts (gegen den Uhrzeigersinn) in 90 Grad vorwärts (im Uhrzeigersinn). Modulo wird das Ergebnis auf weniger als 360 Grad skaliert (z. B. 540 Grad). Drehung auf 180 Grad).

Die Geräteausrichtung wird von verschiedenen APIs unterschiedlich gemeldet:

  • Display#getRotation() ermöglicht die Drehung des Geräts gegen den Uhrzeigersinn (aus dem Punkt des Nutzers) der Ansicht). Dieser Wert wird unverändert in die obige Formel eingesetzt.
  • OrientationEventListener#onOrientationChanged() gibt die Drehung des Geräts im Uhrzeigersinn zurück (aus der Sicht des Nutzers). Wert zur Verwendung in der obigen Formel negieren.

Frontkameras

Kameravorschau und Sensor sind im Querformat und der Sensor ist richtig herum ausgerichtet.
Abbildung 2: Kameravorschau und Sensor beim Drehen des Smartphones um 90 Grad auf Querformat.

Hier ist der Bildpuffer zu sehen, der vom Kamerasensor in Abbildung 2 erstellt wird:

Kamerasensor im Querformat mit Bild aufrecht.

Der Zwischenspeicher muss für die Anpassung an den Sensor um 270 Grad gegen den Uhrzeigersinn gedreht werden. (siehe Kameraausrichtung oben):

Kamerasensor wurde im Hochformat gedreht, das Bild ist seitlich gedreht
            oben rechts.

Dann wird der Puffer um weitere 90 Grad gegen den Uhrzeigersinn gedreht, Gerätedrehung berücksichtigen, sodass das Display korrekt ausgerichtet ist Kameravorschau in Abbildung 2:

Kamerasensor wurde ins Querformat mit Bild gedreht
            aufrecht zu stellen.

Die Kamera ist von rechts zum Querformat gedreht:

Kameravorschau und Sensor im Querformat, aber
            Sensor ist auf dem Kopf.
Abbildung 3: Kameravorschau und Sensor beim Drehen des Smartphones um 270 Grad (oder -90 Grad) ins Querformat.

Hier ist der Bildpuffer:

Der Kamerasensor wurde ins Querformat gedreht und das Bild ist auf dem Kopf.

Der Zwischenspeicher muss für die Anpassung an den Sensor um 270 Grad gegen den Uhrzeigersinn gedreht werden. Ausrichtung:

Kamerasensor für Porträtausrichtung mit seitlich ausgerichtetem Bild, oben links.

Anschließend wird der Puffer um weitere 270 Grad gegen den Uhrzeigersinn gedreht, um die Gerätedrehung zu berücksichtigen:

Kamerasensor wurde ins Querformat mit Bild gedreht
            aufrecht zu stellen.

Rückkameras

Rückkameras haben in der Regel eine Sensorausrichtung von 90 Grad von der Rückseite des Geräts gesehen werden. Bei der Ausrichtung der Kameravorschau wird der Sensorbildpuffer im Uhrzeigersinn um den Betrag der Sensordrehung gedreht (nicht gegen den Uhrzeigersinn wie bei Frontkameras) und dann um den Betrag der Gerätedrehung gegen den Uhrzeigersinn.

Kameravorschau und Sensor sind beide im Querformat, aber der Sensor ist auf dem Kopf.
Abbildung 4: Smartphone mit Rückkamera im Querformat (270 oder -90 Grad gedreht).

Hier ist der Bildpuffer des Kamerasensors in Abbildung 4:

Der Kamerasensor wurde ins Querformat gedreht und das Bild ist auf dem Kopf.

Der Puffer muss um 90 Grad im Uhrzeigersinn gedreht werden, um die Sensorausrichtung anzupassen:

Kamerasensor ist auf Hochformat ausgelegt und das Bild ist seitlich gedreht,
            oben links.

Dann wird der Zwischenspeicher um 270 Grad gegen den Uhrzeigersinn gedreht, um das Gerät zu berücksichtigen. Rotation:

Der Kamerasensor ist im Querformat gedreht, das Bild ist aber aufrecht.

Seitenverhältnis

Das Displayseitenverhältnis ändert sich, wenn sich die Geräteausrichtung ändert, aber auch, wenn faltbare Geräte zusammengeklappt und aufgeklappt werden, wenn Fenster in Umgebungen mit mehreren Fenstern neu skaliert werden und wenn Apps auf sekundären Displays geöffnet werden.

Der Bildpuffer des Kamerasensors muss so ausgerichtet und skaliert sein, dass er der Ausrichtung und dem Seitenverhältnis des Sucher-UI-Elements entspricht, da sich die Benutzeroberfläche dynamisch ändert – unabhängig davon, ob sich das Gerät dreht.

Bei neuen Formfaktoren oder im Mehrfenstermodus oder Multidisplay-Umgebungen, wenn Ihr In der App wird davon ausgegangen, dass die Kameravorschau genauso ausgerichtet ist wie das Gerät (Hoch- oder Querformat) ist die Vorschau möglicherweise falsch ausgerichtet oder skaliert. falsch sind oder beides.

Aufgeklapptes faltbares Gerät mit seitlich gedrehter Porträtkamera-Vorschau.
Abbildung 5: Ein faltbares Gerät wechselt vom Hoch- ins Querformat, der Kamerasensor bleibt jedoch im Hochformat.

In Abbildung 5 ging die App fälschlicherweise davon aus, dass das Gerät um 90 Grad gegen den Uhrzeigersinn gedreht wurde. Daher drehte die App die Vorschau um denselben Betrag.

Aufgeklapptes faltbares Gerät mit aufrechter Kameravorschau, die aufgrund der falschen Skalierung gestaucht ist
Abbildung 6: Ein faltbares Gerät wechselt vom Hoch- ins Querformat, der Kamerasensor bleibt jedoch im Hochformat.

In Abbildung 6 hat die App das Seitenverhältnis des Bildpuffers nicht angepasst, damit es richtig skaliert werden kann, um die neuen Abmessungen des UI-Elements für die Kameravorschau zu erreichen.

Bei Kamera-Apps mit fester Ausrichtung treten auf faltbaren Geräten andere Geräte mit großem Bildschirm, wie z. B. Laptops:

Die Kameravorschau auf dem Laptop ist aufrecht, die App-Benutzeroberfläche ist jedoch seitlich.
Abbildung 7: App im Hochformat mit fester Ausrichtung auf einem Laptop.

In Abbildung 7 ist die Benutzeroberfläche der Kamera-App seitlich gedreht, weil die App auf das Hochformat beschränkt. Das Sucherbild ist korrekt im Verhältnis zum Kamerasensor ausgerichtet.

Porträtmodus mit Einzug

Kamera-Apps, die den Mehrfenstermodus nicht unterstützen (resizeableActivity="false") und ihre Ausrichtung einschränken, (screenOrientation="portrait" oder screenOrientation="landscape") kann auf Geräten mit großen Bildschirmen im Hochformat platziert werden, um die Kameravorschau aufzurufen.

Im Hochformat werden Apps, die nur im Hochformat angezeigt werden können, im Hochformat angezeigt, auch wenn das Display im Querformat ist. Bei Apps, die nur im Querformat angezeigt werden, wird im Querformat ein Letterbox-Effekt angewendet, auch wenn das Display im Hochformat ist. Das Kamerabild wird zur Ausrichtung gedreht. auf der Benutzeroberfläche der App an das Seitenverhältnis der Kameravorschau angepasst und skaliert, damit die Vorschau ausgefüllt wird.

Porträtmodus wird ausgelöst, wenn das Seitenverhältnis des Kamerabilds Sensor und das Seitenverhältnis der primären Aktivität der App stimmen nicht überein.

Kameravorschau und App-Benutzeroberfläche im Laptop in der richtigen Porträtausrichtung.
            Das breite Vorschaubild wird skaliert und zugeschnitten, um ins Hochformat zu passen.
Abbildung 8: App mit fester Ausrichtung im Porträtmodus aktiviert Laptop.

In Abbildung 8 wurde die Kamera-App im Hochformat so gedreht, dass die Benutzeroberfläche angezeigt wird. auf dem Laptop-Display aufrecht. Aufgrund des Unterschieds wird die App mit Letterbox-Balken versehen. im Seitenverhältnis zwischen der App im Hochformat und einem Display im Querformat. Das Kameravorschaubild wurde gedreht, um die Drehung der App-Benutzeroberfläche (aufgrund des eingeblendeten Porträtmodus) auszugleichen. Außerdem wurde das Bild zugeschnitten und skaliert, um es an die Porträtausrichtung anzupassen, wodurch das Sichtfeld reduziert wurde.

Drehen, zuschneiden, skalieren

Eingefügter Porträtmodus wird für eine Kamera-App, die nur im Porträtmodus auf einem Display angezeigt wird, aufgerufen Querformat:

Die Kameravorschau auf dem Laptop ist aufrecht, die App-Benutzeroberfläche ist jedoch seitlich.
Abbildung 9: App im Hochformat auf einem Laptop mit fester Ausrichtung

Die App wird im Hochformat mit Letterbox-Effekt dargestellt:

Die App wurde ins Hochformat gedreht und hat einen Letterbox-Effekt. Das Bild ist seitlich, oben rechts.

Das Kamerabild wird um 90 Grad gedreht, um es an die Neuausrichtung des App:

Sensorbild wurde um 90 Grad gedreht, um es aufrecht zu halten.

Das Bild wird auf das Seitenverhältnis der Kameravorschau zugeschnitten und dann auf Vorschau ausfüllen (Sichtfeld ist verkleinert):

Zugeschnittenes Kamerabild, das so skaliert ist, dass es die Kameravorschau füllt.

Auf faltbaren Geräten kann der Kamerasensor im Hochformat angezeigt werden während das Seitenverhältnis des Displays im Querformat ist:

Die Kameravorschau und die App-Benutzeroberfläche sind vom aufgeklappten Weitwinkeldisplay seitlich gedreht.
Abbildung 10: Entfaltetes Gerät mit einer Kamera-App, die nur Porträts aufnimmt, und unterschiedlichen Seitenverhältnissen des Kamerasensors und des Displays.

Da die Kameravorschau gedreht wird, um sie an die Sensorausrichtung anzupassen, das Bild im Sucher korrekt ausgerichtet ist, aber die App nur im Hochformat seitwärts.

Im Porträt-Einblendmodus muss die App nur im Porträtmodus in Letterbox-Format angezeigt werden, um die App und die Kameravorschau richtig auszurichten:

App im Letterbox-Format im Hochformat mit Kameravorschau
            auf einem faltbaren Gerät aufrecht.

API

Ab Android 12 (API-Level 31) können Apps den eingeblendeten Porträtmodus auch explizit über die Property SCALER_ROTATE_AND_CROP der Klasse CaptureRequest steuern.

Der Standardwert ist SCALER_ROTATE_AND_CROP_AUTO, Dadurch kann das System den Einfügungsmodus aufrufen. SCALER_ROTATE_AND_CROP_90 entspricht dem oben beschriebenen Verhalten im Porträtmodus mit Einblendung.

Nicht alle Geräte unterstützen alle SCALER_ROTATE_AND_CROP-Werte. Eine Liste der unterstützten Werte findest du unter CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES.

KameraX

Mit der Jetpack CameraX-Bibliothek können Sie ganz einfach einen Kamerasucher erstellen, der die Sensorausrichtung und die Gerätedrehung berücksichtigt.

Layoutelement PreviewView erstellt eine Kameravorschau, die sich automatisch an die Ausrichtung des Sensors anpasst, Geräterotation und -skalierung. PreviewView behält das Seitenverhältnis des Kamerabilds bei, indem der Skalierungstyp FILL_CENTER angewendet wird. Das Bild wird zentriert, aber möglicherweise so zugeschnitten, dass es den Abmessungen der PreviewView entspricht. Um das Kamerabild mit einem Letterbox-Bild zu versehen, stellen Sie den Skalierungstyp auf FIT_CENTER

Grundlegende Informationen zum Erstellen einer Kameravorschau mit PreviewView findest du unter Implementieren Sie eine Vorschau.

Eine vollständige Beispielimplementierung finden Sie im CameraXBasic-Repository auf GitHub.

CameraViewfinder

Ähnlich wie beim Anwendungsfall Vorschau bietet die Bibliothek CameraViewfinder eine Reihe von Tools, die die Erstellung einer Kameravorschau vereinfachen. Er ist nicht von CameraX Core abhängig und lässt sich daher nahtlos in Ihr vorhandene Camera2-Codebasis.

Anstatt Surface direkt zu verwenden, können Sie das Widget CameraViewfinder verwenden, um den Kamerafeed für Camera2 anzuzeigen.

CameraViewfinder verwendet intern entweder ein TextureView oder ein SurfaceView, um den Kamerafeed anzuzeigen, und wendet die erforderlichen Transformationen darauf an, um den Sucher korrekt anzuzeigen. Dazu gehört die Korrektur des Seitenverhältnisses, des Maßstabs und der Drehung.

Wenn Sie die Oberfläche vom CameraViewfinder-Objekt anfordern möchten, müssen Sie ein ViewfinderSurfaceRequest erstellen.

Diese Anfrage enthält Anforderungen an die Auflösung der Oberfläche und Informationen zum Kameragerät von CameraCharacteristics.

requestSurfaceAsync() wird angerufen sendet die Anfrage an den Oberflächenanbieter. Dies ist entweder ein TextureView- oder SurfaceView und erhält ein ListenableFuture von Surface.

Wenn Sie markSurfaceSafeToRelease() aufrufen, wird der Surface-Anbieter darüber informiert, dass die Oberfläche nicht mehr benötigt wird und die zugehörigen Ressourcen freigegeben werden können.

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

Oberflächenansicht

SurfaceView ist ein einfacher Ansatz, um eine Kameravorschau zu erstellen, wenn die Vorschau nicht verarbeitet werden muss und nicht animiert ist.

SurfaceView dreht den Kamerasensor-Bildzwischenspeicher automatisch Displayausrichtung und berücksichtigen dabei sowohl die Sensorausrichtung als auch das Gerät Rotation. Der Bildzwischenspeicher wird jedoch so skaliert, dass er in den SurfaceView passt. ohne das Seitenverhältnis zu berücksichtigen.

Das Seitenverhältnis des Bildpuffers muss mit dem Seitenverhältnis der SurfaceView übereinstimmen. Sie können das erreichen, indem Sie den Inhalt der SurfaceView in der Methode onMeasure() der Komponente skalieren:

Der Quellcode von computeRelativeRotation() befindet sich in Relative Drehung unten.)

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

Weitere Informationen zur Implementierung von SurfaceView als Kameravorschau findest du unter Kameraausrichtung.

TextureView

TextureView ist weniger leistungsfähig als SurfaceView und erfordert mehr Aufwand. Mit TextureView haben Sie jedoch maximale Kontrolle über die Kameravorschau.

TextureView dreht den Sensorbildpuffer entsprechend der Sensorausrichtung, aber übernimmt keine Geräterotation oder Skalierung der Vorschau.

Skalierung und Drehung können in einer Matrixtransformation codiert werden. Informationen zum korrekten Skalieren und Drehen von TextureView finden Sie unter Unterstützung für skalierbare Oberflächen in der Kamera App.

Relative Drehung

Die relative Drehung des Kamerasensors ist die erforderliche Drehung Richten Sie die Kamerasensorausgabe auf die Geräteausrichtung aus.

Die relative Drehung wird von Komponenten wie SurfaceView und TextureView verwendet, um die X- und Y-Skalierungsfaktoren für das Vorschaubild zu bestimmen. Sie wird auch verwendet, um gibt die Drehung des Sensorbildpuffers an.

Mit den Klassen CameraCharacteristics und Surface lässt sich die relative Drehung des Kamerasensors berechnen:

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

Fenstermesswerte

Die Bildschirmgröße sollte nicht verwendet werden, um die Abmessungen des Kamerasuchers zu bestimmen. Die Kamera-App wird möglicherweise in einem Teil des Bildschirms ausgeführt, entweder im Mehrfenstermodus auf Mobilgeräten oder im Modus „Bildschirmfrei“ unter ChromeOS.

WindowManager#getCurrentWindowMetrics() (in API-Level 30 hinzugefügt) gibt die Größe des Anwendungsfensters an, nicht die Größe des Displays. Die Methoden der Jetpack WindowManager-Bibliothek WindowMetricsCalculator#computeCurrentWindowMetrics() und WindowInfoTracker#currentWindowMetrics() bieten einen ähnlichen Support mit Abwärtskompatibilität wie API-Level 14.

Drehung um 180 Grad

Eine Drehung eines Geräts um 180 Grad (zum Beispiel von der natürlichen Ausrichtung auf natürliche Ausrichtung verkehrt herum) löst das onConfigurationChanged() Callback des Nutzers an. Das kann dazu führen, dass die Kameravorschau auf dem Kopf steht.

Um eine Drehung um 180 Grad zu erkennen, implementieren Sie eine DisplayListener und überprüfen Sie die Gerätedrehung mit einem Aufruf an Display#getRotation() in der onDisplayChanged() Callback des Nutzers an.

Exklusive Ressourcen

Vor Android 10 war nur die am stärksten sichtbare Aktivität im Mehrfenstermodus Umgebung hatte den Status RESUMED. Das war verwirrend für die Nutzer, Das System gab keine Hinweise darauf, welche Aktivität wieder aufgenommen wurde.

Mit Android 10 (API-Level 29) wurde die Wiederaufnahme mehrerer Apps eingeführt, bei der sich alle sichtbaren Aktivitäten im Status RESUMED befinden. Sichtbare Aktivitäten können den Status PAUSED auch dann erhalten, wenn sich beispielsweise eine transparente Aktivität über der Aktivität befindet oder die Aktivität nicht fokussiert werden kann, z. B. im Bild-im-Bild-Modus (siehe Unterstützung für Bild-im-Bild).

Eine Anwendung, die die Kamera, das Mikrofon oder eine exklusive oder Singleton-Ressource auf API-Level 29 oder höher verwendet, muss Multi-Resume unterstützen. Wenn beispielsweise drei fortgesetzte Aktivitäten die Kamera verwenden möchten, kann nur eine auf diese exklusive Ressource zugreifen. Für jede Aktivität muss ein onDisconnected()-Callback implementiert werden, um über den vorrangigen Zugriff auf die Kamera durch eine Aktivität mit höherer Priorität informiert zu bleiben.

Weitere Informationen finden Sie unter Multi-Resume:

Weitere Informationen