Kameravorschau

Hinweis:Diese Seite bezieht sich auf das Paket Camera2. Sofern Ihre App keine bestimmten Low-Level-Funktionen von Camera2 erfordert, empfehlen wir die Verwendung von CameraX. CameraX und Camera2 unterstützen Android 5.0 (API-Level 21) und höher.

Die Ausrichtung von Kameras und Kameravorschauen ist auf Android-Geräten nicht immer gleich.

Eine Kamera befindet sich in einer festen Position auf einem Gerät, unabhängig davon, ob es sich um ein Smartphone, ein Tablet oder einen Computer handelt. Wenn sich die Geräteausrichtung ändert, ändert sich auch die Kameraausrichtung.

Daher gehen Kamera-Apps in der Regel von einer festen Beziehung zwischen der Geräteausrichtung und dem Seitenverhältnis der Kameravorschau aus. Wenn sich ein Smartphone im Hochformat befindet, wird angenommen, dass die Kameravorschau höher als breit ist. Wenn das Smartphone und die Kamera ins Querformat gedreht werden, wird die Kameravorschau voraussichtlich breiter als hoch sein.

Diese Annahmen werden jedoch von neuen Formfaktoren wie faltbaren Geräten und Anzeigemodi wie dem Mehrfenstermodus und dem Mehrfenstermodus infrage gestellt. Faltbare Geräte ändern Anzeigegröße und Seitenverhältnis, ohne die Ausrichtung zu ändern. Im Mehrfenstermodus werden Kamera-Apps auf einen Teil des Bildschirms beschränkt und die Kameravorschau wird unabhängig von der Geräteausrichtung skaliert. Der Multi-Display-Modus ermöglicht die Verwendung von sekundären Bildschirmen, die möglicherweise nicht dieselbe Ausrichtung wie das primäre Display haben.

Kameraausrichtung

Die Android-Kompatibilitätsdefinition gibt an, dass ein Kamerabildsensor so ausgerichtet sein muss, dass die lange Seite der Kamera mit der langen Seite des Bildschirms übereinstimmt. Das heißt, wenn das Gerät im Querformat gehalten wird, MÜSSEN Bilder im Querformat aufgenommen werden. Dies gilt unabhängig von der natürlichen Ausrichtung des Geräts, d. h., es gilt sowohl für Geräte im Querformat als auch für Geräte im Hochformat.

Die Kamera-zu-Bildschirm-Anordnung maximiert den Anzeigebereich des Kamerasuchers in einer Kamera-App. Außerdem geben Bildsensoren ihre Daten normalerweise im Querformat aus, wobei 4:3 am häufigsten ist.

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

Die natürliche Ausrichtung des Kamerasensors ist Querformat. In Abbildung 1 wird der Sensor der Frontkamera (die Kamera, die in dieselbe Richtung wie das Display zeigt) relativ zum Smartphone um 270 Grad gedreht, um der Android-Kompatibilitätsdefinition zu entsprechen.

Die camera2 API enthält eine SENSOR_ORIENTATION-Konstante, um die Sensordrehung für Apps sichtbar zu machen. Bei den meisten Smartphones und Tablets meldet das Gerät eine Sensorausrichtung von 270 Grad für Frontkameras und 90 Grad (Sichtfeld von der Rückseite des Geräts) für rückseitige Kameras. Dabei wird die lange Seite des Sensors an der langen Seite des Geräts ausgerichtet. Laptopkameras melden in der Regel eine Sensorausrichtung von 0 oder 180 Grad.

Da die Bildsensoren der Kamera ihre Daten (einen Bildzwischenspeicher) in der natürlichen Ausrichtung des Sensors (Querformat) ausgeben, muss der Bildzwischenspeicher um die von SENSOR_ORIENTATION angegebene Gradzahl gedreht werden, damit die Kameravorschau in der natürlichen Ausrichtung des Geräts richtig dargestellt wird. Bei Frontkameras erfolgt die Drehung gegen den Uhrzeigersinn, bei rückseitigen Kameras im Uhrzeigersinn.

Für die Frontkamera in Abbildung 1 sieht der vom Kamerasensor erzeugte Bildzwischenspeicher beispielsweise so aus:

Kamerasensor ist ins Querformat gedreht. Das Bild ist seitlich links oben.

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

Kamerasensor im Hochformat mit aufrechtem Bild.

