Camera API

Das Android-Framework unterstützt verschiedene Kameras und Kamerafunktionen auf Geräten, sodass Sie Bilder und Videos in Ihren Anwendungen aufnehmen können. In diesem Dokument wird ein schneller, einfacher Ansatz für die Bild- und Videoaufnahme sowie ein erweiterter Ansatz zum Erstellen benutzerdefinierter Kameraumgebungen für Nutzer beschrieben.

Hinweis: Auf dieser Seite wird die Klasse Camera beschrieben, die eingestellt wurde. Wir empfehlen die Verwendung der CameraX-Jetpack-Bibliothek oder, für bestimmte Anwendungsfälle, der Klasse camera2. Sowohl CameraX als auch Camera2 funktionieren unter Android 5.0 (API-Level 21) und höher.

Weitere Informationen finden Sie in den folgenden Ressourcen:

Wissenswertes

Bevor Sie Ihre App für die Verwendung von Kameras auf Android-Geräten aktivieren, sollten Sie sich einige Fragen dazu stellen, wie Ihre App diese Hardwarefunktion verwenden soll.

  • Kameraanforderung – Ist die Verwendung einer Kamera für Ihre Anwendung so wichtig, dass sie nicht auf einem Gerät ohne Kamera installiert werden soll? Falls ja, solltest du die Kameraanforderung in deinem Manifest deklarieren.
  • Quick Picture oder benutzerdefinierte Kamera – Wie verwendet Ihre Anwendung die Kamera? Möchten Sie nur schnell ein Foto oder einen Videoclip aufnehmen oder wird Ihre App eine neue Möglichkeit für den Einsatz von Kameras bieten? Wenn Sie schnell einen Schnappschuss oder Clip erstellen möchten, sollten Sie vorhandene Kamera-Apps verwenden. Informationen zur Entwicklung einer benutzerdefinierten Kamerafunktion finden Sie im Abschnitt Kamera-App erstellen.
  • Anforderung an Dienste im Vordergrund – Wann interagiert deine App mit der Kamera? Unter Android 9 (API-Level 28) und höher können im Hintergrund ausgeführte Apps nicht auf die Kamera zugreifen. Daher solltest du die Kamera entweder im Vordergrund oder als Teil eines Diensts im Vordergrund verwenden.
  • Speicher: Sind die von Ihrer App generierten Bilder oder Videos nur für Ihre App sichtbar oder werden sie geteilt, damit sie von anderen Anwendungen wie Galerie oder anderen Medien und sozialen Apps verwendet werden können? Möchten Sie, dass die Bilder und Videos auch dann verfügbar sind, wenn Ihre App deinstalliert ist? Informationen zur Implementierung dieser Optionen findest du im Abschnitt Mediendateien speichern.

Grundlagen

Das Android-Framework unterstützt die Aufnahme von Bildern und Videos über die android.hardware.camera2 API oder die Kamera-Intent. Dies sind die relevanten Klassen:

android.hardware.camera2
Dieses Paket ist die primäre API zum Steuern der Gerätekameras. Damit können Sie Fotos oder Videos aufnehmen, während Sie eine Kamera-App entwickeln.
Camera
Diese Klasse ist die ältere eingestellte API zur Steuerung von Gerätekameras.
SurfaceView
Dieser Kurs wird verwendet, um dem Nutzer eine Live-Kameravorschau zu präsentieren.
MediaRecorder
In diesem Kurs werden Videos mit der Kamera aufgezeichnet.
Intent
Mit dem Intent-Aktionstyp MediaStore.ACTION_IMAGE_CAPTURE oder MediaStore.ACTION_VIDEO_CAPTURE können Bilder oder Videos erfasst werden, ohne das Camera-Objekt direkt zu verwenden.

Manifestdeklarationen

Bevor Sie mit der Entwicklung Ihrer App mit der Camera API beginnen, sollte Ihr Manifest die entsprechenden Deklarationen enthalten, die die Verwendung von Kamerahardware und anderen zugehörigen Funktionen zulassen.

  • Kameraberechtigung: Ihre App muss die Berechtigung anfordern, eine Gerätekamera zu verwenden.
    <uses-permission android:name="android.permission.CAMERA" />
    

    Hinweis:Wenn Sie die Kamera verwenden, indem Sie eine vorhandene Kamera-App aufrufen, muss diese Berechtigung nicht angefordert werden.

  • Kamerafunktionen: In Ihrer App muss auch die Verwendung von Kamerafunktionen deklariert werden, z. B.:
    <uses-feature android:name="android.hardware.camera" />
    

    Eine Liste der Kamerafunktionen finden Sie in der Manifest-Funktionsreferenz.

    Wenn Sie dem Manifest Kamerafunktionen hinzufügen, verhindert Google Play, dass Ihre App auf Geräten installiert wird, die keine Kamera enthalten oder die von Ihnen angegebenen Kamerafunktionen nicht unterstützen. Weitere Informationen zur Verwendung der funktionsbasierten Filterung bei Google Play finden Sie unter Google Play und funktionsbasiertes Filtern.

    Wenn Ihre App eine Kamera oder Kamerafunktion für den ordnungsgemäßen Betrieb verwenden kann, dies aber nicht erfordert, sollten Sie dies im Manifest angeben, indem Sie das Attribut android:required einbeziehen und auf false setzen:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
    
  • Speicherberechtigung: Deine App kann Bilder und Videos auf dem externen Speicher (SD-Karte) des Geräts speichern, wenn sie auf Android 10 (API-Level 29) oder niedriger ausgerichtet ist und im Manifest Folgendes angibt.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  • Berechtigung für Audioaufnahme: Für die Audioaufnahme mit Videoaufnahme muss Ihre Anwendung die Berechtigung zur Audioaufnahme anfordern.
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
  • Standortberechtigung – Wenn Ihre Anwendung Bilder mit GPS-Standortinformationen kennzeichnet, müssen Sie die Berechtigung ACCESS_FINE_LOCATION anfordern. Wenn deine App auf Android 5.0 (API-Level 21) oder höher ausgerichtet ist, musst du außerdem deklarieren, dass deine App das GPS des Geräts verwendet:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
    <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
    <uses-feature android:name="android.hardware.location.gps" />
    

    Weitere Informationen zum Abrufen des Nutzerstandorts finden Sie unter Standortstrategien.

Vorhandene Kamera-Apps verwenden

Eine schnelle Möglichkeit, die Aufnahme von Bildern oder Videos in Ihrer App ohne viel zusätzlichen Code zu ermöglichen, besteht darin, mit einem Intent eine vorhandene Android-Kamera-App aufzurufen. Einzelheiten hierzu findest du in den Lektionen Einfaches Aufnehmen von Fotos und Videos einfach aufzeichnen.

Kamera-App erstellen

Einige Entwickler benötigen möglicherweise eine Kamerabenutzeroberfläche, die an das Erscheinungsbild ihrer Anwendung angepasst ist oder spezielle Funktionen bietet. Einen eigenen Code für die Aufnahme von Bildern zu schreiben, kann den Nutzern ein besseres Erlebnis bieten.

Hinweis: Die folgende Anleitung bezieht sich auf die ältere, verworfene Camera API. Für neue oder erweiterte Kameraanwendungen wird die neuere android.hardware.camera2 API empfohlen.

