Camera API

Das Android-Framework unterstützt verschiedene Kameras und Kamerafunktionen, die auf Geräten verfügbar sind. So können Sie in Ihren Anwendungen Bilder und Videos aufnehmen. 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 Nutzer erläutert.

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

Hinweise

Bevor Sie Ihrer Anwendung die Verwendung von Kameras auf Android-Geräten ermöglichen, sollten Sie sich einige Fragen dazu stellen, wie Ihre App diese Hardwarefunktion verwenden soll.

  • Kameraanforderung: Ist die Verwendung einer Kamera für deine App so wichtig, dass du nicht möchtest, dass sie auf einem Gerät ohne Kamera installiert wird? In diesem Fall solltest du die Kameraanforderung in deinem Manifest deklarieren.
  • Schnappschuss oder benutzerdefinierte Kamera – Wie wird die Kamera in Ihrer Anwendung verwendet? Möchten Sie nur ein schnelles Foto oder einen Videoclip aufnehmen oder bietet Ihre Anwendung eine neue Möglichkeit, Kameras zu verwenden? Wenn Sie nur einen schnellen Schnappschuss oder Clip machen möchten, können Sie vorhandene Kamera-Apps verwenden. Informationen zum Entwickeln einer benutzerdefinierten Kamerafunktion findest du im Abschnitt Kamera-App erstellen.
  • Anforderung an Dienste im Vordergrund: Wann interagiert Ihre 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 verwenden, wenn deine App im Vordergrund ist, oder als Teil eines Dienstes im Vordergrund.
  • Speicher: Sollen die von Ihrer Anwendung generierten Bilder oder Videos nur für Ihre Anwendung sichtbar sein oder sollen sie freigegeben werden, damit andere Anwendungen wie die Galerie oder andere Medien- und Social-Media-Apps sie verwenden können? Sollen die Bilder und Videos auch dann verfügbar sein, wenn deine 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 Klassen:

android.hardware.camera2
Dieses Paket ist die primäre API zur Steuerung von Gerätekameras. Sie kann zum Aufnehmen von Bildern oder Videos verwendet werden, wenn Sie eine Kamera-App erstellen.
Camera
Diese Klasse ist die ältere, verworfene API zur Steuerung von Gerätekameras.
SurfaceView
Diese Klasse wird verwendet, um dem Nutzer eine Live-Kameravorschau zu präsentieren.
MediaRecorder
Diese Klasse wird verwendet, um Videos mit der Kamera aufzunehmen.
Intent
Mit dem Intent-Aktionstyp MediaStore.ACTION_IMAGE_CAPTURE oder MediaStore.ACTION_VIDEO_CAPTURE können Bilder oder Videos aufgenommen werden, ohne das Camera-Objekt direkt zu verwenden.

Manifestdeklarationen

Bevor du mit der Entwicklung deiner Anwendung mit der Camera API beginnst, solltest du prüfen, ob dein Manifest die entsprechenden Deklarationen enthält, um die Verwendung von Kamerahardware und anderen zugehörigen Funktionen zu ermöglichen.

  • Berechtigung zum Zugriff auf die Kamera: Deine Anwendung muss die Berechtigung zur Verwendung der Kamera eines Geräts anfordern.
    <uses-permission android:name="android.permission.CAMERA" />

    Hinweis:Wenn du die Kamera über eine vorhandene Kamera-App verwendest, muss deine Anwendung diese Berechtigung nicht anfordern.

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

    Eine Liste der Kamerafunktionen findest du in der Referenz zu Manifestfunktionen.

    Wenn du deinem Manifest Kamerafunktionen hinzufügst, verhindert Google Play, dass deine App auf Geräten installiert wird, die keine Kamera haben oder die von dir angegebenen Kamerafunktionen nicht unterstützen. Weitere Informationen zur Verwendung der funktionsbasierten Filterung mit Google Play finden Sie unter Google Play und funktionsbasierte Filterung.

    Wenn deine App eine Kamera oder Kamerafunktion für den ordnungsgemäßen Betrieb verwenden kann, aber nicht erfordert, solltest du dies im Manifest angeben, indem du das Attribut android:required einfügst und auf false setzt:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
  • Speicherberechtigung: Deine 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 angegeben ist.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • Berechtigung für Audioaufnahmen: Wenn Sie Audio mit Videoaufnahmen aufnehmen möchten, muss Ihre Anwendung die Berechtigung für Audioaufnahmen anfordern.
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • Berechtigung zur Standortermittlung: Wenn Ihre Anwendung Bilder mit GPS-Standortinformationen taggt, 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 auch angeben, 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, das Aufnehmen von Bildern oder Videos in Ihrer Anwendung ohne viel zusätzlichen Code zu ermöglichen, ist die Verwendung eines Intent, um eine vorhandene Android-Kameraanwendung aufzurufen. Details dazu findest du in den Schulungslektionen Einfach Fotos aufnehmen und Einfach Videos aufnehmen.

