Camera API

Das Android-Framework unterstützt verschiedene Kameras und Kamerafunktionen auf Geräten, sodass Sie in Ihren Apps Fotos und Videos aufnehmen können. In diesem Dokument wird ein schneller, einfacher Ansatz für die Bild- und Videoaufnahme beschrieben. Außerdem wird ein erweiterter Ansatz für die Erstellung benutzerdefinierter Kamerafunktionen für Ihre Nutzer erläutert.

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

Weitere Informationen finden Sie unter den folgenden Links:

Wissenswertes

Bevor Sie Ihrer App die Verwendung von Kameras auf Android-Geräten erlauben, sollten Sie sich einige Fragen dazu stellen, wie diese Hardwarefunktion in Ihrer App verwendet werden soll.

  • Kameraanforderung: Ist die Verwendung einer Kamera für Ihre App so wichtig, dass Sie nicht möchten, dass Ihre App auf einem Gerät installiert wird, das keine Kamera hat? In diesem Fall sollten Sie die Kameraanforderung in Ihrem Manifest deklarieren.
  • Schnellfoto oder benutzerdefinierte Kamera: Wie wird die Kamera in Ihrer App verwendet? Möchten Sie nur ein schnelles Foto oder einen kurzen Videoclip aufnehmen oder bietet Ihre App eine neue Möglichkeit, Kameras zu verwenden? Wenn Sie schnell ein Foto oder Video aufnehmen möchten, können Sie vorhandene Kamera-Apps verwenden. Informationen zum Entwickeln einer benutzerdefinierten Kamerafunktion finden Sie im Abschnitt Eine Kamera-App erstellen.
  • Anforderungen an Dienste im Vordergrund: Wann interagiert Ihre App mit der Kamera? Unter Android 9 (API-Level 28) und höher können Apps, die im Hintergrund ausgeführt werden, nicht auf die Kamera zugreifen. Daher sollten Sie die Kamera entweder verwenden, wenn sich Ihre App im Vordergrund befindet, oder als Teil eines Dienstes im Vordergrund.
  • Speicher: Sollen die von Ihrer App generierten Bilder oder Videos nur für Ihre App sichtbar sein oder freigegeben werden, damit sie von anderen Apps wie der Galerie oder anderen Medien- und Social-Media-Apps verwendet werden können? Sollen die Fotos und Videos auch dann verfügbar sein, wenn die App deinstalliert wird? Im Abschnitt Mediendateien speichern erfahren Sie, wie Sie diese Optionen implementieren.

Grundlagen

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

android.hardware.camera2
Dieses Paket ist die primäre API zur Steuerung von Gerätekameras. Sie können damit Fotos oder Videos aufnehmen, wenn Sie eine Kamera-App entwickeln.
Camera
Diese Klasse ist die ältere eingestellte API zur Steuerung von Gerätekameras.
SurfaceView
Mit dieser Klasse wird dem Nutzer eine Live-Kameravorschau angezeigt.
MediaRecorder
Mit dieser Klasse werden Videos von der Kamera aufgezeichnet.
Intent
Mit einem Intent-Aktionstyp von MediaStore.ACTION_IMAGE_CAPTURE oder MediaStore.ACTION_VIDEO_CAPTURE können Sie Bilder oder Videos aufnehmen, ohne das Camera-Objekt direkt zu verwenden.

Manifesterklärungen

Bevor Sie mit der Entwicklung Ihrer Anwendung mit der Camera API beginnen, sollten Sie dafür sorgen, dass Ihr Manifest die entsprechenden Deklarationen enthält, um die Verwendung der Kamerahardware und anderer zugehöriger Funktionen zu ermöglichen.

  • Kameraberechtigung: Ihre App muss die Berechtigung zum Verwenden der Kamera des Geräts anfordern.
    <uses-permission android:name="android.permission.CAMERA" />
    

    Hinweis:Wenn Sie die Kamera über eine vorhandene Kamera-App aufrufen, muss Ihre Anwendung diese Berechtigung nicht anfordern.

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

    Eine Liste der Kamerafunktionen finden Sie in der Referenz zu Manifest-Funktionen.

    Wenn Sie Ihrem Manifest Kamerafunktionen hinzufügen, verhindert Google Play, dass Ihre App auf Geräten installiert wird, die keine Kamera haben 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 funktionsbasierte Filterung.

    Wenn Ihre Anwendung eine Kamera oder Kamerafunktion für den ordnungsgemäßen Betrieb verwenden kann, sie aber nicht erforderlich ist, sollten Sie dies im Manifest angeben. Fügen Sie dazu das Attribut android:required hinzu und legen Sie es auf false fest:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
    
  • Speicherberechtigung: Ihre App kann Bilder oder Videos im externen Speicher des Geräts (SD-Karte) 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 zur Audioaufnahme: Wenn Sie Audioinhalte mit der Videoaufnahme aufnehmen möchten, muss Ihre App die Berechtigung zur Audioaufnahme anfordern.
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
  • Berechtigung zur Standortermittlung: Wenn Ihre App Bilder mit GPS-Standortinformationen taggt, müssen Sie die Berechtigung ACCESS_FINE_LOCATION anfordern. Wenn Ihre App auf Android 5.0 (API-Level 21) oder höher ausgerichtet ist, müssen Sie außerdem angeben, dass Ihre 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