So erstellen Sie eine benutzerdefinierte Kameraoberfläche für Ihre Anwendung:

  • Kamera erkennen und aufrufen: Erstellen Sie Code, um das Vorhandensein von Kameras zu prüfen und den Zugriff anzufordern.
  • Vorschauklasse erstellen: Erstellen Sie eine Kameravorschauklasse, die SurfaceView erweitert und die SurfaceHolder-Schnittstelle implementiert. Diese Klasse zeigt eine Vorschau der Live-Bilder der Kamera an.
  • Vorschaulayout erstellen: Nachdem Sie die Kameravorschauklasse erstellt haben, erstellen Sie ein Ansichtslayout, das die Vorschau und die gewünschten Steuerelemente der Benutzeroberfläche enthält.
  • Listener für Capture einrichten: Verbinden Sie Listener für die Steuerelemente Ihrer Benutzeroberfläche, um bei Nutzeraktionen wie dem Drücken einer Schaltfläche die Aufnahme von Bildern oder Videos zu starten.
  • Dateien erfassen und speichern: Richten Sie den Code zum Erfassen von Bildern oder Videos und Speichern der Ausgabe ein.
  • Kamera freigeben: Nach der Verwendung der Kamera muss sie von der Anwendung zur Verwendung durch andere Anwendungen ordnungsgemäß freigegeben werden.

Die Kamerahardware ist eine gemeinsam genutzte Ressource, die sorgfältig verwaltet werden muss, damit Ihre Anwendung nicht mit anderen Anwendungen kollidiert, die sie ebenfalls verwenden möchten. In den folgenden Abschnitten wird erläutert, wie Sie Kamerahardware erkennen, Zugriff auf eine Kamera anfordern, Bilder oder Videos aufnehmen und die Kamera freigeben, wenn Ihre Anwendung sie nicht mehr verwendet.

Achtung:Denken Sie daran, das Objekt Camera freizugeben, indem Sie Camera.release() aufrufen, wenn Ihre Anwendung es nicht mehr verwendet. Wenn Ihre Anwendung die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Zugriffsversuche auf die Kamera fehl, auch die Ihrer eigenen Anwendung, und können dazu führen, dass Ihre oder andere Anwendungen heruntergefahren werden.

Kamerahardware wird erkannt

Wenn für Ihre App keine Kamera mit Manifestdeklaration erforderlich ist, sollten Sie prüfen, ob eine Kamera zur Laufzeit verfügbar ist. Verwenden Sie dazu die Methode PackageManager.hasSystemFeature(), wie im folgenden Beispielcode gezeigt:

Kotlin

/** Check if this device has a camera */
private fun checkCameraHardware(context: Context): Boolean {
    if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        // this device has a camera
        return true
    } else {
        // no camera on this device
        return false
    }
}

Java

/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

Android-Geräte können mehrere Kameras haben, z. B. eine Rückkamera für Fotografie und eine Frontkamera für Videoanrufe. Mit Android 2.3 (API-Level 9) und höher können Sie die Anzahl der auf einem Gerät verfügbaren Kameras mit der Methode Camera.getNumberOfCameras() prüfen.

Zugriff auf Kameras

Wenn Sie festgestellt haben, dass das Gerät, auf dem Ihre Anwendung ausgeführt wird, eine Kamera hat, müssen Sie den Zugriff durch Abrufen einer Instanz von Camera anfordern (es sei denn, Sie verwenden einen Intent für den Zugriff auf die Kamera).

Verwenden Sie die Methode Camera.open(), um auf die primäre Kamera zuzugreifen. Achten Sie dabei darauf, alle Ausnahmen zu erfassen, wie im folgenden Code gezeigt:

Kotlin

/** A safe way to get an instance of the Camera object. */
fun getCameraInstance(): Camera? {
    return try {
        Camera.open() // attempt to get a Camera instance
    } catch (e: Exception) {
        // Camera is not available (in use or does not exist)
        null // returns null if camera is unavailable
    }
}

Java

/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}

Achtung:Wenn Sie Camera.open() verwenden, sollten Sie immer auf Ausnahmen prüfen. Wenn Sie nicht auf Ausnahmen prüfen, wenn die Kamera verwendet wird oder nicht vorhanden ist, wird Ihre Anwendung vom System heruntergefahren.

Auf Geräten mit Android 2.3 (API-Level 9) oder höher kannst du mit Camera.open(int) auf bestimmte Kameras zugreifen. Mit dem Beispielcode oben wird auf die erste rückseitige Kamera eines Geräts mit mehr als einer Kamera zugegriffen.

Kamerafunktionen werden geprüft

Sobald Sie Zugriff auf eine Kamera haben, können Sie mithilfe der Methode Camera.getParameters() weitere Informationen zu ihren Funktionen abrufen. Prüfen Sie außerdem das zurückgegebene Camera.Parameters-Objekt auf unterstützte Funktionen. Wenn du API-Level 9 oder höher verwendest, kannst du mit Camera.getCameraInfo() feststellen, ob sich eine Kamera auf der Vorder- oder Rückseite des Geräts befindet und wie die Bilder ausgerichtet sind.

Vorschauklasse erstellen

Damit Nutzer effektiv Fotos oder Videos aufnehmen können, müssen sie sehen können, was die Gerätekamera sieht. Eine Kameravorschauklasse ist eine SurfaceView, die die Live-Bilddaten einer Kamera anzeigen kann, damit Nutzer ein Bild oder Video aufnehmen und aufnehmen können.

Der folgende Beispielcode zeigt, wie Sie eine einfache Kameravorschauklasse erstellen, die in ein View-Layout aufgenommen werden kann. Mit dieser Klasse wird SurfaceHolder.Callback implementiert, um die Callback-Ereignisse zum Erstellen und Löschen der Ansicht zu erfassen. Diese sind für das Zuweisen der Kameravorschaueingabe erforderlich.

Kotlin

/** A basic Camera preview class */
class CameraPreview(
        context: Context,
        private val mCamera: Camera
) : SurfaceView(context), SurfaceHolder.Callback {

    private val mHolder: SurfaceHolder = holder.apply {
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        addCallback(this@CameraPreview)
        // deprecated setting, but required on Android versions prior to 3.0
        setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        mCamera.apply {
            try {
                setPreviewDisplay(holder)
                startPreview()
            } catch (e: IOException) {
                Log.d(TAG, "Error setting camera preview: ${e.message}")
            }
        }
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.
        if (mHolder.surface == null) {
            // preview surface does not exist
            return
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview()
        } catch (e: Exception) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        mCamera.apply {
            try {
                setPreviewDisplay(mHolder)
                startPreview()
            } catch (e: Exception) {
                Log.d(TAG, "Error starting camera preview: ${e.message}")
            }
        }
    }
}

Java

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

Wenn Sie eine bestimmte Größe für die Kameravorschau festlegen möchten, legen Sie dies in der Methode surfaceChanged() fest, wie in den Kommentaren oben beschrieben. Beim Festlegen der Vorschaugröße müssen Sie Werte aus getSupportedPreviewSizes() verwenden. Legen Sie in der Methode setPreviewSize() keine beliebigen Werte fest.

Hinweis:Mit der Einführung der Mehrfensterfunktion in Android 7.0 (API-Ebene 24) und höher können Sie nicht mehr davon ausgehen, dass das Seitenverhältnis der Vorschau mit Ihrer Aktivität übereinstimmt, auch nachdem Sie setDisplayOrientation() aufgerufen haben. Je nach Fenstergröße und -verhältnis müssen Sie möglicherweise eine Weitwinkelvorschau der Kamera in ein Layout im Hochformat anpassen oder umgekehrt, indem Sie ein Letterbox-Layout verwenden.