Kamera-App erstellen

Einige Entwickler benötigen möglicherweise eine Kamera-Benutzeroberfläche, die an das Design ihrer Anwendung angepasst ist oder spezielle Funktionen bietet. Wenn Sie Ihren eigenen Code für die Aufnahme von Bildern schreiben, können Sie Ihren Nutzern eine ansprechendere Erfahrung bieten.

Hinweis: Der folgende Leitfaden 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 darauf zugreifen: Erstelle Code, um zu prüfen, ob Kameras vorhanden sind, und um Zugriff anzufordern.
  • Vorschauklasse erstellen: Erstelle eine Kameravorschauklasse, die SurfaceView erweitert und die SurfaceHolder-Schnittstelle implementiert. Diese Klasse zeigt eine Vorschau der Livebilder der Kamera an.
  • Vorschaulayout erstellen: Sobald du die Kameravorschauklasse hast, erstelle ein Ansichtslayout, das die Vorschau und die gewünschten Steuerelemente der Benutzeroberfläche enthält.
  • Listener für die Aufnahme einrichten: Verbinden Sie Listener für Ihre Oberflächensteuerelemente, um die Bild- oder Videoaufnahme als Reaktion auf Nutzeraktionen wie das Drücken einer Taste zu starten.
  • Dateien aufnehmen und speichern: Richten Sie den Code zum Aufnehmen von Bildern oder Videos und zum Speichern der Ausgabe ein.
  • Kamera freigeben: Nach der Verwendung der Kamera muss deine Anwendung sie ordnungsgemäß für die Verwendung durch andere Anwendungen freigeben.

Die Kamerahardware ist eine gemeinsam genutzte Ressource, die sorgfältig verwaltet werden muss, damit es nicht zu Konflikten zwischen Ihrer Anwendung und anderen Anwendungen kommt, die sie möglicherweise ebenfalls verwenden möchten. In den folgenden Abschnitten wird erläutert, wie du Kamerahardware erkennst, Zugriff auf eine Kamera anforderst, Bilder oder Videos aufnimmst und die Kamera freigibst, wenn deine Anwendung sie nicht mehr verwendet.

Achtung: Denken Sie daran, das Camera-Objekt durch Aufrufen von Camera.release() freizugeben, wenn Ihre Anwendung es nicht mehr benötigt. Wenn deine App die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Versuche, auf die Kamera zuzugreifen, fehl, einschließlich der Versuche deiner eigenen App. Dies kann dazu führen, dass deine oder andere Apps beendet werden.

Kamerahardware wird erkannt

Wenn für deine App nicht ausdrücklich eine Kamera über eine Manifestdeklaration erforderlich ist, solltest du prüfen, ob zur Laufzeit eine Kamera verfügbar ist. Verwenden Sie für diese Prüfung 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 Fotos und eine Frontkamera für Videoanrufe. Unter Android 2.3 (API-Level 9) und höher können Sie mit der Methode Camera.getNumberOfCameras() die Anzahl der auf einem Gerät verfügbaren Kameras prüfen.