Wenn Sie in Ihrer App ohne viel zusätzlichen Code Fotos oder Videos aufnehmen möchten, können Sie mit einem Intent eine vorhandene Android-Kameraanwendung aufrufen. Weitere Informationen finden Sie in den Trainingslektionen Einfach Fotos aufnehmen und Einfach Videos aufnehmen.

Kamera-App entwickeln

Einige Entwickler benötigen möglicherweise eine Kamera-Benutzeroberfläche, die dem Erscheinungsbild ihrer App angepasst ist oder spezielle Funktionen bietet. Wenn Sie Ihren eigenen Code zum Aufnehmen von Bildern schreiben, können Sie die Nutzerfreundlichkeit verbessern.

Hinweis: Dieser Leitfaden bezieht sich auf die ältere, eingestellte 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 darauf zugreifen: Hiermit können Sie Code erstellen, um nach Kameras zu suchen und Zugriff anzufordern.
  • Vorschauklasse erstellen: Erstellen Sie eine Kameravorschauklasse, die SurfaceView erweitert und die SurfaceHolder-Schnittstelle implementiert. In dieser Klasse werden die Livebilder der Kamera in der Vorschau angezeigt.
  • 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 die Aufnahme einrichten: Sie können Listener für die Steuerelemente Ihrer Benutzeroberfläche verbinden, um die Bild- oder Videoaufnahme als Reaktion auf Nutzeraktionen zu starten, z. B. das Drücken einer Schaltfläche.
  • Dateien aufnehmen und speichern: Hier können Sie den Code für die Aufnahme von Bildern oder Videos und das Speichern der Ausgabe einrichten.
  • Kamera freigeben: Nach der Verwendung der Kamera muss Ihre Anwendung sie für die Verwendung durch andere Anwendungen freigeben.

Die Kamerahardware ist eine freigegebene Ressource, die sorgfältig verwaltet werden muss, damit Ihre App nicht mit anderen Apps in Konflikt gerät, die sie möglicherweise auch verwenden möchten. In den folgenden Abschnitten erfahren Sie, wie Sie Kamerahardware erkennen, Zugriff auf eine Kamera anfordern, Bilder oder Videos aufnehmen und die Kamera wieder freigeben, wenn Ihre Anwendung sie nicht mehr benötigt.

Achtung:Denken Sie daran, das Camera-Objekt freizugeben, indem Sie Camera.release() aufrufen, wenn Ihre Anwendung es nicht mehr verwendet. Wenn Ihre App die Kamera nicht richtig freigibt, schlagen alle nachfolgenden Zugriffsversuche auf die Kamera fehl, einschließlich derjenigen durch Ihre eigene App. Dies kann dazu führen, dass Ihre oder andere Apps geschlossen werden.

Kamerahardware erkennen

Wenn für Ihre Anwendung keine Kamera mit einer Manifestdeklaration erforderlich ist, sollten Sie prüfen, ob eine Kamera zur Laufzeit verfügbar ist. Verwenden Sie dazu die Methode PackageManager.hasSystemFeature(), wie im Beispielcode unten 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 Fotos und eine Frontkamera für Videoanrufe. Ab Android 2.3 (API-Level 9) können Sie mit der Methode Camera.getNumberOfCameras() die Anzahl der auf einem Gerät verfügbaren Kameras 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 anfordern, indem Sie eine Instanz von Camera abrufen (es sei denn, Sie verwenden eine Intent-Aktion für den Zugriff auf die Kamera).

Verwenden Sie die Methode Camera.open(), um auf die Hauptkamera zuzugreifen, und fangen Sie alle Ausnahmen ab, 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:Prüfen Sie bei der Verwendung von Camera.open() immer, ob Ausnahmen vorliegen. Wenn Sie nicht nach Ausnahmen prüfen, ob die Kamera in Gebrauch ist oder nicht vorhanden ist, wird Ihre Anwendung vom System heruntergefahren.