Vorschau in ein Layout einfügen

Eine Kameravorschauklasse wie das im vorherigen Abschnitt gezeigte Beispiel muss zusammen mit anderen Steuerelementen der Benutzeroberfläche zum Aufnehmen eines Fotos oder Videos im Layout einer Aktivität platziert werden. In diesem Abschnitt erfahren Sie, wie Sie ein grundlegendes Layout und eine Aktivität für die Vorschau erstellen.

Der folgende Layoutcode bietet eine sehr einfache Ansicht, die zum Anzeigen einer Kameravorschau verwendet werden kann. In diesem Beispiel ist das FrameLayout-Element als Container für die Kameravorschauklasse vorgesehen. Dieser Layouttyp wird verwendet, damit zusätzliche Bildinformationen oder Steuerelemente über die Live-Kameravorschaubilder gelegt werden können.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

Auf den meisten Geräten ist die Standardausrichtung der Kameravorschau das Querformat. In diesem Beispiellayout wird ein horizontales Layout (Querformat) angegeben und der folgende Code legt die Ausrichtung der Anwendung im Querformat fest. Um das Rendern einer Kameravorschau zu vereinfachen, sollten Sie die Ausrichtung der Vorschauaktivitäten Ihrer Anwendung ins Querformat ändern. Fügen Sie dazu dem Manifest Folgendes hinzu.

<activity android:name=".CameraActivity"
          android:label="@string/app_name"

          android:screenOrientation="landscape">
          <!-- configure this activity to use landscape orientation -->

          <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Hinweis:Eine Kameravorschau muss nicht im Querformat sein. Ab Android 2.2 (API-Level 8) können Sie mit der Methode setDisplayOrientation() die Rotation des Vorschaubilds festlegen. Wenn Sie die Vorschauausrichtung ändern möchten, wenn der Nutzer das Smartphone neu richtet, beenden Sie die Vorschau in der surfaceChanged()-Methode der Vorschauklasse, indem Sie Camera.stopPreview() die Ausrichtung ändern und sie dann mit Camera.startPreview() noch einmal starten.

Fügen Sie in der Aktivität für die Kameraansicht die Vorschauklasse dem FrameLayout-Element hinzu, das im Beispiel oben gezeigt wird. Außerdem muss durch Ihre Kameraaktivität sichergestellt sein, dass die Kamera loslässt, wenn sie pausiert oder heruntergefahren wird. Das folgende Beispiel zeigt, wie Sie eine Kameraaktivität so ändern, dass die Vorschauklasse angehängt wird, die unter Vorschauklasse erstellen beschrieben wird.

Kotlin

class CameraActivity : Activity() {

    private var mCamera: Camera? = null
    private var mPreview: CameraPreview? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Create an instance of Camera
        mCamera = getCameraInstance()

        mPreview = mCamera?.let {
            // Create our Preview view
            CameraPreview(this, it)
        }

        // Set the Preview view as the content of our activity.
        mPreview?.also {
            val preview: FrameLayout = findViewById(R.id.camera_preview)
            preview.addView(it)
        }
    }
}

Java

public class CameraActivity extends Activity {

    private Camera mCamera;
    private CameraPreview mPreview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create an instance of Camera
        mCamera = getCameraInstance();

        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }
}

Hinweis:Die Methode getCameraInstance() im Beispiel oben bezieht sich auf die Beispielmethode unter Auf Kameras zugreifen.

Bilder aufnehmen

Nachdem Sie eine Vorschauklasse und ein Ansichtslayout für die Darstellung erstellt haben, können Sie mit der Aufnahme von Bildern mit Ihrer Anwendung beginnen. In Ihrem Anwendungscode müssen Sie Listener einrichten, damit die Steuerelemente der Benutzeroberfläche mit der Aufnahme eines Bildes auf eine Nutzeraktion reagieren können.

Verwenden Sie zum Abrufen eines Bildes die Methode Camera.takePicture(). Diese Methode verwendet drei Parameter, die Daten von der Kamera empfangen. Um Daten im JPEG-Format zu empfangen, müssen Sie eine Camera.PictureCallback-Schnittstelle implementieren, um die Bilddaten zu empfangen und in eine Datei zu schreiben. Der folgende Code zeigt eine grundlegende Implementierung der Camera.PictureCallback-Schnittstelle zum Speichern eines von der Kamera empfangenen Bilds.

Kotlin

private val mPicture = Camera.PictureCallback { data, _ ->
    val pictureFile: File = getOutputMediaFile(MEDIA_TYPE_IMAGE) ?: run {
        Log.d(TAG, ("Error creating media file, check storage permissions"))
        return@PictureCallback
    }

    try {
        val fos = FileOutputStream(pictureFile)
        fos.write(data)
        fos.close()
    } catch (e: FileNotFoundException) {
        Log.d(TAG, "File not found: ${e.message}")
    } catch (e: IOException) {
        Log.d(TAG, "Error accessing file: ${e.message}")
    }
}

Java

private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions");
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};

Lösen Sie die Aufnahme eines Bildes aus, indem Sie die Methode Camera.takePicture() aufrufen. Der folgende Beispielcode zeigt, wie diese Methode über die Schaltfläche View.OnClickListener aufgerufen wird.

Kotlin

val captureButton: Button = findViewById(R.id.button_capture)
captureButton.setOnClickListener {
    // get an image from the camera
    mCamera?.takePicture(null, null, picture)
}

Java

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // get an image from the camera
            mCamera.takePicture(null, null, picture);
        }
    }
);

Hinweis:Im folgenden Beispiel bezieht sich das Mitglied mPicture auf den Beispielcode oben.

Achtung:Denken Sie daran, das Objekt Camera freizugeben, indem Sie Camera.release() aufrufen, wenn Ihre Anwendung es nicht mehr verwendet. Informationen zum Lösen der Kamera finden Sie unter Kamera freigeben.

Aufnehmen von Videos

Die Videoaufnahme mit dem Android-Framework erfordert eine sorgfältige Verwaltung des Camera-Objekts und Koordination mit der MediaRecorder-Klasse. Bei der Videoaufzeichnung mit Camera musst du neben den Camera.open()- und Camera.release()-Aufrufen die Aufrufe Camera.lock() und Camera.unlock() verwalten, um MediaRecorder Zugriff auf die Kamerahardware zu gewähren.

Hinweis: Ab Android 4.0 (API-Level 14) werden die Aufrufe Camera.lock() und Camera.unlock() automatisch für dich verwaltet.