Auf Kameras zugreifen

Wenn du festgestellt hast, dass das Gerät, auf dem deine App ausgeführt wird, eine Kamera hat, musst du den Zugriff darauf anfordern, indem du eine Instanz von Camera abrufst (es sei denn, du verwendest einen Intent für den Zugriff auf die Kamera).

Verwende die Methode Camera.open(), um auf die Hauptkamera zuzugreifen, und fange alle Ausnahmen ab, wie im Code unten 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 du nicht prüfst, ob die Kamera verwendet wird oder nicht vorhanden ist, wird deine Anwendung vom System beendet.

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 obigen Beispielcode wird auf die erste Rückkamera auf einem Gerät mit mehr als einer Kamera zugegriffen.

Kamerafunktionen prüfen

Sobald du Zugriff auf eine Kamera hast, kannst du mit der Methode Camera.getParameters() weitere Informationen zu ihren Funktionen abrufen und das zurückgegebene Camera.Parameters-Objekt auf unterstützte Funktionen prüfen. 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 die Ausrichtung des Bildes bestimmen.

Vorschauklasse erstellen

Damit Nutzer effektiv Bilder 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.

Der folgende Beispielcode zeigt, wie Sie eine einfache Kameravorschauklasse erstellen, die in ein View-Layout eingefügt werden kann. Diese Klasse implementiert SurfaceHolder.Callback, um die Callback-Ereignisse für das Erstellen und Löschen der Ansicht zu erfassen, die für die Zuweisung der Eingabe für die Kameravorschau 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, legen Sie diese in der Methode surfaceChanged() fest, wie in den Kommentaren oben beschrieben. Wenn Sie die Vorschaugröße festlegen, müssen Sie Werte aus getSupportedPreviewSizes() verwenden. Legen Sie in der Methode setPreviewSize() keine beliebigen Werte fest.

Hinweis:Seit der Einführung der Mehrfensterfunktion 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, selbst wenn Sie setDisplayOrientation() aufrufen. Je nach Fenstergröße und Seitenverhältnis müssen Sie möglicherweise eine breite Kameravorschau in ein Hochformatlayout einpassen oder umgekehrt, indem Sie ein Letterbox-Layout verwenden.

Vorschau in einem Layout platzieren

Eine Kameravorschauklasse, wie im vorherigen Abschnitt gezeigt, muss zusammen mit anderen Steuerelementen der Benutzeroberfläche zum Aufnehmen eines Bildes oder Videos im Layout einer Aktivität platziert 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, die für die Anzeige einer Kameravorschau verwendet werden kann. In diesem Beispiel soll das FrameLayout-Element der Container für die Kameravorschauklasse sein. Dieser Layouttyp wird verwendet, damit zusätzliche Bildinformationen oder Steuerelemente über den Live-Vorschaubildern der Kamera eingeblendet 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. Mit dem Code unten wird die Ausrichtung der Anwendung auf das Querformat festgelegt. Damit die Kameravorschau einfacher gerendert werden kann, solltest du die Ausrichtung der Vorschauaktivität deiner Anwendung auf Querformat ändern. Füge dazu Folgendes in dein Manifest ein:

<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 angezeigt werden. Ab Android 2.2 (API-Level 8) kannst du die Methode setDisplayOrientation() verwenden, um die Drehung des Vorschaubilds festzulegen. Wenn du die Ausrichtung der Vorschau ändern möchtest, wenn der Nutzer das Smartphone neu ausrichtet, musst du in der Methode surfaceChanged() deiner Vorschauklasse zuerst die Vorschau mit Camera.stopPreview() beenden, die Ausrichtung ändern und dann die Vorschau mit Camera.startPreview() wieder starten.