Auf Geräten mit Android 2.3 (API-Level 9) oder höher können Sie über Camera.open(int) auf bestimmte Kameras zugreifen. Der Beispielcode oben greift auf die erste Rückkamera eines Geräts mit mehreren Kameras zu.

Kamerafunktionen prüfen

Sobald Sie Zugriff auf eine Kamera erhalten haben, können Sie mithilfe der Methode Camera.getParameters() weitere Informationen zu den Funktionen erhalten. Prüfen Sie dazu, ob die unterstützten Funktionen im zurückgegebenen Camera.Parameters-Objekt enthalten sind. Wenn Sie API-Ebene 9 oder höher verwenden, können Sie mit Camera.getCameraInfo() ermitteln, ob sich eine Kamera auf der Vorder- oder Rückseite des Geräts befindet, und die Ausrichtung des Bildes.

Vorschauklasse erstellen

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

Im folgenden Beispielcode wird gezeigt, wie Sie eine einfache Kameravorschauklasse erstellen, die in ein View-Layout eingefügt werden kann. Diese Klasse implementiert SurfaceHolder.Callback, um die Rückrufereignisse zum Erstellen und Löschen der Ansicht zu erfassen, die für die Zuweisung der Kameravorschaueingabe erforderlich sind.

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, können Sie dies in der surfaceChanged()-Methode tun, wie in den Kommentaren oben beschrieben. Beim Festlegen der Vorschaugröße müssen Werte aus getSupportedPreviewSizes() verwendet werden. Legen Sie keine beliebigen Werte in der setPreviewSize()-Methode fest.

Hinweis:Mit der Einführung der Funktion Mehrfenstermodus in Android 7.0 (API-Level 24) und höher können Sie nicht mehr davon ausgehen, dass das Seitenverhältnis der Vorschau mit dem Ihrer Aktivität übereinstimmt, auch nicht nach dem Aufruf von setDisplayOrientation(). Je nach Fenstergröße und Seitenverhältnis musst du möglicherweise eine breite Kameravorschau in ein Hochformat-Layout oder umgekehrt ein Letterbox-Layout einpassen.

Vorschau in ein Layout einfügen

Eine Kameravorschauklasse wie im vorherigen Abschnitt gezeigt muss zusammen mit anderen Steuerelementen der Benutzeroberfläche zum Aufnehmen von Fotos oder Videos in das Layout einer Aktivität eingefügt werden. In diesem Abschnitt erfahren Sie, wie Sie ein einfaches Layout und eine einfache Aktivität für die Vorschau erstellen.

Der folgende Layoutcode bietet eine sehr einfache Ansicht, mit der eine Kameravorschau angezeigt werden kann. In diesem Beispiel ist das FrameLayout-Element der Container für die Kameravorschauklasse. Bei diesem Layouttyp können zusätzliche Bildinformationen oder Steuerelemente auf die Live-Kameravorschaubilder gelegt werden.

<?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 Querformat. In diesem Beispiellayout wird ein horizontales (Querformat) festgelegt. Der Code unten fixiert die Ausrichtung der Anwendung auf Querformat. Um das Rendern einer Kameravorschau zu vereinfachen, sollten Sie die Ausrichtung der Vorschauaktivität Ihrer Anwendung in Ihrem Manifest in „Querformat“ ändern. Fügen Sie dazu 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:Die Kameravorschau muss nicht im Querformat sein. Ab Android 2.2 (API-Ebene 8) können Sie mit der Methode setDisplayOrientation() die Drehung des Vorschaubilds festlegen. Wenn die Vorschauausrichtung geändert werden soll, wenn der Nutzer das Smartphone neu ausrichtet, beenden Sie in der surfaceChanged()-Methode Ihrer Vorschauklasse zuerst die Vorschau mit Camera.stopPreview(), ändern Sie die Ausrichtung und starten Sie die Vorschau dann wieder mit Camera.startPreview().

Fügen Sie in der Aktivität für Ihre Kameraansicht dem FrameLayout-Element im Beispiel oben Ihre Vorschauklasse hinzu. Ihre Kameraaktivität muss außerdem dafür sorgen, dass die Kamera freigegeben wird, wenn sie pausiert oder ausgeschaltet wird. Im folgenden Beispiel wird gezeigt, wie Sie eine Kameraaktivität ändern, um die Vorschauklasse anzuhängen, die im Abschnitt Vorschauklasse erstellen beschrieben wurde.

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 erstellt haben, in dem sie angezeigt werden soll, können Sie mit der Aufnahme von Bildern mit Ihrer Anwendung beginnen. In Ihrem Anwendungscode müssen Sie Listener für die Steuerelemente Ihrer Benutzeroberfläche einrichten, damit auf eine Nutzeraktion reagiert und ein Foto aufgenommen wird.