Im Gegensatz zur Aufnahme von Bildern mit der Kamera eines Geräts erfordert das Aufnehmen von Videos eine ganz bestimmte Aufrufreihenfolge. Sie müssen eine bestimmte Reihenfolge für die Ausführung einhalten, um mit Ihrer Anwendung Videos vorzubereiten und wie unten beschrieben aufzunehmen.

  1. Kamera öffnen: Verwenden Sie Camera.open(), um eine Instanz des Kameraobjekts abzurufen.
  2. Vorschau verbinden: Sie können eine Live-Bildvorschau der Kamera erstellen, indem Sie ein SurfaceView über Camera.setPreviewDisplay() mit der Kamera verbinden.
  3. Vorschau starten: Rufen Sie Camera.startPreview() auf, um sich die Live-Kamerabilder anzeigen zu lassen.
  4. Videoaufnahme starten: Für die Videoaufnahme müssen die folgenden Schritte in der richtigen Reihenfolge ausgeführt werden:
    1. Kamera entsperren – Entsperre die Kamera zur Verwendung durch MediaRecorder, indem du Camera.unlock() aufrufst.
    2. MediaRecorder konfigurieren: Rufe die folgenden MediaRecorder-Methoden in dieser Reihenfolge auf. Weitere Informationen finden Sie in der Referenzdokumentation zu MediaRecorder.
      1. setCamera(): Lege die Kamera fest, die für die Videoaufnahme verwendet werden soll. Verwende die aktuelle Instanz von Camera deiner Anwendung.
      2. setAudioSource(): Legen Sie die Audioquelle fest. Verwenden Sie dazu MediaRecorder.AudioSource.CAMCORDER.
      3. setVideoSource(): Legen Sie die Videoquelle fest. Verwenden Sie MediaRecorder.VideoSource.CAMERA.
      4. Lege das Ausgabeformat und die Codierung des Videos fest. Verwenden Sie für Android 2.2 (API-Level 8) und höher die Methode MediaRecorder.setProfile und rufen Sie eine Profilinstanz mit CamcorderProfile.get() ab. Bei Android-Versionen vor 2.2 müssen das Videoausgabeformat und die Codierungsparameter festgelegt werden:
        1. setOutputFormat(): Legen Sie das Ausgabeformat fest und geben Sie die Standardeinstellung an oder MediaRecorder.OutputFormat.MPEG_4.
        2. setAudioEncoder(): Legen Sie den Toncodierungstyp fest, geben Sie die Standardeinstellung an oder MediaRecorder.AudioEncoder.AMR_NB.
        3. setVideoEncoder(): Legen Sie den Videocodierungstyp fest, geben Sie die Standardeinstellung an oder MediaRecorder.VideoEncoder.MPEG_4_SP.
      5. setOutputFile(): Legen Sie die Ausgabedatei fest. Verwenden Sie dazu getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() der Beispielmethode im Abschnitt Mediendateien speichern.
      6. setPreviewDisplay(): Geben Sie das Vorschau-Layoutelement SurfaceView für Ihre App an. Verwenden Sie dasselbe Objekt, das Sie für Connect Preview angegeben haben.

      Achtung:Sie müssen diese MediaRecorder-Konfigurationsmethoden in dieser Reihenfolge aufrufen. Andernfalls treten in Ihrer Anwendung Fehler auf und die Aufzeichnung schlägt fehl.

    3. Prepare MediaRecorder: Bereiten Sie den MediaRecorder mit den angegebenen Konfigurationseinstellungen vor. Rufen Sie dazu MediaRecorder.prepare() auf.
    4. MediaRecorder starten: Rufe MediaRecorder.start() auf, um ein Video aufzunehmen.
  5. Videoaufzeichnung beenden: Rufen Sie der Reihe nach die folgenden Methoden auf, um eine Videoaufzeichnung erfolgreich abzuschließen:
    1. MediaRecorder beenden: Beende die Videoaufzeichnung durch Aufrufen von MediaRecorder.stop().
    2. MediaRecorder zurücksetzen: Entfernen Sie optional die Konfigurationseinstellungen aus dem Rekorder, indem Sie MediaRecorder.reset() aufrufen.
    3. MediaRecorder Release – Lasse MediaRecorder durch Aufrufen von MediaRecorder.release() los.
    4. Kamera sperren: Rufe Camera.lock() auf, damit die Kamera in zukünftigen MediaRecorder-Sitzungen verwendet werden kann. Ab Android 4.0 (API-Level 14) ist dieser Aufruf nur erforderlich, wenn der MediaRecorder.prepare()-Aufruf fehlschlägt.
  6. Vorschau beenden: Wenn deine Aktivität die Verwendung der Kamera beendet hat, kannst du die Vorschau mit Camera.stopPreview() beenden.
  7. Kamera freigeben: Lassen Sie die Kamera los, damit andere Anwendungen sie verwenden können. Rufen Sie dazu Camera.release() auf.

Hinweis:Sie können MediaRecorder verwenden, ohne vorher eine Kameravorschau zu erstellen, und die ersten Schritte dieses Vorgangs überspringen. Da Nutzer sich jedoch normalerweise vor dem Start einer Aufzeichnung eine Vorschau ansehen möchten, wird dieser Vorgang hier nicht erläutert.

Tipp:Wenn Ihre Anwendung normalerweise zum Aufzeichnen von Videos verwendet wird, legen Sie setRecordingHint(boolean) auf true fest, bevor Sie die Vorschau starten. Mit dieser Einstellung können Sie die Startzeit der Aufzeichnung verkürzen.

MediaRecorder konfigurieren

Wenn Sie die Klasse MediaRecorder zum Aufzeichnen von Videos verwenden, müssen Sie die Konfigurationsschritte in einer bestimmten Reihenfolge ausführen und dann die Methode MediaRecorder.prepare() aufrufen, um die Konfiguration zu prüfen und zu implementieren. Der folgende Beispielcode zeigt, wie die MediaRecorder-Klasse für die Videoaufzeichnung richtig konfiguriert und vorbereitet wird.

Kotlin

private fun prepareVideoRecorder(): Boolean {
    mediaRecorder = MediaRecorder()

    mCamera?.let { camera ->
        // Step 1: Unlock and set camera to MediaRecorder
        camera?.unlock()

        mediaRecorder?.run {
            setCamera(camera)

            // Step 2: Set sources
            setAudioSource(MediaRecorder.AudioSource.CAMCORDER)
            setVideoSource(MediaRecorder.VideoSource.CAMERA)

            // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
            setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH))

            // Step 4: Set output file
            setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString())

            // Step 5: Set the preview output
            setPreviewDisplay(mPreview?.holder?.surface)

            setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
            setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
            setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT)


            // Step 6: Prepare configured MediaRecorder
            return try {
                prepare()
                true
            } catch (e: IllegalStateException) {
                Log.d(TAG, "IllegalStateException preparing MediaRecorder: ${e.message}")
                releaseMediaRecorder()
                false
            } catch (e: IOException) {
                Log.d(TAG, "IOException preparing MediaRecorder: ${e.message}")
                releaseMediaRecorder()
                false
            }
        }

    }
    return false
}

Java

private boolean prepareVideoRecorder(){

    mCamera = getCameraInstance();
    mediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: Set output file
    mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: Set the preview output
    mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
    try {
        mediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

Vor Android 2.2 (API-Level 8) musst du das Ausgabeformat und die Codierungsformate direkt festlegen, anstatt CamcorderProfile zu verwenden. Dieser Ansatz wird im folgenden Code veranschaulicht:

Kotlin

    // Step 3: Set output format and encoding (for versions prior to API Level 8)
    mediaRecorder?.apply {
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
        setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT)
    }

Java

    // Step 3: Set output format and encoding (for versions prior to API Level 8)
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);

Die folgenden Parameter für die Videoaufnahme für MediaRecorder sind Standardeinstellungen festgelegt. Sie können diese Einstellungen für Ihre App jedoch anpassen:

MediaRecorder starten und beenden