Fügen Sie in der Aktivität für Ihre Kameraansicht die Vorschauklasse dem FrameLayout-Element hinzu, das im Beispiel oben gezeigt wird. Außerdem muss die Kameraaktivität dafür sorgen, dass die Kamera freigegeben wird, wenn sie pausiert oder beendet wird. Im folgenden Beispiel wird gezeigt, wie eine Kameraaktivität geändert wird, um die Vorschauklasse anzuhängen, die unter Vorschauklasse erstellen gezeigt 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, die unter Auf Kameras zugreifen gezeigt wird.

Bilder aufnehmen

Sobald du eine Vorschauklasse und ein Ansichtslayout erstellt hast, in dem sie angezeigt werden soll, kannst du mit der Aufnahme von Bildern mit deiner Anwendung beginnen. In Ihrem Anwendungscode müssen Sie Listener für die Steuerelemente der Benutzeroberfläche einrichten, damit auf eine Nutzeraktion mit der Aufnahme eines Bildes reagiert wird.

Verwenden Sie die Methode Camera.takePicture(), um ein Bild abzurufen. Diese Methode verwendet drei Parameter, 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 einfache Implementierung der Camera.PictureCallback-Schnittstelle 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());
        }
    }
};

Lösen Sie die Aufnahme eines Bildes aus, indem Sie die Methode Camera.takePicture() aufrufen. Der folgende Beispielcode zeigt, 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 obigen Beispielcode.

Achtung: Denken Sie daran, das Camera-Objekt durch Aufrufen von Camera.release() freizugeben, wenn Ihre Anwendung es nicht mehr benötigt. Informationen zum Lösen der Kamera findest du unter Kamera lösen.

Videos aufnehmen

Für die Videoaufnahme mit dem Android-Framework ist eine sorgfältige Verwaltung des Camera-Objekts und eine Abstimmung mit der MediaRecorder-Klasse erforderlich. Wenn Sie Videos mit Camera aufnehmen, müssen Sie die Aufrufe Camera.lock() und Camera.unlock() verwalten, um MediaRecorder Zugriff auf die Kamerahardware zu gewähren, zusätzlich zu den Aufrufen Camera.open() und Camera.release().

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