Eine rückseitige Kamera würde einen Bildzwischenspeicher mit derselben Ausrichtung wie der Zwischenspeicher oben erzeugen, aber SENSOR_ORIENTATION beträgt 90 Grad. Dadurch wird der Zwischenspeicher um 90 Grad im Uhrzeigersinn gedreht.

Bildschirm drehen

Die Gerätedrehung ist der Grad, um den ein Gerät aus seiner natürlichen Ausrichtung gedreht wird. Ein Smartphone im Querformat hat beispielsweise eine Gerätedrehung von 90 oder 270 Grad, je nach Drehrichtung.

Damit die Kameravorschau aufrecht erscheint, muss der Bildzwischenspeicher eines Kamerasensors (zusätzlich zu den Grad der Sensorausrichtung) um die gleiche Gradzahl wie die Gerätedrehung gedreht werden.

Berechnung der Ausrichtung

Die richtige Ausrichtung der Kameravorschau berücksichtigt die Sensorausrichtung und Gerätedrehung.

Die Gesamtdrehung des Zwischenspeichers für das Sensorbild 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 gedreht (aus der natürlichen Ausrichtung des Sensors). Bei rückseitigen Kameras wird der Sensorbildzwischenspeicher im Uhrzeigersinn gedreht.

Der Ausdruck deviceOrientationDegrees * sign + 360 wandelt die Gerätedrehung für rückseitige Kameras von gegen den Uhrzeigersinn in den Uhrzeigersinn um (z. B. Umwandlung von 270 Grad gegen den Uhrzeigersinn in 90 Grad im Uhrzeigersinn). Der Modulo-Vorgang skaliert das Ergebnis auf weniger als 360 Grad (z. B. eine Skalierung von 540 Grad auf 180 Grad).

Verschiedene APIs melden die Geräterotation unterschiedlich:

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

Frontkameras

Kameravorschau und Sensor im Querformat, der Sensor ist rechts oben.
Abbildung 2. Kameravorschau und -sensor mit um 90 Grad gedrehtes Smartphone im Querformat.

Hier ist der vom Kamerasensor erzeugte Bildzwischenspeicher in Abbildung 2:

Kamerasensor im Querformat mit aufrechtem Bild.

Der Zwischenspeicher muss um 270 Grad gegen den Uhrzeigersinn gedreht werden, um die Sensorausrichtung zu korrigieren (siehe Kameraausrichtung oben):

Kamerasensor wurde in die Hochformatausrichtung gedreht. Das Bild ist seitlich oben rechts.

Dann wird der Zwischenspeicher weitere 90 Grad gegen den Uhrzeigersinn gedreht, um die Gerätedrehung zu berücksichtigen. Dies führt zur richtigen Ausrichtung der Kameravorschau in Abbildung 2:

Kamerasensor wurde ins Querformat gedreht, das Bild ist aufrecht.

Hier ist die Kamera im Querformat nach rechts zu sehen:

Kameravorschau und Sensor im Querformat, aber der Sensor ist auf dem Kopf.
Abbildung 3: Kameravorschau und Sensor mit gedrehtem Smartphone um 270 Grad (oder -90 Grad) im Querformat.

So sieht der Bildzwischenspeicher aus:

Kamerasensor wurde ins Querformat gedreht, das Bild wird auf dem Kopf gestellt.

Der Zwischenspeicher muss um 270 Grad gegen den Uhrzeigersinn gedreht werden, um die Sensorausrichtung zu korrigieren:

Kamerasensor mit der Bewertung im Hochformat und seitlichem Bild, oben links.

Dann wird der Zwischenspeicher weitere 270 Grad gegen den Uhrzeigersinn gedreht, um die Gerätedrehung zu berücksichtigen:

Kamerasensor wurde ins Querformat gedreht, das Bild ist aufrecht.

Rückkameras

Rückkameras haben in der Regel eine Sensorausrichtung von 90 Grad (aus Sicht von der Rückseite des Geräts). Beim Ausrichten der Kameravorschau wird der Sensorbildpuffer um die Sensordrehung im Uhrzeigersinn gedreht (im Gegensatz zu Frontkameras gegen den Uhrzeigersinn). Anschließend wird der Bildzwischenspeicher um den Grad der Gerätedrehung gegen den Uhrzeigersinn gedreht.

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

Hier ist der Bildzwischenspeicher des Kamerasensors in Abbildung 4:

Kamerasensor wurde ins Querformat gedreht, das Bild wird auf dem Kopf gestellt.