Wenn Sie die Videoaufzeichnung mit der Klasse MediaRecorder starten und beenden, müssen Sie eine bestimmte Reihenfolge einhalten, wie unten aufgeführt.

  1. Kamera mit Camera.unlock() entsperren
  2. Konfigurieren Sie MediaRecorder wie im obigen Codebeispiel gezeigt
  3. Aufnahme mit MediaRecorder.start() starten
  4. Video aufnehmen
  5. Aufnahme mit MediaRecorder.stop() beenden
  6. Lasse den Medienrekorder mit MediaRecorder.release() los
  7. Kamera mit Camera.lock() sperren

Der folgende Beispielcode zeigt, wie eine Schaltfläche verbunden wird, um die Videoaufzeichnung mit der Kamera und der Klasse MediaRecorder richtig zu starten und zu beenden.

Hinweis:Lassen Sie die Kamera nicht los, wenn Sie eine Videoaufnahme abgeschlossen haben. Andernfalls wird die Vorschau angehalten.

Kotlin

var isRecording = false
val captureButton: Button = findViewById(R.id.button_capture)
captureButton.setOnClickListener {
    if (isRecording) {
        // stop recording and release camera
        mediaRecorder?.stop() // stop the recording
        releaseMediaRecorder() // release the MediaRecorder object
        mCamera?.lock() // take camera access back from MediaRecorder

        // inform the user that recording has stopped
        setCaptureButtonText("Capture")
        isRecording = false
    } else {
        // initialize video camera
        if (prepareVideoRecorder()) {
            // Camera is available and unlocked, MediaRecorder is prepared,
            // now you can start recording
            mediaRecorder?.start()

            // inform the user that recording has started
            setCaptureButtonText("Stop")
            isRecording = true
        } else {
            // prepare didn't work, release the camera
            releaseMediaRecorder()
            // inform user
        }
    }
}

Java

private boolean isRecording = false;

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isRecording) {
                // stop recording and release camera
                mediaRecorder.stop();  // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object
                mCamera.lock();         // take camera access back from MediaRecorder

                // inform the user that recording has stopped
                setCaptureButtonText("Capture");
                isRecording = false;
            } else {
                // initialize video camera
                if (prepareVideoRecorder()) {
                    // Camera is available and unlocked, MediaRecorder is prepared,
                    // now you can start recording
                    mediaRecorder.start();

                    // inform the user that recording has started
                    setCaptureButtonText("Stop");
                    isRecording = true;
                } else {
                    // prepare didn't work, release the camera
                    releaseMediaRecorder();
                    // inform user
                }
            }
        }
    }
);

Hinweis:Im obigen Beispiel bezieht sich die Methode prepareVideoRecorder() auf den Beispielcode unter MediaRecorder konfigurieren. Mit dieser Methode wird die Kamera gesperrt und die MediaRecorder-Instanz konfiguriert und vorbereitet.

Kamera freigeben

Kameras sind Ressourcen, die von Anwendungen auf einem Gerät gemeinsam genutzt werden. Ihre Anwendung kann die Kamera nach dem Abrufen einer Instanz von Camera verwenden. Achten Sie besonders darauf, das Kameraobjekt freizugeben, wenn Ihre Anwendung es nicht mehr verwendet, und sobald Ihre Anwendung pausiert wird (Activity.onPause()). Wird die Kamera durch Ihre Anwendung nicht ordnungsgemäß freigegeben, schlagen alle nachfolgenden Zugriffsversuche auf die Kamera – auch durch Ihre eigene Anwendung – fehl und können dazu führen, dass Ihre Anwendung oder andere Anwendungen heruntergefahren werden.

Um eine Instanz des Camera-Objekts freizugeben, verwenden Sie die Camera.release()-Methode, wie im folgenden Beispielcode gezeigt.

Kotlin

class CameraActivity : Activity() {
    private var mCamera: Camera?
    private var preview: SurfaceView?
    private var mediaRecorder: MediaRecorder?

    override fun onPause() {
        super.onPause()
        releaseMediaRecorder() // if you are using MediaRecorder, release it first
        releaseCamera() // release the camera immediately on pause event
    }

    private fun releaseMediaRecorder() {
        mediaRecorder?.reset() // clear recorder configuration
        mediaRecorder?.release() // release the recorder object
        mediaRecorder = null
        mCamera?.lock() // lock camera for later use
    }

    private fun releaseCamera() {
        mCamera?.release() // release the camera for other applications
        mCamera = null
    }
}

Java

public class CameraActivity extends Activity {
    private Camera mCamera;
    private SurfaceView preview;
    private MediaRecorder mediaRecorder;

    ...

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder();       // if you are using MediaRecorder, release it first
        releaseCamera();              // release the camera immediately on pause event
    }

    private void releaseMediaRecorder(){
        if (mediaRecorder != null) {
            mediaRecorder.reset();   // clear recorder configuration
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
            mCamera.lock();           // lock camera for later use
        }
    }

    private void releaseCamera(){
        if (mCamera != null){
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
    }
}

Achtung:Wenn Ihre Anwendung die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Zugriffsversuche auf die Kamera fehl, auch durch Ihre eigene Anwendung, und können dazu führen, dass Ihre Anwendung oder andere Anwendungen heruntergefahren werden.

Mediendateien werden gespeichert

Von Nutzern erstellte Mediendateien, z. B. Bilder und Videos, sollten im externen Speicherverzeichnis eines Geräts (SD-Karte) gespeichert werden, um Systemspeicherplatz zu sparen und Nutzern den Zugriff auf diese Dateien ohne ihr Gerät zu ermöglichen. Es gibt viele mögliche Verzeichnisspeicherorte zum Speichern von Mediendateien auf einem Gerät, es gibt jedoch nur zwei Standardspeicherorte, die du als Entwickler in Betracht ziehen solltest:

  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES): Diese Methode gibt den standardmäßigen, geteilten und empfohlenen Speicherort zum Speichern von Bildern und Videos zurück. Dieses Verzeichnis ist freigegeben (öffentlich), sodass andere Anwendungen an diesem Speicherort gespeicherte Dateien leicht finden, lesen, ändern und löschen können. Wenn Ihre App vom Nutzer deinstalliert wird, werden Mediendateien, die an diesem Speicherort gespeichert sind, nicht entfernt. Damit vorhandene Bilder und Videos von Nutzern nicht beeinträchtigt werden, sollten Sie in diesem Verzeichnis ein Unterverzeichnis für die Mediendateien Ihrer Anwendung erstellen, wie im folgenden Codebeispiel gezeigt. Diese Methode ist in Android 2.2 (API-Level 8) verfügbar. Entsprechende Aufrufe in früheren API-Versionen finden Sie unter Freigegebene Dateien speichern.
  • Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES): Diese Methode gibt einen Standardspeicherort für Bilder und Videos zurück, die mit Ihrer App verknüpft sind. Wenn Ihre App deinstalliert wird, werden alle an diesem Speicherort gespeicherten Dateien entfernt. Für Dateien an diesem Speicherort wird keine Sicherheit erzwungen. Andere Anwendungen können sie lesen, ändern oder löschen.

Der folgende Beispielcode zeigt, wie ein File- oder Uri-Speicherort für eine Mediendatei erstellt wird, die beim Aufrufen der Kamera eines Geräts mit einer Intent oder als Teil einer Erstellung einer Kamera-App verwendet werden kann.

Kotlin

val MEDIA_TYPE_IMAGE = 1
val MEDIA_TYPE_VIDEO = 2