Im Gegensatz zum Aufnehmen von Bildern mit einer Gerätekamera ist für die Aufnahme von Videos eine ganz bestimmte Aufrufreihenfolge erforderlich. Sie müssen eine bestimmte Reihenfolge einhalten, um Videos mit Ihrer Anwendung erfolgreich vorzubereiten und aufzunehmen, wie unten beschrieben.

  1. Kamera öffnen: Verwenden Sie Camera.open(), um eine Instanz des Kameraobjekts abzurufen.
  2. Vorschau verbinden: Bereite eine Vorschau des Live-Kamerabilds vor, indem du ein SurfaceView über Camera.setPreviewDisplay() mit der Kamera verbindest.
  3. Vorschau starten: Rufe Camera.startPreview() auf, um die Live-Kamerabilder anzuzeigen.
  4. Videoaufnahme starten: Die folgenden Schritte müssen in der angegebenen Reihenfolge ausgeführt werden, um ein Video aufzunehmen:
    1. Kamera entsperren: Entsperre die Kamera für die Verwendung durch MediaRecorder, indem du Camera.unlock() aufrufst.
    2. MediaRecorder konfigurieren: Rufen Sie die folgenden MediaRecorder-Methoden in dieser Reihenfolge auf. Weitere Informationen finden Sie in der Referenzdokumentation zu MediaRecorder.
      1. setCamera(): Legen Sie die Kamera fest, die für die Videoaufnahme verwendet werden soll. Verwenden Sie die aktuelle Instanz von Camera Ihrer Anwendung.
      2. setAudioSource(): Legen Sie die Audioquelle fest, verwenden Sie MediaRecorder.AudioSource.CAMCORDER.
      3. setVideoSource(): Legen Sie die Videoquelle fest. Verwenden Sie MediaRecorder.VideoSource.CAMERA.
      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 mit CamcorderProfile.get() eine Profilinstanz 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 Typ der Audiocodierung 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 Preview angegeben haben.

      Achtung:Sie müssen diese MediaRecorder-Konfigurationsmethoden in dieser Reihenfolge aufrufen, da sonst Fehler in Ihrer Anwendung auftreten und die Aufzeichnung fehlschlägt.

    3. MediaRecorder vorbereiten: Bereiten Sie den MediaRecorder mit den angegebenen Konfigurationseinstellungen vor, indem Sie MediaRecorder.prepare() aufrufen.
    4. MediaRecorder starten: Starten Sie die Videoaufnahme durch Aufrufen von MediaRecorder.start().
  5. Videoaufzeichnung beenden: Rufen Sie die folgenden Methoden in der angegebenen Reihenfolge auf, um eine Videoaufzeichnung erfolgreich abzuschließen:
    1. MediaRecorder beenden: Beenden Sie die Videoaufnahme, indem Sie MediaRecorder.stop() aufrufen.
    2. MediaRecorder zurücksetzen: Optional können Sie die Konfigurationseinstellungen aus dem Recorder entfernen, indem Sie MediaRecorder.reset() aufrufen.
    3. MediaRecorder freigeben: Gib den MediaRecorder frei, indem du MediaRecorder.release() aufrufst.
    4. Kamera sperren: Sperren Sie die Kamera, damit sie in zukünftigen MediaRecorder-Sitzungen verwendet werden kann, indem Sie Camera.lock() aufrufen. Ab Android 4.0 (API-Level 14) ist dieser Aufruf nur erforderlich, wenn der Aufruf von MediaRecorder.prepare() fehlschlägt.
  6. Vorschau beenden: Wenn die Kamera für die Aktivität nicht mehr benötigt wird, beende die Vorschau mit Camera.stopPreview().
  7. Kamera freigeben: Gib die Kamera frei, damit andere Anwendungen sie verwenden können, indem du Camera.release() aufrufst.

Hinweis:Es ist möglich, MediaRecorder zu verwenden, ohne zuerst eine Kameravorschau zu erstellen, und die ersten Schritte dieses Prozesses zu überspringen. Da Nutzer jedoch in der Regel eine Vorschau sehen möchten, bevor sie eine Aufnahme starten, wird dieser Prozess hier nicht behandelt.

Tipp: Wenn Ihre Anwendung normalerweise zum Aufzeichnen von Videos verwendet wird, setzen Sie setRecordingHint(boolean) auf true, bevor Sie die Vorschau starten. Mit dieser Einstellung kann die Zeit bis zum Start der Aufzeichnung verkürzt werden.

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 Klasse MediaRecorder 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) 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);

Für die folgenden Videoaufzeichnungsparameter für MediaRecorder sind Standardeinstellungen festgelegt. Sie können diese Einstellungen jedoch für Ihre Anwendung anpassen:

MediaRecorder starten und beenden

Wenn du die Videoaufnahme mit der Klasse MediaRecorder startest und beendest, musst du 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. MediaRecorder mit MediaRecorder.release() freigeben
  7. Kamera mit Camera.lock() sperren

Der folgende Beispielcode zeigt, wie Sie eine Schaltfläche so einrichten, dass die Videoaufnahme mit der Kamera und der Klasse MediaRecorder ordnungsgemäß gestartet und beendet wird.

Hinweis:Lass die Kamera während der Videoaufnahme nicht los, da die Vorschau sonst beendet 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, der unter MediaRecorder konfigurieren gezeigt wird. Diese Methode sperrt die Kamera und konfiguriert und bereitet die MediaRecorder-Instanz vor.

Kamera wird freigegeben