Der Zwischenspeicher muss um 90 Grad im Uhrzeigersinn gedreht werden, um die Sensorausrichtung zu korrigieren:

Kamerasensor mit der Bewertung im Hochformat und seitlichem Bild, oben links.

Dann wird der Zwischenspeicher um 270 Grad gegen den Uhrzeigersinn gedreht, um die Gerätedrehung zu berücksichtigen:

Kamerasensor wurde ins Querformat gedreht, das Bild ist aufrecht.

Seitenverhältnis

Das Seitenverhältnis des Displays ändert sich, wenn sich die Geräteausrichtung ändert, aber auch, wenn faltbare Smartphones auf- und zugeklappt werden, die Größe von Fenstern in Mehrfensterumgebungen angepasst wird und wenn Apps auf sekundären Bildschirmen geöffnet werden.

Der Bildzwischenspeicher des Kamerasensors muss so ausgerichtet und skaliert werden, dass er der Ausrichtung und dem Seitenverhältnis des UI-Elements des Suchers entspricht, wenn sich die Ausrichtung der UI dynamisch ändert – unabhängig davon, ob sich die Ausrichtung des Geräts ändert.

Wenn in Ihrer App bei neuen Formfaktoren oder in Umgebungen mit Mehrfenster- und Mehrfachdisplay davon ausgegangen wird, dass die Kameravorschau dieselbe Ausrichtung wie das Gerät hat (Hoch- oder Querformat), wird die Vorschau möglicherweise falsch ausgerichtet, falsch skaliert oder beides.

Aufgeklapptes faltbares Gerät mit seitlich gedrehter Vorschau der Kamera im Hochformat.
Abbildung 5: Faltbares Gerät wechselt vom Hochformat zum Querformat, der Kamerasensor bleibt jedoch im Hochformat.

In Abbildung 5 nahm die App fälschlicherweise an, das Gerät um 90 Grad gegen den Uhrzeigersinn gedreht zu werden. Daher wurde die Vorschau in der App um denselben Wert gedreht.

Aufgeklapptes faltbares Gerät mit aufrechter Kameravorschau, aber aufgrund von falscher Skalierung zusammengedrückt.
Abbildung 6. Faltbares Gerät wechselt vom Hochformat zum Querformat, der Kamerasensor bleibt jedoch im Hochformat.

In Abbildung 6 hat die App das Seitenverhältnis des Bildzwischenspeichers nicht angepasst, um eine korrekte Skalierung an die neuen Abmessungen des UI-Elements für die Kameravorschau zu ermöglichen.

Bei Kamera-Apps mit fester Ausrichtung treten in der Regel auf faltbaren Geräten und anderen Geräten mit großem Bildschirm wie Laptops Probleme auf:

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

In Abbildung 7 ist die Benutzeroberfläche der Kamera-App seitwärts ausgerichtet, da die Ausrichtung der App auf das Hochformat beschränkt ist. Das Bild im Sucher ist korrekt relativ zum Kamerasensor ausgerichtet.

Porträtmodus verwenden

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

Apps, die im Hochformat dargestellt werden, werden im Hochformat angezeigt, obwohl das Seitenverhältnis des Displays Querformat ist. Apps, die nur im Querformat verwendet werden, werden im Querformat im Letterbox-Format dargestellt, obwohl das Seitenverhältnis des Bildschirms das Hochformat ist. Das Kamerabild wird so gedreht, dass es mit der App-Benutzeroberfläche übereinstimmt. Es wird auf das Seitenverhältnis der Kameravorschau zugeschnitten und dann skaliert, um die Vorschau auszufüllen.

Der eingefügte Porträtmodus wird ausgelöst, wenn das Seitenverhältnis des Bildsensors der Kamera und das Seitenverhältnis der primären Aktivität der Anwendung nicht übereinstimmen.

Kameravorschau und App-Benutzeroberfläche im richtigen Hochformat auf einem Laptop.
            Das breite Vorschaubild wird skaliert und an das Hochformat zugeschnitten.
Abbildung 8. App für Hochformat im Hochformat mit fester Ausrichtung auf einem Laptop.