/** Create a file Uri for saving an image or video */
private fun getOutputMediaFileUri(type: Int): Uri {
    return Uri.fromFile(getOutputMediaFile(type))
}

/** Create a File for saving an image or video */
private fun getOutputMediaFile(type: Int): File? {
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    val mediaStorageDir = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "MyCameraApp"
    )
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    mediaStorageDir.apply {
        if (!exists()) {
            if (!mkdirs()) {
                Log.d("MyCameraApp", "failed to create directory")
                return null
            }
        }
    }

    // Create a media file name
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    return when (type) {
        MEDIA_TYPE_IMAGE -> {
            File("${mediaStorageDir.path}${File.separator}IMG_$timeStamp.jpg")
        }
        MEDIA_TYPE_VIDEO -> {
            File("${mediaStorageDir.path}${File.separator}VID_$timeStamp.mp4")
        }
        else -> null
    }
}

Java

public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;

/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
      return Uri.fromFile(getOutputMediaFile(type));
}

/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");
    } else if(type == MEDIA_TYPE_VIDEO) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "VID_"+ timeStamp + ".mp4");
    } else {
        return null;
    }

    return mediaFile;
}

Hinweis: Environment.getExternalStoragePublicDirectory() ist ab Android 2.2 (API-Level 8) verfügbar. Wenn deine Anzeigen auf Geräte mit älteren Android-Versionen ausgerichtet sind, verwende stattdessen Environment.getExternalStorageDirectory(). Weitere Informationen finden Sie unter Freigegebene Dateien speichern.

Damit der URI Arbeitsprofile unterstützt, konvertieren Sie zuerst den Datei-URI in einen Inhalts-URI. Fügen Sie dann den Inhalts-URI in EXTRA_OUTPUT einer Intent ein.

Weitere Informationen zum Speichern von Dateien auf einem Android-Gerät finden Sie unter Datenspeicher.

Kamerafunktionen

Android unterstützt eine Vielzahl von Kamerafunktionen, die Sie über Ihre Kamera-App steuern können, darunter Bildformat, Blitzmodus, Fokuseinstellungen und vieles mehr. In diesem Abschnitt werden die gängigen Kamerafunktionen und ihre Verwendung kurz erläutert. Auf die meisten Kamerafunktionen kann mit dem through Camera.Parameters-Objekt zugegriffen werden und es kann festgelegt werden. Es gibt jedoch einige wichtige Funktionen, für die mehr als einfache Einstellungen in Camera.Parameters erforderlich sind. Diese Funktionen werden in den folgenden Abschnitten behandelt:

Allgemeine Informationen zur Verwendung von Funktionen, die über Camera.Parameters gesteuert werden, finden Sie im Abschnitt Kamerafunktionen verwenden. Weitere Informationen zur Verwendung von Funktionen, die über das Kameraparameterobjekt gesteuert werden, finden Sie über die Links in der Liste der Funktionen zur API-Referenzdokumentation.

Tabelle 1 Allgemeine Kamerafunktionen, sortiert nach dem Android API-Level, auf dem sie eingeführt wurden.

Funktion API-Ebene Beschreibung
Gesichtserkennung 14 Erkennen Sie menschliche Gesichter in einem Bild und verwenden Sie sie zur Fokussierung, Messung und zum Weißabgleich.
Messbereiche 14 Einen oder mehrere Bereiche in einem Bild zur Berechnung des Weißabgleichs angeben
Schwerpunkte 14 Einen oder mehrere Bereiche in einem Bild zur Fokussierung festlegen
White Balance Lock 14 Automatische Weißabgleichanpassungen stoppen oder starten
Exposure Lock 14 Automatische Belichtungsanpassung starten oder stoppen
Video Snapshot 14 Bild während der Videodrehung aufnehmen (Frame-Erfassung)
Zeitraffervideo 11 Frames mit festgelegten Verzögerungen aufnehmen, um ein Video im Zeitraffer aufzunehmen
Multiple Cameras 9 Unterstützung für mehr als eine Kamera auf einem Gerät, einschließlich Front- und Rückkameras
Focus Distance 9 Gibt die Abstände zwischen der Kamera und Objekten an, die im Fokus zu sein scheinen
Zoom 8 Bildvergrößerung festlegen
Exposure Compensation 8 Belichtung erhöhen oder verringern
GPS Data 5 Geografische Standortdaten in das Bild einbeziehen oder auslassen
White Balance 5 Stellen Sie den Weißabgleichmodus ein. Dieser wirkt sich auf die Farbwerte im aufgenommenen Bild aus.
Focus Mode 5 Einstellen, wie die Kamera auf ein Motiv fokussiert (z. B. automatisch, fest, Makro- oder unendlich)
Scene Mode 5 Einen voreingestellten Modus für bestimmte Arten von Fotosituationen anwenden, z. B. Nacht-, Strand-, Schnee- oder Kerzenlichtszenen
JPEG Quality 5 Legen Sie die Komprimierungsstufe für ein JPEG-Bild fest. Dadurch werden Qualität und Größe der Ausgabedatei erhöht oder verringert.
Flash Mode 5 Blitz ein- oder ausschalten oder automatische Einstellung verwenden
Color Effects 5 Wenden Sie einen Farbeffekt auf das aufgenommene Bild an, z. B. Schwarz-Weiß, Sepiaton oder Negativ.
Anti-Banding 5 Reduziert durch die JPEG-Komprimierung den Effekt von Streifenbildung bei Farbverläufen
Picture Format 1 Dateiformat für das Bild angeben
Picture Size 1 Legen Sie die Pixelabmessungen des gespeicherten Bilds fest.

Hinweis:Diese Funktionen werden aufgrund von Hardwareunterschieden und Softwareimplementierung nicht auf allen Geräten unterstützt. Informationen zum Prüfen der Verfügbarkeit von Funktionen auf dem Gerät, auf dem Ihre Anwendung ausgeführt wird, finden Sie unter Verfügbarkeit von Funktionen prüfen.

Verfügbarkeit von Funktionen wird geprüft

Wenn Sie Kamerafunktionen auf Android-Geräten verwenden, müssen Sie zuerst wissen, dass nicht alle Kamerafunktionen auf allen Geräten unterstützt werden. Außerdem können Geräte, die eine bestimmte Funktion unterstützen, diese auf einer anderen Stufe oder mit anderen Optionen unterstützen. Daher müssen Sie bei der Entwicklung einer Kameraanwendung entscheiden, welche Kamerafunktionen Sie auf welcher Ebene unterstützen möchten. Nach dieser Entscheidung sollten Sie Code in Ihre Kameraanwendung einbinden, um zu prüfen, ob die Gerätehardware diese Funktionen unterstützt und ordnungsgemäß ausfällt, wenn eine Funktion nicht verfügbar ist.

Sie können die Verfügbarkeit von Kamerafunktionen prüfen, indem Sie eine Instanz des Parameterobjekts einer Kamera abrufen und die relevanten Methoden prüfen. Das folgende Codebeispiel zeigt, wie Sie ein Camera.Parameters-Objekt abrufen und prüfen, ob die Kamera die Autofokus-Funktion unterstützt:

Kotlin

val params: Camera.Parameters? = camera?.parameters
val focusModes: List<String>? = params?.supportedFocusModes
if (focusModes?.contains(Camera.Parameters.FOCUS_MODE_AUTO) == true) {
    // Autofocus mode is supported
}

Java

// get Camera parameters
Camera.Parameters params = camera.getParameters();