Kameras sind eine Ressource, die von Anwendungen auf einem Gerät gemeinsam genutzt wird. Deine Anwendung kann die Kamera verwenden, nachdem sie eine Instanz von Camera abgerufen hat. Du musst besonders darauf achten, das Kameraobjekt freizugeben, wenn deine Anwendung es nicht mehr verwendet und sobald deine Anwendung pausiert wird (Activity.onPause()). Wenn deine Anwendung die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Versuche, auf die Kamera zuzugreifen, fehl, einschließlich der Versuche deiner eigenen Anwendung. Dies kann dazu führen, dass deine oder andere Anwendungen beendet werden.

Wenn Sie eine Instanz des Camera-Objekts freigeben möchten, verwenden Sie die Methode Camera.release(), 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 Versuche, auf die Kamera zuzugreifen, fehl, einschließlich der Versuche Ihrer eigenen Anwendung. Dies kann dazu führen, dass Ihre oder andere Anwendungen beendet werden.

Mediendateien werden gespeichert

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

  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES): Diese Methode gibt den standardmäßigen, freigegebenen und empfohlenen Speicherort für Bilder und Videos zurück. Dieses Verzeichnis ist freigegeben (öffentlich), sodass andere Anwendungen Dateien, die an diesem Speicherort gespeichert sind, leicht finden, lesen, ändern und löschen können. Wenn deine Anwendung vom Nutzer deinstalliert wird, werden die an diesem Speicherort gespeicherten Mediendateien nicht entfernt. Damit die vorhandenen Bilder und Videos der Nutzer nicht beeinträchtigt werden, solltest du in diesem Verzeichnis ein Unterverzeichnis für die Mediendateien deiner App erstellen, wie im folgenden Codebeispiel gezeigt. Diese Methode ist in Android 2.2 (API-Level 8) verfügbar. Informationen zu entsprechenden Aufrufen 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 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.

Der folgende Beispielcode zeigt, wie Sie einen File- oder Uri-Speicherort für eine Mediendatei erstellen, die beim Aufrufen der Kamera eines Geräts mit einem 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 in Android 2.2 (API-Level 8) oder höher verfügbar. Wenn Sie Geräte mit älteren Android-Versionen verwenden, 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ügen Sie 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 mit Ihrer Kamera-App steuern können, z. B. Bildformat, Blitzmodus, Fokuseinstellungen und vieles mehr. In diesem Abschnitt werden die gängigen Kamerafunktionen aufgeführt und kurz erläutert, wie sie verwendet werden. Auf die meisten Kamerafunktionen kann über das Objekt Camera.Parameters zugegriffen werden. Es gibt jedoch mehrere wichtige Funktionen, die mehr als nur einfache Einstellungen in Camera.Parameters erfordern. 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 mit den Kameraparametern gesteuert werden, finden Sie in der API-Referenzdokumentation. Folgen Sie dazu den Links in der Funktionsliste unten.

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