Verwenden Sie die Methode Camera.takePicture(), um ein Bild abzurufen. Diese Methode nimmt drei Parameter entgegen, die Daten von der Kamera empfangen. Wenn Sie Daten im JPEG-Format empfangen möchten, 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-Oberfläche zum Speichern eines von der Kamera empfangenen Bildes.

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

Starten Sie die Aufnahme eines Bilds durch Aufrufen der Methode Camera.takePicture(). Im folgenden Beispielcode wird gezeigt, wie diese Methode über eine 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:Das Mitglied mPicture im folgenden Beispiel bezieht sich auf den Beispielcode oben.

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

Videos aufnehmen

Die Videoaufnahme mit dem Android-Framework erfordert eine sorgfältige Verwaltung des Camera-Objekts und eine Abstimmung mit der MediaRecorder-Klasse. Wenn Sie mit Camera ein Video aufnehmen, müssen Sie die Camera.lock()- und Camera.unlock()-Aufrufe verwalten, um MediaRecorder zusätzlich zu den Camera.open()- und Camera.release()-Aufrufen 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 Sie verwaltet.

Im Gegensatz zum Aufnehmen von Fotos mit der Kamera eines Geräts erfordert die Videoaufnahme eine ganz bestimmte Aufrufabfolge. Sie müssen eine bestimmte Reihenfolge einhalten, um die Aufnahme mit Ihrer Anwendung vorzubereiten und durchzuführen. Weitere Informationen finden Sie unten.

  1. Kamera öffnen: Mit Camera.open() können Sie eine Instanz des Kameraobjekts abrufen.
  2. Connect Preview (Vorschau verbinden): Sie können eine Live-Kamerabildvorschau erstellen, indem Sie einen SurfaceView über Camera.setPreviewDisplay() mit der Kamera verbinden.
  3. Vorschau starten: Mit Camera.startPreview() können Sie die Live-Kamerabilder anzeigen lassen.
  4. Videoaufnahme starten: Die folgenden Schritte müssen in der richtigen Reihenfolge ausgeführt werden, damit ein Video aufgenommen werden kann:
    1. Kamera entsperren: Sie können die Kamera für die Nutzung durch MediaRecorder entsperren, indem Sie Camera.unlock() aufrufen.
    2. MediaRecorder konfigurieren: Rufen Sie die folgenden MediaRecorder-Methoden in dieser Reihenfolge auf. Weitere Informationen finden Sie in der MediaRecorder-Referenzdokumentation.
      1. setCamera(): Legen Sie die Kamera fest, die für die Videoaufnahme verwendet werden soll. Verwenden Sie dazu die aktuelle Instanz von Camera in Ihrer Anwendung.
      2. setAudioSource() – Audioquelle festlegen, MediaRecorder.AudioSource.CAMCORDER verwenden
      3. setVideoSource(): Videoquelle festlegen, MediaRecorder.VideoSource.CAMERA verwenden.
      4. Legen Sie das Videoausgabeformat und die Codierung 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 Sie das Videoausgabeformat und die Codierungsparameter festlegen:
        1. setOutputFormat(): Legen Sie das Ausgabeformat fest. Geben Sie die Standardeinstellung oder MediaRecorder.OutputFormat.MPEG_4 an.
        2. setAudioEncoder() – Legen Sie den Toncodierungstyp fest. Geben Sie die Standardeinstellung oder MediaRecorder.AudioEncoder.AMR_NB an.
        3. setVideoEncoder(): Legen Sie den Videocodierungstyp fest. Geben Sie die Standardeinstellung oder MediaRecorder.VideoEncoder.MPEG_4_SP an.
      5. setOutputFile(): Legen Sie die Ausgabedatei fest. Verwenden Sie getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() aus der Beispielmethode im Abschnitt Mediendateien speichern.
      6. setPreviewDisplay() – Geben Sie das Vorschaulayout-Element SurfaceView für Ihre Anwendung an. Verwenden Sie dasselbe Objekt, das Sie für Connect-Vorabversion 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. MediaRecorder vorbereiten: Durch Aufrufen von MediaRecorder.prepare() wird die MediaRecorder mit den angegebenen Konfigurationseinstellungen vorbereitet.
    4. MediaRecorder starten: Durch Aufrufen von MediaRecorder.start() wird die Videoaufzeichnung gestartet.
  5. Videoaufzeichnung beenden: Rufen Sie die folgenden Methoden in der richtigen Reihenfolge auf, um eine Videoaufzeichnung abzuschließen:
    1. MediaRecorder beenden: Durch Aufrufen von MediaRecorder.stop() wird die Videoaufzeichnung beendet.
    2. MediaRecorder zurücksetzen: Optional können Sie die Konfigurationseinstellungen aus dem Rekorder entfernen, indem Sie MediaRecorder.reset() aufrufen.
    3. MediaRecorder freigeben: Mit MediaRecorder.release() wird die MediaRecorder freigegeben.
    4. Kamera sperren: Sie können die Kamera sperren, damit sie für zukünftige MediaRecorder-Sitzungen verwendet werden kann. Rufen Sie dazu Camera.lock() auf. Ab Android 4.0 (API-Ebene 14) ist dieser Aufruf nur dann erforderlich, wenn der MediaRecorder.prepare()-Aufruf fehlschlägt.
  6. Vorschau beenden: Wenn Sie die Kamera nicht mehr verwenden, können Sie die Vorschau mit Camera.stopPreview() beenden.
  7. Kamera freigeben: Durch Aufrufen von Camera.release() wird die Kamera freigegeben, damit andere Anwendungen sie verwenden können.