List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
  // Autofocus mode is supported
}

Sie können die oben beschriebene Technik für die meisten Kamerafunktionen verwenden. Das Camera.Parameters-Objekt bietet eine getSupported...()-, is...Supported()- oder getMax...()-Methode, um festzustellen, ob und in welchem Umfang ein Feature unterstützt wird.

Wenn für Ihre App bestimmte Kamerafunktionen erforderlich sind, damit sie ordnungsgemäß funktionieren, können Sie diese über Ergänzungen zu Ihrem App-Manifest anfordern. Wenn du die Verwendung bestimmter Kamerafunktionen wie Blitz und Autofokus angibst, schränkt Google Play die Installation deiner App auf Geräten ein, die diese Funktionen nicht unterstützen. Eine Liste der Kamerafunktionen, die in Ihrem App-Manifest deklariert werden können, finden Sie in der Funktionsreferenz des Manifests.

Kamerafunktionen verwenden

Die meisten Kamerafunktionen werden mit einem Camera.Parameters-Objekt aktiviert und gesteuert. Um dieses Objekt zu erhalten, rufen Sie zuerst eine Instanz des Camera-Objekts ab, rufen die Methode getParameters() auf, ändern das zurückgegebene Parameterobjekt und setzen es dann wieder in das Kameraobjekt ein, wie im folgenden Beispielcode gezeigt:

Kotlin

val params: Camera.Parameters? = camera?.parameters
params?.focusMode = Camera.Parameters.FOCUS_MODE_AUTO
camera?.parameters = params

Java

// get Camera parameters
Camera.Parameters params = camera.getParameters();
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
camera.setParameters(params);

Diese Technik funktioniert für fast alle Kamerafunktionen. Die meisten Parameter können jederzeit geändert werden, nachdem Sie eine Instanz des Camera-Objekts abgerufen haben. Änderungen an Parametern sind für den Nutzer in der Regel sofort in der Kameravorschau der Anwendung sichtbar. Softwareseitig kann es mehrere Frames dauern, bis Parameteränderungen tatsächlich wirksam werden, wenn die Kamerahardware die neuen Anweisungen verarbeitet und dann aktualisierte Bilddaten sendet.

Wichtig:Einige Kamerafunktionen können nicht automatisch geändert werden. Insbesondere wenn Sie die Größe oder Ausrichtung der Kameravorschau ändern möchten, müssen Sie sie zuerst beenden, ihre Größe ändern und die Vorschau dann neu starten. Ab Android 4.0 (API-Level 14) kann die Vorschauausrichtung geändert werden, ohne dass die Vorschau neu gestartet wird.

Für die Implementierung anderer Kamerafunktionen ist mehr Code erforderlich:

  • Mess- und Fokusbereiche
  • Gesichtserkennung
  • Zeitraffervideo

In den folgenden Abschnitten erhalten Sie einen kurzen Überblick über die Implementierung dieser Funktionen.

Mess- und Fokusbereiche

In einigen fotografischen Szenarien liefert die automatische Fokussierung und Lichtmessung möglicherweise nicht die gewünschten Ergebnisse. Ab Android 4.0 (API-Level 14) bietet Ihre Kamera-App zusätzliche Steuerelemente, mit denen Ihre App oder Nutzer Bereiche in einem Bild zur Bestimmung der Fokus- oder Lichtintensität festlegen und diese zur Aufnahme von Bildern oder Videos an die Kamerahardware weitergeben können.

Die Bereiche für Messung und Fokus funktionieren sehr ähnlich wie andere Kamerafunktionen, da Sie sie über Methoden im Camera.Parameters-Objekt steuern. Mit dem folgenden Code werden zwei Lichtmessbereiche für eine Instanz von Camera festgelegt:

Kotlin

// Create an instance of Camera
camera = getCameraInstance()

// set Camera parameters
val params: Camera.Parameters? = camera?.parameters

params?.apply {
    if (maxNumMeteringAreas > 0) { // check that metering areas are supported
        meteringAreas = ArrayList<Camera.Area>().apply {
            val areaRect1 = Rect(-100, -100, 100, 100) // specify an area in center of image
            add(Camera.Area(areaRect1, 600)) // set weight to 60%
            val areaRect2 = Rect(800, -1000, 1000, -800) // specify an area in upper right of image
            add(Camera.Area(areaRect2, 400)) // set weight to 40%
        }
    }
    camera?.parameters = this
}

Java

// Create an instance of Camera
camera = getCameraInstance();

// set Camera parameters
Camera.Parameters params = camera.getParameters();

if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported
    List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();

    Rect areaRect1 = new Rect(-100, -100, 100, 100);    // specify an area in center of image
    meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60%
    Rect areaRect2 = new Rect(800, -1000, 1000, -800);  // specify an area in upper right of image
    meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40%
    params.setMeteringAreas(meteringAreas);
}

camera.setParameters(params);

Das Camera.Area-Objekt enthält zwei Datenparameter: ein Rect-Objekt zum Festlegen eines Bereichs im Sichtfeld der Kamera und einen Gewichtswert, der der Kamera mitteilt, welche Bedeutung dieser Bereich bei Lichtmessungen oder Fokusberechnungen erhalten soll.

Das Feld Rect in einem Camera.Area-Objekt beschreibt eine rechteckige Form, die auf einem Raster von 2.000 × 2.000 Pixeln abgebildet ist. Die Koordinaten -1000 und -1000 stehen für die linke obere Ecke des Kamerabildes und die Koordinaten 1000 und 1000 für die untere rechte Ecke des Kamerabildes, wie in der folgenden Abbildung dargestellt.

Abbildung 1: Die roten Linien veranschaulichen das Koordinatensystem für die Angabe eines Camera.Area in einer Kameravorschau. Das blaue Feld zeigt die Position und Form eines Kamerabereichs mit den Rect-Werten 333.333.667.667.

Die Grenzen dieses Koordinatensystems entsprechen immer dem äußeren Rand des Bilds, das in der Kameravorschau sichtbar ist, und werden bei der Zoomstufe nicht verkleinert oder erweitert. Ebenso wird das Koordinatensystem bei der Drehung der Bildvorschau mit Camera.setDisplayOrientation() nicht neu abgebildet.

Gesichtserkennung

Bei Bildern, auf denen Personen zu sehen sind, sind Gesichter in der Regel der wichtigste Teil des Bilds und sollten zur Bestimmung von Fokus und Weißabgleich bei der Aufnahme verwendet werden. Das Framework Android 4.0 (API-Level 14) bietet APIs für die Erkennung von Gesichtern und die Berechnung von Bildeinstellungen mithilfe der Gesichtserkennungstechnologie.

Hinweis:Während die Gesichtserkennung ausgeführt wird, haben setWhiteBalance(String), setFocusAreas(List<Camera.Area>) und setMeteringAreas(List<Camera.Area>) keine Auswirkungen.

Zur Verwendung der Gesichtserkennung in Ihrer Kamera-App sind einige allgemeine Schritte erforderlich:

  • Prüfen, ob die Gesichtserkennung auf dem Gerät unterstützt wird
  • Gesichtserkennungs-Listener erstellen
  • Gesichtserkennungs-Listener dem Kameraobjekt hinzufügen
  • Gesichtserkennung nach der Vorschau starten (und nach jedem Vorschauneustart)