Funktion API-Ebene Beschreibung
Gesichtserkennung 14 Gesichter von Menschen in einem Bild erkennen und für Fokus, Belichtungsmessung und Weißabgleich verwenden
Messbereiche 14 Einen oder mehrere Bereiche in einem Bild für die Berechnung des Weißabgleichs angeben
Schwerpunkte 14 Einen oder mehrere Bereiche in einem Bild festlegen, die für den Fokus verwendet werden sollen
White Balance Lock 14 Automatische Anpassung des Weißabgleichs beenden oder starten
Exposure Lock 14 Automatische Belichtungsanpassung aktivieren oder deaktivieren
Video Snapshot 14 Foto während der Videoaufnahme aufnehmen (Frame Grab)
Zeitraffervideo 11 Frames mit festgelegten Verzögerungen aufnehmen, um ein Zeitraffervideo 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 Entfernungen zwischen der Kamera und Objekten an, die scharfgestellt zu sein scheinen
Zoom 8 Bildvergrößerung festlegen
Exposure Compensation 8 Belichtung erhöhen oder verringern
GPS Data 5 Geografische Standortdaten in das Bild einfügen oder weglassen
White Balance 5 Weißabgleichmodus festlegen, der sich auf die Farbwerte im aufgenommenen Bild auswirkt
Focus Mode 5 Festlegen, wie die Kamera auf ein Motiv fokussiert, z. B. automatisch, fest, Makro oder unendlich
Scene Mode 5 Voreingestellten Modus für bestimmte Arten von Fotosituationen wie Nacht-, Strand-, Schnee- oder Kerzenlichtszenen anwenden
JPEG Quality 5 Komprimierungsstufe für ein JPEG-Bild festlegen, wodurch die Qualität und Größe der Bildausgabedatei erhöht oder verringert wird
Flash Mode 5 Blitz aktivieren, deaktivieren oder automatische Einstellung verwenden
Color Effects 5 Wende einen Farbeffekt auf das aufgenommene Bild an, z. B. Schwarz-Weiß, Sepia oder Negativ.
Anti-Banding 5 Reduziert den Effekt von Streifenbildung in 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 der 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 Kamerafunktionen auf Android-Geräten verwenden möchten, sollten Sie zuerst 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 musst du bei der Entwicklung einer Kamera-App entscheiden, welche Kamerafunktionen du in welchem Umfang unterstützen möchtest. Nachdem du diese Entscheidung getroffen hast, solltest du Code in deine Kamera-App einfügen, der prüft, ob die Gerätehardware diese Funktionen unterstützt, und der ordnungsgemäß fehlschlägt, wenn eine Funktion nicht verfügbar ist.

Du kannst die Verfügbarkeit von Kamerafunktionen prüfen, indem du eine Instanz des Parameterobjekts einer Kamera abrufst und die relevanten Methoden prüfst. Im folgenden Codebeispiel wird gezeigt, 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
}

Die oben gezeigte Methode funktioniert für die meisten Kamerafunktionen. Das Objekt Camera.Parameters bietet die Methoden getSupported...(), is...Supported() oder getMax...(), um zu bestimmen, ob (und in welchem Umfang) ein Feature unterstützt wird.

Wenn Ihre Anwendung bestimmte Kamerafunktionen benötigt, um ordnungsgemäß zu funktionieren, können Sie diese durch Ergänzungen im Anwendungsmanifest anfordern. Wenn du die Verwendung bestimmter Kamerafunktionen wie Blitz und Autofokus deklarierst, 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 Referenz zu Manifestfunktionen.

Kamerafunktionen verwenden

Die meisten Kamerafunktionen werden über ein Camera.Parameters-Objekt aktiviert und gesteuert. Sie erhalten dieses Objekt, 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. Dies wird im folgenden Beispielcode veranschaulicht:

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 und die meisten Parameter können jederzeit geändert werden, nachdem Sie eine Instanz des Camera-Objekts erhalten haben. Änderungen an Parametern sind für den Nutzer in der Regel sofort in der Kameravorschau der Anwendung sichtbar. Auf der Softwareseite kann es mehrere Frames dauern, bis Parameteränderungen tatsächlich 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 wenn du die Größe oder Ausrichtung der Kameravorschau ändern möchtest, musst du zuerst die Vorschau beenden, die Vorschaugröße ändern und dann die Vorschau neu starten. 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, darunter:

  • Messung und Bereiche mit Verbesserungspotenzial
  • Gesichtserkennung
  • Zeitraffervideo

In den folgenden Abschnitten finden Sie eine kurze Übersicht über die Implementierung dieser Funktionen.

Messung und Bereiche mit Verbesserungspotenzial

In einigen fotografischen Szenarien liefern die automatische Fokussierung und die Belichtungsmessung möglicherweise nicht die gewünschten Ergebnisse. Ab Android 4.0 (API-Level 14) kann deine Kamera-App zusätzliche Steuerelemente bereitstellen, mit denen deine App oder Nutzer Bereiche in einem Bild angeben können, die für die Bestimmung der Fokus- oder Lichtstärkeeinstellungen 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 ähnlich wie andere Kamerafunktionen. Du steuerst sie über Methoden im Camera.Parameters-Objekt. Im folgenden Code wird gezeigt, wie zwei Belichtungsmessbereiche 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, mit dem ein Bereich im Sichtfeld der Kamera angegeben wird, und einen Gewichtungswert, der der Kamera mitteilt, wie wichtig dieser Bereich bei der Belichtungsmessung oder Fokusberechnung sein soll.