In Abbildung 8 wurde die Kamera-App für das Hochformat gedreht, um die Benutzeroberfläche auf dem Laptop-Display aufrecht anzuzeigen. Die App hat ein Letterbox-Bild, da sich das Seitenverhältnis zwischen der App im Hochformat und dem Display im Querformat unterscheidet. Das Vorschaubild der Kamera wurde gedreht, um die Drehung der Benutzeroberfläche der App (aufgrund des Einsatzes im Hochformat) auszugleichen. Das Bild wurde zugeschnitten und skaliert, um es an die Hochformatausrichtung anzupassen, wodurch das Sichtfeld verringert wird.

Drehen, zuschneiden, skalieren

Dieser Modus wird für eine Kamera-App im Hochformat auf einem Display mit einem Seitenverhältnis im Querformat aufgerufen:

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

Die App weist ein Letterbox-Bild im Hochformat auf:

App wurde ins Hochformat gedreht und im Letterbox-Format dargestellt. Das Bild ist seitlich rechts oben.

Das Kamerabild wird um 90 Grad gedreht, um die Neuausrichtung der App anzupassen:

Das Sensorbild wurde um 90 Grad gedreht, um es aufrecht zu stellen.

Das Bild wird auf das Seitenverhältnis der Kameravorschau zugeschnitten und dann skaliert, um die Vorschau auszufüllen (das Sichtfeld wird verkleinert):

Zugeschnittenes Kamerabild, das auf die Füllung der Kameravorschau skaliert wurde.

Bei faltbaren Geräten kann der Kamerasensor Hochformat sein, während das Seitenverhältnis des Displays Querformat ist:

Kameravorschau und App-Benutzeroberfläche sind seitlich auf einem breiten, aufgeklappten Display gedreht.
Abbildung 10. Aufgeklapptes Gerät mit einer Kamera-App im Hochformat und unterschiedlichen Seitenverhältnissen von Kamerasensor und Display.

Da die Kameravorschau gedreht wird, um sie an die Sensorausrichtung anzupassen, wird das Bild korrekt im Sucher ausgerichtet. Die App für das Hochformat ist jedoch seitwärts gedreht.

Für den Einsatz des Hochformats muss die App nur im Hochformat ausgerichtet werden, um die App- und Kameravorschau richtig auszurichten:

App mit Letterbox-Bild in Hochformat mit aufrechter Kameravorschau auf einem faltbaren Gerät.

API

Ab Android 12 (API-Level 31) können Apps den Einfügung-Hochformat auch explizit über das Attribut SCALER_ROTATE_AND_CROP der Klasse CaptureRequest steuern.

Der Standardwert ist SCALER_ROTATE_AND_CROP_AUTO. Dadurch kann das System den Inset-Porträtmodus aufrufen. SCALER_ROTATE_AND_CROP_90 entspricht dem oben beschriebenen Verhalten des integrierten Hochformats.

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

KameraX

Mit der Bibliothek Jetpack CameraX können Sie einen Kamerasucher erstellen, der die Sensorausrichtung und die Gerätedrehung erleichtert.

Mit dem Layoutelement PreviewView wird eine Kameravorschau erstellt. Dabei werden die Sensorausrichtung, die Geräteausrichtung und die Skalierung automatisch angepasst. PreviewView behält das Seitenverhältnis des Kamerabilds bei, indem der Skalierungstyp FILL_CENTER angewendet wird. Dieser wird das Bild zentriert, aber möglicherweise auf die Abmessungen von PreviewView zugeschnitten. Für das Letterbox-Bild der Kamera legen Sie den Skalierungstyp auf FIT_CENTER fest.

Grundlegende Informationen zum Erstellen einer Kameravorschau mit PreviewView finden Sie unter Vorschau implementieren.

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

Kamerasucher

Ähnlich wie beim Anwendungsfall Vorschau bietet die Bibliothek CameraViewfinder eine Reihe von Tools, um das Erstellen einer Kameravorschau zu vereinfachen. Sie benötigt keine CameraX Core, sodass sie nahtlos in Ihre vorhandene Camera2-Codebasis eingebunden werden kann.

Anstatt Surface direkt zu verwenden, kannst du das Widget CameraViewfinder verwenden, um den Kamerafeed für Camera2 aufzurufen.

CameraViewfinder verwendet intern entweder TextureView oder SurfaceView zur Anzeige des Kamerafeeds und wendet die erforderlichen Transformationen auf sie an, um den Sucher korrekt anzuzeigen. Dazu gehört die Korrektur des Seitenverhältnisses, der Skalierung 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 für die Oberflächenauflösung und Kamerageräteinformationen aus CameraCharacteristics.