Hinweis:Sie können MediaRecorder verwenden, ohne zuerst eine Kameravorschau zu erstellen, und die ersten Schritte dieses Vorgangs überspringen. Da Nutzer jedoch in der Regel eine Vorschau sehen möchten, bevor sie mit der Aufnahme beginnen, wird dieser Vorgang hier nicht beschrieben.

Tipp:Wenn Sie Ihre App normalerweise zum Aufzeichnen von Videos verwenden, setzen Sie setRecordingHint(boolean) auf true, bevor Sie die Vorschau starten. Mit dieser Einstellung lässt sich die Zeit verkürzen, die für den Start der Aufzeichnung benötigt wird.

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. Im folgenden Beispielcode wird gezeigt, wie die Klasse MediaRecorder richtig für die Videoaufzeichnung 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;
}

Unter Android 2.2 (API-Level 8) müssen Sie die Parameter für 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 Videoaufzeichnungsparameter für MediaRecorder sind Standardeinstellungen. Sie können diese Einstellungen jedoch für Ihre Anwendung anpassen:

MediaRecorder starten und beenden

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

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

Im folgenden Beispielcode wird gezeigt, wie Sie eine Schaltfläche verkabeln, 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 beenden, da sonst die Vorschau angehalten wird.

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. Bei dieser Methode wird die Kamera gesperrt und die MediaRecorder-Instanz konfiguriert und vorbereitet.

Kamera lösen

Kameras sind eine Ressource, die von Anwendungen auf einem Gerät gemeinsam genutzt wird. Ihre Anwendung kann die Kamera verwenden, nachdem eine Instanz von Camera abgerufen wurde. Sie müssen das Kameraobjekt jedoch unbedingt freigeben, wenn Ihre Anwendung es nicht mehr verwendet und sobald Ihre Anwendung pausiert wird (Activity.onPause()). Wenn Ihre Anwendung die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Zugriffsversuche auf die Kamera fehl, einschließlich derjenigen Ihrer eigenen Anwendung. Dies kann dazu führen, dass Ihre oder andere Anwendungen heruntergefahren werden.

Verwenden Sie die Methode Camera.release(), um eine Instanz des Camera-Objekts freizugeben, wie im Beispielcode unten 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 App die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Zugriffsversuche auf die Kamera fehl, einschließlich derjenigen durch Ihre eigene App. Dies kann dazu führen, dass Ihre oder andere Apps geschlossen werden.

Mediendateien speichern

Von Nutzern erstellte Mediendateien wie 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 auch ohne ihr Gerät zu ermöglichen. Es gibt viele mögliche Verzeichnisspeicherorte, um Mediendateien auf einem Gerät zu speichern. Als Entwickler sollten Sie jedoch nur zwei Standardspeicherorte in Betracht ziehen:

  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES): Mit dieser Methode wird der standardmäßige, freigegebene und empfohlene Speicherort für Bilder und Videos zurückgegeben. Dieses Verzeichnis ist freigegeben (öffentlich), sodass andere Anwendungen dort gespeicherte Dateien leicht finden, lesen, ändern und löschen können. Wenn die App vom Nutzer deinstalliert wird, werden die an diesem Speicherort gespeicherten Mediendateien nicht entfernt. Damit vorhandene Bilder und Videos der Nutzer 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-Ebene 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 das Speichern von Bildern und Videos zurück, die mit Ihrer Anwendung verknüpft sind. Wenn Ihre Anwendung deinstalliert wird, werden alle an diesem Speicherort gespeicherten Dateien entfernt. Für Dateien an diesem Speicherort wird keine Sicherheit erzwungen und andere Anwendungen können sie lesen, ändern und löschen.