Das Feld Rect in einem Camera.Area-Objekt beschreibt eine rechteckige Form, die auf einem Raster mit 2.000 × 2.000 Einheiten abgebildet ist. Die Koordinaten -1000, -1000 stellen die obere linke Ecke des Kamerabilds dar und die Koordinaten 1000, 1000 die untere rechte Ecke des Kamerabilds, wie in der Abbildung unten gezeigt.

Abbildung 1. Die roten Linien veranschaulichen das Koordinatensystem, mit dem ein Camera.Area in einer Kameravorschau angegeben wird. 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 Bildes, das in der Kameravorschau sichtbar ist, und werden nicht mit der Zoomstufe verkleinert oder vergrößert. Auch bei der Drehung der Bildvorschau mit Camera.setDisplayOrientation() wird das Koordinatensystem nicht neu zugeordnet.

Gesichtserkennung

Bei Bildern, auf denen Personen zu sehen sind, sind die Gesichter in der Regel der wichtigste Teil des Bildes. Sie sollten beim Aufnehmen eines Bildes sowohl für die Fokussierung als auch für den Weißabgleich verwendet werden. Das Android 4.0-Framework (API-Level 14) bietet APIs zum Identifizieren von Gesichtern und zum Berechnen 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.

Die Verwendung der Gesichtserkennungsfunktion in Ihrer Kameraanwendung erfordert einige allgemeine Schritte:

  • Prüfen, ob die Gesichtserkennung auf dem Gerät unterstützt wird
  • Listener für die Gesichtserkennung erstellen
  • Fügen Sie dem Kameraobjekt den Listener für die Gesichtserkennung hinzu.
  • Gesichtserkennung nach der Vorschau (und nach jedem Neustart der Vorschau) starten

Die Gesichtserkennung wird nicht auf allen Geräten unterstützt. Sie können prüfen, ob diese Funktion unterstützt wird, indem Sie getMaxNumDetectedFaces() aufrufen. Ein Beispiel für diese Prüfung finden Sie unten in der Beispielmethode startFaceDetection().

Damit Sie benachrichtigt werden und auf die Erkennung eines Gesichts reagieren können, muss Ihre Kameraanwendung einen Listener für Gesichtserkennungsereignisse festlegen. Dazu müssen Sie eine Listener-Klasse erstellen, die die Schnittstelle Camera.FaceDetectionListener implementiert, wie im folgenden Beispielcode 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());

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 Aufruf 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 der Ausführung Ihrer Anwendung nicht verfügbar ist.

Zeitraffervideo

Mit Zeitraffervideos können Nutzer Videoclips erstellen, in denen Bilder kombiniert werden, die im Abstand von einigen Sekunden oder Minuten aufgenommen wurden. Diese Funktion verwendet MediaRecorder, um die Bilder für eine Zeitraffersequenz aufzunehmen.

Wenn du ein Zeitraffervideo mit MediaRecorder aufnehmen möchtest, musst du das Recorder-Objekt so konfigurieren, als würdest du ein normales Video aufnehmen. Setze die aufgenommenen Bilder pro Sekunde auf eine niedrige Zahl und verwende 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 Konfigurationsverfahrens für MediaRecorder vorgenommen werden. Ein vollständiges Codebeispiel für die Konfiguration finden Sie unter MediaRecorder konfigurieren. Nach Abschluss der Konfiguration starten Sie die Videoaufnahme 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 mit Android 10 (API-Level 29) oder höher benötigen die Berechtigung CAMERA, um auf die Werte der folgenden Felder zuzugreifen, 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 finden Sie unter Camera2Basic-Beispiel und Offizielle CameraX-Beispiel-App.