Die Gesichtserkennung wird nicht auf allen Geräten unterstützt. Wenn Sie prüfen möchten, ob dieses Feature unterstützt wird, rufen Sie getMaxNumDetectedFaces() auf. Ein Beispiel für diese Prüfung finden Sie unten in der Beispielmethode startFaceDetection().

Damit Sie benachrichtigt werden und auf die Gesichtswiedererkennung reagieren können, muss Ihre Kamera-App einen Listener für Gesichtserkennungsereignisse einrichten. Dazu müssen Sie eine Listener-Klasse erstellen, die die Camera.FaceDetectionListener-Schnittstelle implementiert, wie im Beispielcode unten gezeigt.

Kotlin

internal class MyFaceDetectionListener : Camera.FaceDetectionListener {

    override fun onFaceDetection(faces: Array<Camera.Face>, camera: Camera) {
        if (faces.isNotEmpty()) {
            Log.d("FaceDetection", ("face detected: ${faces.size}" +
                    " Face 1 Location X: ${faces[0].rect.centerX()}" +
                    "Y: ${faces[0].rect.centerY()}"))
        }
    }
}

Java

class MyFaceDetectionListener implements Camera.FaceDetectionListener {

    @Override
    public void onFaceDetection(Face[] faces, Camera camera) {
        if (faces.length > 0){
            Log.d("FaceDetection", "face detected: "+ faces.length +
                    " Face 1 Location X: " + faces[0].rect.centerX() +
                    "Y: " + faces[0].rect.centerY() );
        }
    }
}

Nachdem Sie diese Klasse erstellt haben, setzen Sie sie in das Camera-Objekt Ihrer Anwendung, wie im folgenden Beispielcode gezeigt:

Kotlin

camera?.setFaceDetectionListener(MyFaceDetectionListener())

Java

camera.setFaceDetectionListener(new MyFaceDetectionListener());

Ihre Anwendung muss die Gesichtserkennungsfunktion jedes Mal starten, wenn Sie die Kameravorschau starten oder neu starten. Erstellen Sie eine Methode zum Starten der Gesichtserkennung, damit Sie sie bei Bedarf aufrufen können, wie im Beispielcode unten gezeigt.

Kotlin

fun startFaceDetection() {
    // Try starting Face Detection
    val params = mCamera?.parameters
    // start face detection only *after* preview has started

    params?.apply {
        if (maxNumDetectedFaces > 0) {
            // camera supports face detection, so can start it:
            mCamera?.startFaceDetection()
        }
    }
}

Java

public void startFaceDetection(){
    // Try starting Face Detection
    Camera.Parameters params = mCamera.getParameters();

    // start face detection only *after* preview has started
    if (params.getMaxNumDetectedFaces() > 0){
        // camera supports face detection, so can start it:
        mCamera.startFaceDetection();
    }
}

Sie müssen die Gesichtserkennung jedes Mal starten, wenn Sie die Kameravorschau starten oder neu starten. Wenn Sie die unter Vorschauklasse erstellen gezeigte Vorschauklasse verwenden, fügen Sie die Methode startFaceDetection() sowohl der Methode surfaceCreated() als auch der Methode surfaceChanged() in Ihrer Vorschauklasse hinzu, wie im Beispielcode unten gezeigt.

Kotlin

override fun surfaceCreated(holder: SurfaceHolder) {
    try {
        mCamera.setPreviewDisplay(holder)
        mCamera.startPreview()

        startFaceDetection() // start face detection feature
    } catch (e: IOException) {
        Log.d(TAG, "Error setting camera preview: ${e.message}")
    }
}

override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
    if (holder.surface == null) {
        // preview surface does not exist
        Log.d(TAG, "holder.getSurface() == null")
        return
    }
    try {
        mCamera.stopPreview()
    } catch (e: Exception) {
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: ${e.message}")
    }
    try {
        mCamera.setPreviewDisplay(holder)
        mCamera.startPreview()

        startFaceDetection() // re-start face detection feature
    } catch (e: Exception) {
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: ${e.message}")
    }
}

Java

public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // start face detection feature

    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (holder.getSurface() == null){
        // preview surface does not exist
        Log.d(TAG, "holder.getSurface() == null");
        return;
    }

    try {
        mCamera.stopPreview();

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
    }

    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // re-start face detection feature

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}

Hinweis:Denken Sie daran, diese Methode nach dem Aufrufen von startPreview() aufzurufen. Versuchen Sie nicht, die Gesichtserkennung in der Methode onCreate() der Hauptaktivität Ihrer Kamera-App zu starten, da die Vorschau zu diesem Zeitpunkt während der Ausführung Ihrer App nicht verfügbar ist.

Zeitraffervideo

Mit Zeitraffervideos können Nutzer Videoclips erstellen, in denen Bilder im Abstand von wenigen Sekunden oder Minuten kombiniert werden. Dieses Feature verwendet MediaRecorder, um die Bilder für eine Zeitraffersequenz aufzuzeichnen.

Um ein Zeitraffervideo mit MediaRecorder aufzunehmen, musst du das Rekorder-Objekt so konfigurieren, dass du ein normales Video aufnimmst. Setze die Anzahl der erfassten Bilder pro Sekunde auf eine niedrige Zahl und verwende eine der Einstellungen für die Zeitrafferqualität, wie im folgenden Codebeispiel gezeigt.

Kotlin

mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH))
mediaRecorder.setCaptureRate(0.1) // capture a frame every 10 seconds

Java

// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH));
...
// Step 5.5: Set the video capture rate to a low number
mediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds

Diese Einstellungen müssen im Rahmen eines umfassenderen Konfigurationsverfahrens für MediaRecorder vorgenommen werden. Ein vollständiges Codebeispiel für die Konfiguration finden Sie unter MediaRecorder konfigurieren. Sobald die Konfiguration abgeschlossen ist, starten Sie die Videoaufzeichnung so, als würden Sie einen normalen Videoclip aufzeichnen. Weitere Informationen zum Konfigurieren und Ausführen von MediaRecorder finden Sie unter Videos aufnehmen.

In den Beispielen für Camera2Video und HdrViewfinder wird die Verwendung der auf dieser Seite behandelten APIs weiter veranschaulicht.

Kamerafelder, für die eine Berechtigung erforderlich ist

Apps mit Android 10 (API-Level 29) oder höher müssen die Berechtigung CAMERA haben, um auf die Werte der folgenden Felder zugreifen zu können, die von der Methode getCameraCharacteristics() zurückgegeben werden:

  • LENS_POSE_ROTATION
  • LENS_POSE_TRANSLATION
  • LENS_INTRINSIC_CALIBRATION
  • LENS_RADIAL_DISTORTION
  • LENS_POSE_REFERENCE
  • LENS_DISTORTION
  • LENS_INFO_HYPERFOCAL_DISTANCE
  • LENS_INFO_MINIMUM_FOCUS_DISTANCE
  • SENSOR_REFERENCE_ILLUMINANT1
  • SENSOR_REFERENCE_ILLUMINANT2
  • SENSOR_CALIBRATION_TRANSFORM1
  • SENSOR_CALIBRATION_TRANSFORM2
  • SENSOR_COLOR_TRANSFORM1
  • SENSOR_COLOR_TRANSFORM2
  • SENSOR_FORWARD_MATRIX1
  • SENSOR_FORWARD_MATRIX2

Zusätzlicher Beispielcode

Beispiel-Apps können Sie im Camera2Basic-Beispiel und in der offiziellen CameraX-Beispiel-App herunterladen.