Im folgenden Beispielcode wird gezeigt, wie Sie einen File- oder Uri-Speicherort für eine Mediendatei erstellen, die beim Aufrufen der Kamera eines Geräts mit einer Intent oder als Teil 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 Sie Ihre Anzeigen auf Geräte mit älteren Android-Versionen ausrichten möchten, verwenden Sie stattdessen Environment.getExternalStorageDirectory(). Weitere Informationen finden Sie unter Freigegebene Dateien speichern.

Damit der URI Arbeitsprofile unterstützt, müssen Sie zuerst den Datei-URI in einen Inhalts-URI konvertieren. Füge dann den Inhalts-URI zu EXTRA_OUTPUT eines Intent hinzu.

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 die Kameraanwendung steuern können, z. B. Bildformat, Blitzmodus und Fokuseinstellungen. In diesem Abschnitt werden die gängigen Kamerafunktionen aufgeführt und kurz erläutert. Auf die meisten Kamerafunktionen kann über das Camera.Parameters-Objekt zugegriffen und sie können dort festgelegt werden. Es gibt jedoch einige wichtige Funktionen, für die mehr als nur 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. Ausführlichere Informationen zur Verwendung von Funktionen, die über das Objekt „camera_parameters“ gesteuert werden, finden Sie in der API-Referenzdokumentation. Folgen Sie dazu den Links in der folgenden Funktionsliste.

Tabelle 1 Gängige Kamerafunktionen, sortiert nach der Android-API-Ebene, in der sie eingeführt wurden.

Funktion API-Ebene Beschreibung
Gesichtserkennung 14 Gesichter in einem Bild erkennen und für Fokus, Belichtung und Weißabgleich verwenden
Messbereiche 14 Geben Sie einen oder mehrere Bereiche in einem Bild für die Berechnung des Weißabgleichs an.
Schwerpunkte 14 Festlegen eines oder mehrerer Bereiche in einem Bild, die scharf gestellt werden sollen
White Balance Lock 14 Automatische Weißabgleichseinstellungen beenden oder starten
Exposure Lock 14 Automatische Belichtungsanpassungen beenden oder starten
Video Snapshot 14 Foto während der Videoaufnahme aufnehmen (Frame-Grabbing)
Zeitraffervideo 11 Frames mit festgelegten Verzögerungen aufnehmen, um ein Zeitraffervideo zu erstellen
Multiple Cameras 9 Unterstützung für mehrere Kameras auf einem Gerät, einschließlich Front- und Rückkameras
Focus Distance 9 Gibt die Entfernungen zwischen der Kamera und Objekten an, die scheinbar im Fokus sind
Zoom 8 Bildvergrößerung festlegen
Exposure Compensation 8 Belichtungsstufe erhöhen oder verringern
GPS Data 5 Geografische Standortdaten in das Bild ein- oder ausschließen
White Balance 5 Weißabgleichsmodus festlegen, der sich auf die Farbwerte im aufgenommenen Bild auswirkt
Focus Mode 5 Legen Sie fest, wie die Kamera ein Motiv scharfstellt, z. B. automatisch, fix, Makro oder Unendlich.
Scene Mode 5 Einen voreingestellten Modus für bestimmte Arten von Aufnahmesituationen wie Nacht, Strand, Schnee oder Kerzenlicht anwenden
JPEG Quality 5 Legen Sie die Komprimierungsstufe für ein JPEG-Bild fest, um die Qualität und Größe der Bildausgabedatei zu erhöhen oder zu verringern.
Flash Mode 5 Blitz aktivieren, deaktivieren oder automatische Einstellung verwenden
Color Effects 5 Sie können dem aufgenommenen Bild einen Farbeffekt wie Schwarz-Weiß, Sepia oder Negativ hinzufügen.
Anti-Banding 5 Reduziert die Auswirkungen von Streifen bei Farbverläufen aufgrund der JPEG-Komprimierung
Picture Format 1 Dateiformat für das Bild angeben
Picture Size 1 Pixelabmessungen des gespeicherten Bildes angeben

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 prüfen

Wenn Sie die Kamerafunktionen auf Android-Geräten verwenden möchten, sollten Sie wissen, dass nicht alle Kamerafunktionen auf allen Geräten unterstützt werden. Außerdem unterstützen Geräte, die eine bestimmte Funktion unterstützen, diese möglicherweise in unterschiedlichem Maße oder mit unterschiedlichen Optionen. Daher müssen Sie bei der Entwicklung einer Kameraanwendung entscheiden, welche Kamerafunktionen Sie unterstützen und in welchem Umfang. Nachdem Sie diese Entscheidung getroffen haben, sollten Sie in Ihrer Kameraanwendung Code einfügen, der prüft, ob die Gerätehardware diese Funktionen unterstützt, und fehlerfrei abläuft, wenn eine Funktion nicht verfügbar ist.