Durch das Aufrufen von requestSurfaceAsync() wird die Anfrage an den Oberflächenanbieter gesendet. Dies ist entweder ein TextureView oder SurfaceView und erhält einen ListenableFuture von Surface.

Durch den Aufruf von markSurfaceSafeToRelease() wird der Oberflächenanbieter darüber informiert, dass die Oberfläche nicht benötigt wird und zugehörige Ressourcen freigegeben werden können.

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

Oberflächenansicht

Mit SurfaceView lässt sich eine Kameravorschau einfach erstellen, wenn die Vorschau nicht verarbeitet werden muss und nicht animiert ist.

SurfaceView dreht den Bildzwischenspeicher des Kamerasensors automatisch so, dass er der Bildschirmausrichtung entspricht. Dabei werden sowohl die Sensorausrichtung als auch die Gerätedrehung berücksichtigt. Der Bildzwischenspeicher wird jedoch auf die Abmessungen von SurfaceView ohne Berücksichtigung des Seitenverhältnisses skaliert.

Achten Sie darauf, dass das Seitenverhältnis des Bildzwischenspeichers dem Seitenverhältnis von SurfaceView entspricht. Dazu skalieren Sie den Inhalt von SurfaceView in der Methode onMeasure() der Komponente:

Der Quellcode von computeRelativeRotation() befindet sich unten unter Relative Rotation.

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

Weitere Informationen zum Implementieren von SurfaceView als Kameravorschau finden Sie unter Kameraausrichtungen.

Texturansicht

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

TextureView rotiert den Zwischenspeicher des Sensorbilds basierend auf der Sensorausrichtung, verarbeitet jedoch nicht die Gerätedrehung oder die Skalierung der Vorschau.

Skalierung und Rotation können in einer Matrix-Transformation codiert werden. Informationen zum korrekten Skalieren und Drehen einer TextureView finden Sie unter Flächen mit anpassbarer Größe in der Kamera-App unterstützen.

Relative Drehung

Die relative Drehung des Kamerasensors ist der Grad der Drehung, der erforderlich ist, um die Ausgabe des Kamerasensors an die Geräteausrichtung auszurichten.

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 die Rotation des Sensorbildzwischenspeichers anzugeben.

Mit den Klassen CameraCharacteristics und Surface kann die relative Rotation des Kamerasensors berechnet werden:

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

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 freien Modus unter ChromeOS.

WindowManager#getCurrentWindowMetrics() (in API-Level 30 hinzugefügt) gibt die Größe des Anwendungsfensters und nicht die Größe des Bildschirms zurück. Die Jetpack WindowManager-Bibliotheksmethoden WindowMetricsCalculator#computeCurrentWindowMetrics() und WindowInfoTracker#currentWindowMetrics() bieten eine ähnliche Unterstützung mit Abwärtskompatibilität mit API-Level 14.

Drehung um 180 Grad

Eine Drehung um 180 Grad (z. B. von natürlicher Ausrichtung zur natürlichen Ausrichtung auf den Kopf) löst den onConfigurationChanged()-Callback nicht aus. Dies kann dazu führen, dass die Kameravorschau auf dem Kopf steht.

Implementieren Sie zum Erkennen einer Drehung um 180 Grad einen DisplayListener und prüfen Sie die Gerätedrehung mit einem Aufruf von Display#getRotation() im onDisplayChanged()-Callback.

Exklusive Ressourcen

Vor Android 10 hatte nur die am stärksten sichtbare Aktivität in einer Mehrfensterumgebung den Status RESUMED. Dies war für die Nutzer verwirrend, da das System keinen Hinweis darauf bot, welche Aktivität fortgesetzt wurde.

Mit Android 10 (API-Level 29) wurde die Funktion zur mehrfachen Fortsetzung eingeführt, bei der alle sichtbaren Aktivitäten den Status RESUMED haben. Sichtbare Aktivitäten können weiterhin in den Status PAUSED wechseln, wenn beispielsweise eine transparente Aktivität über der Aktivität liegt oder die Aktivität nicht fokussierbar ist, z. B. im Bild-im-Bild-Modus (siehe Unterstützung von 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 die Multi-Fortsetzen 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 einen präventiven Zugriff auf die Kamera durch eine Aktivität mit höherer Priorität informiert zu werden.

Weitere Informationen finden Sie unter Mehrere Lebensläufe.

Weitere Informationen