Sie können die Verfügbarkeit von Kamerafunktionen prüfen, indem Sie eine Instanz des Parametersobjekts einer Kamera abrufen und die entsprechenden Methoden prüfen. Im folgenden Codebeispiel wird gezeigt, wie Sie ein Camera.Parameters-Objekt abrufen und prüfen, ob die Kamera den Autofokus 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 Methode für die meisten Kamerafunktionen verwenden. Das Camera.Parameters-Objekt bietet die Methoden getSupported...(), is...Supported() oder getMax...(), um zu ermitteln, ob (und in welchem Umfang) eine Funktion unterstützt wird.

Wenn Ihre App bestimmte Kamerafunktionen für die ordnungsgemäße Funktion benötigt, können Sie sie durch Ergänzungen in Ihrem App-Manifest anfordern. Wenn Sie die Verwendung bestimmter Kamerafunktionen wie Blitz und Autofokus angeben, verhindert Google Play, dass Ihre App auf Geräten installiert wird, die diese Funktionen nicht unterstützen. Eine Liste der Kamerafunktionen, die in Ihrem App-Manifest deklariert werden können, finden Sie in der Referenz zu Manifest-Funktionen.

Kamerafunktionen verwenden

Die meisten Kamerafunktionen werden mit einem Camera.Parameters-Objekt aktiviert und gesteuert. Sie rufen dieses Objekt auf, indem Sie zuerst eine Instanz des Camera-Objekts abrufen, die Methode getParameters() aufrufen, das zurückgegebene Parameterobjekt ändern und es dann wieder in das Kameraobjekt einfügen, 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 Methode 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 den Parametern sind für den Nutzer in der Regel sofort in der Kameravorschau der Anwendung sichtbar. Softwareseitig kann es einige Frames dauern, bis Parameteränderungen wirksam werden, da die Kamerahardware die neuen Anweisungen verarbeitet und dann aktualisierte Bilddaten sendet.

Wichtig:Einige Kamerafunktionen können nicht beliebig geändert werden. Insbesondere müssen Sie die Vorschau zuerst beenden, die Vorschaugröße ändern und dann die Vorschau wieder starten, um die Größe oder Ausrichtung der Kameravorschau zu ändern. Ab Android 4.0 (API-Level 14) kann die Ausrichtung der Vorschau geändert werden, ohne dass die Vorschau neu gestartet werden muss.

Für andere Kamerafunktionen ist mehr Code erforderlich, z. B. für:

  • Belichtungs- und Fokusbereiche
  • Gesichtserkennung
  • Zeitraffervideo

In den folgenden Abschnitten erhalten Sie eine kurze Übersicht dazu, wie Sie diese Funktionen implementieren.

Mess- und Fokusbereiche

In einigen fotografischen Situationen erzielen Sie mit der automatischen Fokussierung und Belichtungsmessung möglicherweise nicht die gewünschten Ergebnisse. Ab Android 4.0 (API-Ebene 14) kann Ihre Kamera-App zusätzliche Steuerelemente bereitstellen, mit denen Ihre App oder Nutzer Bereiche in einem Bild angeben können, die für die Bestimmung der Fokus- oder Belichtungseinstellungen verwendet werden sollen. Diese Werte werden dann an die Kamerahardware übergeben, um Bilder oder Videos aufzunehmen.

Bereiche für die Belichtungsmessung und den Fokus funktionieren sehr ähnlich wie andere Kamerafunktionen, da sie über Methoden im Camera.Parameters-Objekt gesteuert werden. Im folgenden Code wird gezeigt, wie zwei Belichtungsmessungsbereiche für eine Instanz von Camera festgelegt werden:

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 Angeben eines Bereichs im Sichtfeld der Kamera und einen Gewichtswert, der der Kamera mitteilt, welche Bedeutung dieser Bereich bei der Belichtungsmessung oder Fokusberechnung haben soll.

Das Feld Rect in einem Camera.Area-Objekt beschreibt eine rechteckige Form, die auf ein Raster von 2.000 × 2.000 Einheiten prognostiziert wird. Die Koordinaten -1.000, -1.000 stehen für die linke obere Ecke des Kamerabilds und die Koordinaten 1.000, 1.000 für die rechte untere Ecke des Kamerabilds, wie in der Abbildung unten dargestellt.

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

Die Grenzen dieses Koordinatensystems entsprechen immer dem äußeren Rand des Bildes, das in der Kameravorschau zu sehen ist, und schrumpfen oder erweitern sich nicht mit dem Zoomfaktor. Ebenso wird das Koordinatensystem nicht neu zugeordnet, wenn Sie die Bildvorschau mit Camera.setDisplayOrientation() drehen.

Gesichtserkennung

Bei Fotos mit Personen sind Gesichter in der Regel der wichtigste Teil des Bildes. Sie sollten beim Aufnehmen eines Fotos sowohl für den Fokus als auch für den Weißabgleich verwendet werden. Das Android 4.0-Framework (API-Ebene 14) bietet APIs zur Identifizierung von Gesichtern und zum Berechnen von Bildeinstellungen mithilfe der Gesichtserkennungstechnologie.

Hinweis:Wenn die Gesichtswiedererkennung aktiv ist, haben setWhiteBalance(String), setFocusAreas(List<Camera.Area>) und setMeteringAreas(List<Camera.Area>) keine Auswirkungen.

Für die Verwendung der Gesichtserkennungsfunktion in Ihrer Kameraanwendung sind einige allgemeine Schritte erforderlich:

  • Prüfen, ob die Gesichtserkennung auf dem Gerät unterstützt wird
  • Listener für die Gesichtserkennung erstellen
  • Dem Kameraobjekt den Listener für die Gesichtserkennung hinzufügen
  • Gesichtserkennung nach der Vorabversion starten (und nach jedem Neustart der Vorabversion)

Die Funktion zur Gesichtserkennung wird nicht auf allen Geräten unterstützt. Ob diese Funktion unterstützt wird, können Sie durch Aufrufen von getMaxNumDetectedFaces() prüfen. Ein Beispiel für diese Prüfung ist in der Beispielmethode für startFaceDetection() unten zu sehen.

Damit Sie benachrichtigt werden und auf die Erkennung eines Gesichts reagieren können, muss Ihre Kameraanwendung einen Listener für Ereignisse der Gesichtserkennung 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, legen Sie sie im Camera-Objekt Ihrer Anwendung fest, wie im folgenden Beispielcode gezeigt:

Kotlin

camera?.setFaceDetectionListener(MyFaceDetectionListener())

Java

camera.setFaceDetectionListener(new MyFaceDetectionListener());

Die Funktion zur Gesichtserkennung muss in Ihrer Anwendung jedes Mal gestartet werden, 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 Vorschauklasse verwenden, die unter Vorschauklasse erstellen gezeigt wird, 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:Diese Methode muss nach dem Aufruf von startPreview() aufgerufen werden. Versuchen Sie nicht, die Gesichtserkennung in der onCreate()-Methode der Hauptaktivität Ihrer Kamera-App zu starten, da die Vorschau zu diesem Zeitpunkt in der Ausführung Ihrer Anwendung nicht verfügbar ist.

Zeitraffervideo

Mit Zeitraffervideos können Nutzer Videoclips erstellen, in denen Bilder kombiniert werden, die wenige Sekunden oder Minuten auseinander liegen. Bei dieser Funktion werden die Bilder für eine Zeitraffersequenz mit MediaRecorder aufgenommen.

Wenn Sie mit MediaRecorder ein Zeitraffervideo aufnehmen möchten, müssen Sie das Rekorderobjekt so konfigurieren, als würden Sie ein normales Video aufnehmen. Legen Sie dazu eine niedrige Anzahl von Frames pro Sekunde fest und verwenden Sie eine der Qualitätseinstellungen für Zeitraffer, wie im Codebeispiel unten 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 größeren Konfigurationsvorgangs für MediaRecorder vorgenommen werden. Ein vollständiges Beispiel für den Konfigurationscode findest du unter MediaRecorder konfigurieren. Sobald die Konfiguration abgeschlossen ist, starten Sie die Videoaufzeichnung wie bei einem normalen Videoclip. Weitere Informationen zum Konfigurieren und Ausführen von MediaRecorder finden Sie unter Videos aufnehmen.

Die Beispiele Camera2Video und HdrViewfinder veranschaulichen die Verwendung der auf dieser Seite beschriebenen APIs.

Kamerafelder, für die eine Berechtigung erforderlich ist

Apps, die Android 10 (API-Level 29) oder höher ausführen, benötigen die Berechtigung CAMERA, um auf die Werte der folgenden Felder zuzugreifen, die die Methode getCameraCharacteristics() zurückgibt:

  • 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 finden Sie unter Camera2Basic-Beispiel und Offizielle CameraX-Beispiel-App.