Das Android-Framework unterstützt verschiedene auf Geräten verfügbare Kameras und Kamerafunktionen, mit denen Sie in Ihren Apps Bilder und Videos aufnehmen können. In diesem Dokument wird ein schneller, einfacher Ansatz für die Bild- und Videoaufnahme beschrieben und ein erweiterter Ansatz zum Erstellen benutzerdefinierter Kamerafunktionen für Nutzer beschrieben.
Hinweis:Auf dieser Seite wird die verworfene Klasse Camera
beschrieben. Wir empfehlen die Verwendung der CameraX-Jetpack-Bibliothek oder für bestimmte Anwendungsfälle der Klasse camera2
. Sowohl CameraX als auch Camera2 funktionieren unter Android 5.0 (API-Level 21) und höher.
Weitere Informationen finden Sie in den folgenden verwandten Ressourcen:
Wissenswertes
Bevor Sie Ihrer App die Verwendung von Kameras auf Android-Geräten ermöglichen, sollten Sie sich einige Fragen dazu stellen, wie Ihre App diese Hardwarefunktion nutzen möchte.
- Kameraanforderung: Ist die Verwendung einer Kamera für Ihre Anwendung so wichtig, dass sie nicht auf Geräten ohne Kamera installiert werden soll? Falls ja, solltest du die Kameraanforderung in deinem Manifest angeben.
- Quick Picture oder benutzerdefinierte Kamera – Wie verwendet Ihre Anwendung die Kamera? Möchten Sie nur schnell ein Bild oder einen Videoclip aufnehmen oder bietet Ihre App eine neue Möglichkeit, Kameras zu verwenden? Unter Bestehende Kamera-Apps verwenden können Sie schnell einen Schnappschuss oder Clip erstellen. Informationen zur Entwicklung einer benutzerdefinierten Kamerafunktion finden Sie im Abschnitt 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 im Hintergrund ausgeführte Apps nicht auf die Kamera zugreifen. Daher solltest du die Kamera verwenden, wenn deine App im Vordergrund ausgeführt wird oder wenn sie zu einem Dienst im Vordergrund gehört.
- Speicher: Sind die von Ihrer App generierten Bilder oder Videos nur für Ihre App sichtbar oder werden sie freigegeben, damit sie von anderen Anwendungen wie der Galerie oder anderen Medien und sozialen Apps verwendet werden können? Sollen die Bilder und Videos auch nach der Deinstallation Ihrer Anwendung verfügbar sein? Informationen zur Implementierung dieser Optionen findest du im Abschnitt Mediendateien speichern.
Grundlagen
Das Android-Framework unterstützt die Erfassung 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 zum Steuern der Gerätekameras. Sie können damit Fotos oder Videos aufnehmen, wenn Sie eine Kamera-App erstellen.
Camera
- Diese Klasse ist die ältere eingestellte API zur Steuerung von Gerätekameras.
SurfaceView
- Mit dieser Klasse wird Nutzern eine Live-Kameravorschau präsentiert.
MediaRecorder
- Mit dieser Klasse werden Videos von der Kamera aufgezeichnet.
Intent
- Mit dem Intent-Aktionstyp
MediaStore.ACTION_IMAGE_CAPTURE
oderMediaStore.ACTION_VIDEO_CAPTURE
können Bilder oder Videos erfasst werden, ohne dasCamera
-Objekt direkt zu verwenden.
Manifestdeklarationen
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 einer Gerätekamera anfordern.
<uses-permission android:name="android.permission.CAMERA" />
Hinweis:Wenn Sie die Kamera verwenden, indem Sie eine vorhandene Kamera-App aufrufen, muss Ihre App diese Berechtigung nicht anfordern.
- Kamerafunktionen: In deiner App muss auch die Verwendung von Kamerafunktionen erklärt werden, zum Beispiel:
<uses-feature android:name="android.hardware.camera" />
Eine Liste der Kamerafunktionen findest du in der Referenz zu Funktionen im Manifest.
Wenn du deinem Manifest Kamerafunktionen hinzufügst, verhindert Google Play die Installation deiner App auf Geräten, die keine Kamera haben oder die von dir angegebenen Kamerafunktionen nicht unterstützen. Weitere Informationen zum funktionsbasierten Filtern bei Google Play findest du unter Google Play und funktionsbasiertes Filtern.
Wenn in Ihrer App eine Kamera- oder Kamerafunktion für einen einwandfreien Betrieb verwendet werden kann, dies aber nicht erforderlich ist, sollten Sie dies im Manifest angeben, indem Sie das Attribut
android:required
einfügen und es auffalse
setzen:<uses-feature android:name="android.hardware.camera" android:required="false" />
- Speicherberechtigung: Deine App kann Bilder oder Videos auf dem 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 Audioaufnahme: Für die Aufzeichnung von Audio mit Videoaufnahme muss Ihre Anwendung die Berechtigung für die Audioaufnahme 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, Bilder oder Videos in Ihrer App ohne großen zusätzlichen Code aufzunehmen, besteht darin, mit einem Intent
eine vorhandene Android-Kamera-App aufzurufen.
Weitere Informationen finden Sie in den Trainingsmodulen Fotos einfach gemacht und Videos einfach aufnehmen.
Kamera-App erstellen
Einige Entwickler benötigen möglicherweise eine Kamera-Benutzeroberfläche, die an das Erscheinungsbild ihrer App angepasst ist oder spezielle Funktionen bietet. Wenn Sie Ihren eigenen Code zur Aufnahme von Bildern erstellen, können Sie die Nutzererfahrung ansprechender gestalten.
Hinweis: Die folgende Anleitung bezieht sich auf die ältere, verworfene Camera
API. Für neue oder erweiterte Kameraanwendungen wird die neuere android.hardware.camera2
API empfohlen.
Die allgemeinen Schritte zum Erstellen einer benutzerdefinierten Kameraoberfläche für Ihre Anwendung sind die folgenden:
- Kamera erkennen und darauf zugreifen: Erstellt Code, um das Vorhandensein von Kameras zu prüfen und den Zugriff anzufordern.
- Vorschauklasse erstellen – Erstellt eine Kameravorschauklasse, die
SurfaceView
erweitert und dieSurfaceHolder
-Schnittstelle implementiert. Diese Klasse zeigt eine Vorschau der Live-Bilder von der Kamera. - Vorschaulayout erstellen: Sobald Sie die Kameravorschauklasse haben, erstellen Sie ein Ansichtslayout, das die Vorschau und die gewünschten Steuerelemente für die Benutzeroberfläche enthält.
- Listener für die Erfassung einrichten: Verbinden Sie Listener für Ihre Benutzeroberflächensteuerelemente, um die Bild- oder Videoaufnahme als Reaktion auf Nutzeraktionen wie das Drücken einer Schaltfläche zu starten.
- Dateien erfassen und speichern: Richten Sie den Code zum Erfassen von Bildern oder Videos und Speichern der Ausgabe ein.
- Kamera freigeben: Nachdem Sie die Kamera verwendet haben, muss sie von Ihrer App ordnungsgemäß für andere Anwendungen freigegeben werden.
Die Kamerahardware ist eine gemeinsam genutzte Ressource, die sorgfältig verwaltet werden muss, damit Ihre Anwendung nicht mit anderen Anwendungen kollidiert, die sie möglicherweise ebenfalls verwenden möchten. In den folgenden Abschnitten wird erläutert, wie Sie die Kamerahardware erkennen, Zugriff auf eine Kamera anfordern, Bilder oder Videos aufnehmen und die Kamera wieder freigeben, wenn Ihre Anwendung sie nicht mehr verwendet hat.
Achtung:Denken Sie daran, das Objekt Camera
freizugeben. Rufen Sie dazu Camera.release()
auf, wenn Ihre Anwendung die Verwendung abgeschlossen hat. Wenn Ihre Anwendung die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Versuche, auf die Kamera zuzugreifen, fehl, auch die von Ihrer eigenen Anwendung. Dies kann dazu führen, dass Ihre oder andere Anwendungen heruntergefahren werden.
Kamerahardware wird erkannt
Wenn für deine App keine Kamera mit 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 Kamera auf der Rückseite zum Fotografieren und eine Frontkamera für Videoanrufe. Mit Android 2.3 (API-Level 9) und höher kannst du die Anzahl der auf einem Gerät verfügbaren Kameras mit der Methode Camera.getNumberOfCameras()
prüfen.
Auf Kameras zugreifen
Wenn Sie festgestellt haben, dass das Gerät, auf dem Ihre App ausgeführt wird, eine Kamera hat, müssen Sie den Zugriff über eine Instanz von Camera
anfordern (es sei denn, Sie verwenden einen Intent, um auf die Kamera zuzugreifen).
Verwenden Sie die Methode Camera.open()
, um auf die primäre Kamera zuzugreifen, und achten Sie darauf, alle Ausnahmen wie im folgenden Code zu erkennen:
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:Achten Sie bei der Verwendung von Camera.open()
immer auf Ausnahmen. Wenn Sie nicht prüfen, ob Ausnahmen vorliegen, wenn die Kamera verwendet wird oder nicht vorhanden ist, wird Ihre Anwendung vom System heruntergefahren.
Auf Geräten mit Android 2.3 (API-Level 9) oder höher kannst du mit Camera.open(int)
auf bestimmte Kameras zugreifen. Der obige Beispielcode greift auf die erste rückseitige Kamera eines Geräts mit mehr als einer Kamera zu.
Kamerafunktionen werden geprüft
Nachdem Sie Zugriff auf eine Kamera erhalten haben, können Sie 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 wie das Bild ausgerichtet ist.
Vorschauklasse erstellen
Damit Nutzer effektiv Bilder oder Videos aufnehmen können, müssen sie in der Lage sein, zu sehen, was die Kamera des Geräts sieht. Eine Kameravorschauklasse ist ein SurfaceView
, der die von einer Kamera stammenden Live-Bilddaten darstellen kann, damit Nutzer ein Bild oder Video mit Frames aufnehmen und aufnehmen können.
Der folgende Beispielcode zeigt, wie eine einfache Kameravorschauklasse erstellt wird, die in ein View
-Layout aufgenommen werden kann. Diese Klasse implementiert SurfaceHolder.Callback
, um die Callback-Ereignisse zum Erstellen und Löschen der Ansicht zu erfassen. Diese sind für die Zuweisung der Kameravorschaueingabe erforderlich.
Kotlin
/** A basic Camera preview class */ class CameraPreview( context: Context, private val mCamera: Camera ) : SurfaceView(context), SurfaceHolder.Callback { private val mHolder: SurfaceHolder = holder.apply { // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. addCallback(this@CameraPreview) // deprecated setting, but required on Android versions prior to 3.0 setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) } override fun surfaceCreated(holder: SurfaceHolder) { // The Surface has been created, now tell the camera where to draw the preview. mCamera.apply { try { setPreviewDisplay(holder) startPreview() } catch (e: IOException) { Log.d(TAG, "Error setting camera preview: ${e.message}") } } } override fun surfaceDestroyed(holder: SurfaceHolder) { // empty. Take care of releasing the Camera preview in your activity. } override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. if (mHolder.surface == null) { // preview surface does not exist return } // stop preview before making changes try { mCamera.stopPreview() } catch (e: Exception) { // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings mCamera.apply { try { setPreviewDisplay(mHolder) startPreview() } catch (e: Exception) { Log.d(TAG, "Error starting camera preview: ${e.message}") } } } }
Java
/** A basic Camera preview class */ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; public CameraPreview(Context context, Camera camera) { super(context); mCamera = camera; // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = getHolder(); mHolder.addCallback(this); // deprecated setting, but required on Android versions prior to 3.0 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, now tell the camera where to draw the preview. try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } public void surfaceDestroyed(SurfaceHolder holder) { // empty. Take care of releasing the Camera preview in your activity. } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. if (mHolder.getSurface() == null){ // preview surface does not exist return; } // stop preview before making changes try { mCamera.stopPreview(); } catch (Exception e){ // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception e){ Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } } }
Wenn Sie für die Kameravorschau eine bestimmte Größe festlegen möchten, legen Sie dies in der surfaceChanged()
-Methode fest, wie in den Kommentaren oben erwähnt. Beim Festlegen der Vorschaugröße müssen Sie Werte aus getSupportedPreviewSizes()
verwenden.
Legen Sie keine beliebigen Werte in der Methode setPreviewSize()
fest.
Hinweis:Mit der Einführung der
Mehrfenstermodus-Funktion in Android 7.0 (API-Ebene 24) und höher kannst du nicht mehr davon ausgehen, dass das Seitenverhältnis der Vorschau deiner Aktivität entspricht, auch nachdem du setDisplayOrientation()
aufgerufen hast.
Je nach Fenstergröße und Seitenverhältnis kann es sein, dass du die Vorschau einer Breitbildkamera an ein Hochformat anpassen musst oder umgekehrt, indem du ein Letterbox-Layout verwendest.
Vorschau in einem Layout platzieren
Eine Kameravorschauklasse, wie im vorherigen Abschnitt gezeigt, muss im Layout einer Aktivität zusammen mit anderen Steuerelementen der Benutzeroberfläche zum Aufnehmen von Bildern oder Videos platziert werden. In diesem Abschnitt erfahren Sie, wie Sie ein grundlegendes Layout und eine Aktivität für die Vorschau erstellen.
Der folgende Layoutcode bietet eine sehr einfache Ansicht, die zur Anzeige einer Kameravorschau verwendet werden kann. In diesem Beispiel ist das Element FrameLayout
der Container für die Kameravorschauklasse. Mit diesem Layouttyp können zusätzliche Bildinformationen oder Steuerelemente über die Live-Vorschaubilder der Kamera 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 das Querformat. Dieses Beispiellayout gibt ein horizontales Layout (Querformat) an und der Code unten legt die Ausrichtung der Anwendung im Querformat fest. Um das Rendern der Kameravorschau zu vereinfachen, sollten Sie die Ausrichtung der Aktivität der App in das Querformat ändern. Fügen Sie dazu Folgendes zu Ihrem Manifest hinzu.
<activity android:name=".CameraActivity" android:label="@string/app_name" android:screenOrientation="landscape"> <!-- configure this activity to use landscape orientation --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Hinweis:Eine Kameravorschau muss nicht im Querformat sein.
Ab Android 2.2 (API-Ebene 8) können Sie mit der Methode setDisplayOrientation()
die Rotation des Vorschaubilds festlegen. Wenn Sie die Ausrichtung der Vorschau ändern möchten, wenn der Nutzer das Smartphone neu ausrichtet, müssen Sie in der Methode surfaceChanged()
Ihrer Vorschauklasse zuerst die Vorschau mit Camera.stopPreview()
beenden und dann noch einmal mit Camera.startPreview()
starten.
Fügen Sie in der Aktivität für die Kameraansicht Ihre Vorschauklasse dem FrameLayout
-Element hinzu, wie im Beispiel oben dargestellt. Außerdem muss durch die Kameraaktivität dafür gesorgt werden, dass die Kamera freigegeben wird, wenn sie pausiert oder heruntergefahren wird. Das folgende Beispiel zeigt, wie Sie eine Kameraaktivität ändern, um die Vorschauklasse hinzuzufügen, die unter Vorschauklasse erstellen beschrieben wird.
Kotlin
class CameraActivity : Activity() { private var mCamera: Camera? = null private var mPreview: CameraPreview? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create an instance of Camera mCamera = getCameraInstance() mPreview = mCamera?.let { // Create our Preview view CameraPreview(this, it) } // Set the Preview view as the content of our activity. mPreview?.also { val preview: FrameLayout = findViewById(R.id.camera_preview) preview.addView(it) } } }
Java
public class CameraActivity extends Activity { private Camera mCamera; private CameraPreview mPreview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create an instance of Camera mCamera = getCameraInstance(); // Create our Preview view and set it as the content of our activity. mPreview = new CameraPreview(this, mCamera); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(mPreview); } }
Hinweis:Die Methode getCameraInstance()
im Beispiel oben bezieht sich auf die unter Auf Kameras zugreifen gezeigte Methode.
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 einrichten, damit die Steuerelemente Ihrer Benutzeroberfläche auf Nutzeraktionen durch Aufnehmen eines Bildes reagieren.
Verwenden Sie zum Abrufen eines Bildes die Methode Camera.takePicture()
. 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 grundlegende Implementierung der Camera.PictureCallback
-Schnittstelle zum Speichern eines von der Kamera empfangenen Bilds.
Kotlin
private val mPicture = Camera.PictureCallback { data, _ -> val pictureFile: File = getOutputMediaFile(MEDIA_TYPE_IMAGE) ?: run { Log.d(TAG, ("Error creating media file, check storage permissions")) return@PictureCallback } try { val fos = FileOutputStream(pictureFile) fos.write(data) fos.close() } catch (e: FileNotFoundException) { Log.d(TAG, "File not found: ${e.message}") } catch (e: IOException) { Log.d(TAG, "Error accessing file: ${e.message}") } }
Java
private PictureCallback mPicture = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); if (pictureFile == null){ Log.d(TAG, "Error creating media file, check storage permissions"); return; } try { FileOutputStream fos = new FileOutputStream(pictureFile); fos.write(data); fos.close(); } catch (FileNotFoundException e) { Log.d(TAG, "File not found: " + e.getMessage()); } catch (IOException e) { Log.d(TAG, "Error accessing file: " + e.getMessage()); } } };
Rufen Sie die Methode Camera.takePicture()
auf, um das Erfassen eines Bildes auszulösen. Der folgende Beispielcode zeigt, wie diese Methode über das View.OnClickListener
einer Schaltfläche 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 Objekt Camera
freizugeben. Rufen Sie dazu Camera.release()
auf, wenn Ihre Anwendung die Verwendung abgeschlossen hat. Informationen zum Freigeben der Kamera finden Sie unter Kamera loslösen.
Videos aufnehmen
Für Videoaufnahmen mit dem Android-Framework ist eine sorgfältige Verwaltung des Camera
-Objekts und eine Abstimmung mit der Klasse MediaRecorder
erforderlich. Wenn du Videos mit Camera
aufzeichnest, musst du die Camera.lock()
- und Camera.unlock()
-Aufrufe verwalten, um MediaRecorder
neben den Camera.open()
- und Camera.release()
-Aufrufen den Zugriff auf die Kamerahardware zu erlauben.
Hinweis:Ab Android 4.0 (API-Level 14) werden die Aufrufe Camera.lock()
und Camera.unlock()
automatisch für Sie verwaltet.
Anders als beim Aufnehmen von Bildern mit einer Gerätekamera erfordert die Videoaufnahme eine ganz bestimmte Reihenfolge von Aufrufen. Sie müssen eine bestimmte Ausführungsreihenfolge einhalten, um sich wie unten beschrieben auf ein Video vorzubereiten und mit Ihrer Anwendung aufzunehmen.
- Kamera öffnen: Verwenden Sie
Camera.open()
, um eine Instanz des Kameraobjekts abzurufen. - Vorschau verbinden – Bereite eine Live-Kamerabildvorschau vor, indem du ein
SurfaceView
überCamera.setPreviewDisplay()
mit der Kamera verbindest. - Vorschau starten: Rufen Sie
Camera.startPreview()
auf, um die Live-Kamerabilder anzusehen. - Videoaufnahme starten: Damit das Video aufgezeichnet werden kann, müssen die folgenden Schritte ausgeführt werden:
- Kamera entsperren: Rufen Sie
Camera.unlock()
auf, um die Kamera fürMediaRecorder
zu entsperren. - MediaRecorder konfigurieren: Rufen Sie die folgenden
MediaRecorder
-Methoden in dieser Reihenfolge auf. Weitere Informationen finden Sie in der Referenzdokumentation zuMediaRecorder
.setCamera()
: Legen Sie die Kamera fest, die für die Videoaufnahme verwendet werden soll. Verwenden Sie dazu die aktuelle Instanz vonCamera
in Ihrer Anwendung.setAudioSource()
: Legen Sie die Audioquelle fest. Verwenden Sie dazuMediaRecorder.AudioSource.CAMCORDER
.setVideoSource()
: Legen Sie die Videoquelle fest. Verwenden Sie dazuMediaRecorder.VideoSource.CAMERA
.- Legen Sie das Videoausgabeformat und die Codierung fest. Verwenden Sie ab Android 2.2 (API-Level 8) die Methode
MediaRecorder.setProfile
und rufen Sie mitCamcorderProfile.get()
eine Profilinstanz ab. Bei Android-Versionen vor 2.2 müssen Sie das Videoausgabeformat und die Codierungsparameter festlegen:setOutputFormat()
: Legen Sie das Ausgabeformat fest und geben Sie die Standardeinstellung oderMediaRecorder.OutputFormat.MPEG_4
an.setAudioEncoder()
: Legen Sie den Toncodierungstyp fest und geben Sie die Standardeinstellung oderMediaRecorder.AudioEncoder.AMR_NB
an.setVideoEncoder()
: Legen Sie den Videocodierungstyp fest und geben Sie die Standardeinstellung oderMediaRecorder.VideoEncoder.MPEG_4_SP
an.
setOutputFile()
: Legen Sie die Ausgabedatei fest und verwenden SiegetOutputMediaFile(MEDIA_TYPE_VIDEO).toString()
aus der Beispielmethode im Abschnitt Mediendateien speichern.setPreviewDisplay()
: Geben Sie das Vorschau-LayoutelementSurfaceView
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. Andernfalls treten in der Anwendung Fehler auf und die Aufzeichnung schlägt fehl. - MediaRecorder vorbereiten: Bereiten Sie den
MediaRecorder
mit den bereitgestellten Konfigurationseinstellungen vor. Rufen Sie dazuMediaRecorder.prepare()
auf. - MediaRecorder starten: Starten Sie die Videoaufnahme durch Aufrufen von
MediaRecorder.start()
.
- Kamera entsperren: Rufen Sie
- Videoaufnahme beenden: Rufen Sie der Reihe nach die folgenden Methoden auf, um eine Videoaufnahme erfolgreich abzuschließen:
- MediaRecorder beenden: Rufen Sie
MediaRecorder.stop()
auf, um die Videoaufnahme zu beenden. - MediaRecorder zurücksetzen: Entfernen Sie optional die Konfigurationseinstellungen aus dem Rekorder, indem Sie
MediaRecorder.reset()
aufrufen. - Release MediaRecorder: Veröffentliche
MediaRecorder
durch Aufrufen vonMediaRecorder.release()
. - Kamera sperren: Sperren Sie die Kamera, damit sie in zukünftigen
MediaRecorder
-Sitzungen verwendet werden kann. Dazu rufen SieCamera.lock()
auf. Ab Android 4.0 (API-Level 14) ist dieser Aufruf nur dann erforderlich, wenn derMediaRecorder.prepare()
-Aufruf fehlschlägt.
- MediaRecorder beenden: Rufen Sie
- Vorschau beenden: Wenn Ihre Aktivität die Kameranutzung beendet hat, beenden Sie die Vorschau mit
Camera.stopPreview()
. - Release Camera: Lassen Sie die Kamera los, damit andere Anwendungen sie verwenden können. Rufen Sie dazu
Camera.release()
auf.
Hinweis:Sie können MediaRecorder
verwenden, ohne zuvor eine Kameravorschau zu erstellen, und die ersten Schritte dieses Vorgangs überspringen. Da Nutzer jedoch in der Regel es vorziehen, eine Vorschau anzuzeigen, bevor sie eine Aufzeichnung starten, wird dieser Vorgang hier nicht erläutert.
Tipp:Wenn deine App normalerweise zum Aufzeichnen von Videos verwendet wird, setze setRecordingHint(boolean)
vor der Vorschau auf true
. Mit dieser Einstellung lässt sich die Aufnahmezeit verkürzen.
MediaRecorder konfigurieren
Wenn Sie die Klasse MediaRecorder
zum Aufzeichnen von Videos verwenden, müssen Sie die Konfigurationsschritte in einer bestimmten Reihenfolge ausführen und dann die Methode MediaRecorder.prepare()
aufrufen, um die Konfiguration zu prüfen und zu implementieren. Der folgende Beispielcode zeigt, wie die 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; }
Vor Android 2.2 (API-Ebene 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 Videoaufnahmeparameter für MediaRecorder
gelten Standardeinstellungen. Sie können diese Einstellungen jedoch auch für Ihre Anwendung anpassen:
setVideoEncodingBitRate()
setVideoSize()
setVideoFrameRate()
setAudioEncodingBitRate()
setAudioChannels()
setAudioSamplingRate()
MediaRecorder starten und beenden
Wenn Sie eine Videoaufzeichnung mit der Klasse MediaRecorder
starten und beenden möchten, müssen Sie eine bestimmte Reihenfolge beachten, wie unten aufgeführt.
- Kamera mit
Camera.unlock()
entsperren - Konfigurieren Sie
MediaRecorder
wie im obigen Codebeispiel gezeigt - Aufnahme mit
MediaRecorder.start()
starten - Video aufnehmen
- Aufnahme mit
MediaRecorder.stop()
beenden - Medienrekorder mit
MediaRecorder.release()
loslassen - Kamera mit
Camera.lock()
sperren
Der folgende Beispielcode zeigt, wie eine Schaltfläche zum ordnungsgemäßen Starten und Beenden der Videoaufzeichnung mit der Kamera und der Klasse MediaRecorder
verbunden wird.
Hinweis:Lassen Sie die Kamera am Ende einer Videoaufnahme nicht los. Andernfalls wird die Vorschau beendet.
Kotlin
var isRecording = false val captureButton: Button = findViewById(R.id.button_capture) captureButton.setOnClickListener { if (isRecording) { // stop recording and release camera mediaRecorder?.stop() // stop the recording releaseMediaRecorder() // release the MediaRecorder object mCamera?.lock() // take camera access back from MediaRecorder // inform the user that recording has stopped setCaptureButtonText("Capture") isRecording = false } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording mediaRecorder?.start() // inform the user that recording has started setCaptureButtonText("Stop") isRecording = true } else { // prepare didn't work, release the camera releaseMediaRecorder() // inform user } } }
Java
private boolean isRecording = false; // Add a listener to the Capture button Button captureButton = (Button) findViewById(id.button_capture); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (isRecording) { // stop recording and release camera mediaRecorder.stop(); // stop the recording releaseMediaRecorder(); // release the MediaRecorder object mCamera.lock(); // take camera access back from MediaRecorder // inform the user that recording has stopped setCaptureButtonText("Capture"); isRecording = false; } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording mediaRecorder.start(); // inform the user that recording has started setCaptureButtonText("Stop"); isRecording = true; } else { // prepare didn't work, release the camera releaseMediaRecorder(); // inform user } } } } );
Hinweis:Im obigen Beispiel bezieht sich die Methode prepareVideoRecorder()
auf den Beispielcode unter MediaRecorder konfigurieren. Mit dieser Methode wird die Kamera gesperrt und die MediaRecorder
-Instanz konfiguriert und vorbereitet.
Kamera freigeben
Kameras sind eine Ressource, die von Apps auf einem Gerät gemeinsam genutzt wird. Ihre App kann die Kamera verwenden, nachdem sie eine Instanz von Camera
abgerufen hat. Achten Sie besonders darauf, dass das Kameraobjekt freigegeben wird, wenn Ihre App sie nicht mehr verwendet (Activity.onPause()
). Wenn Ihre App die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Versuche, auf die Kamera zuzugreifen, einschließlich solcher von Ihrer eigenen App, fehl und können dazu führen, dass Ihre oder andere Anwendungen beendet werden.
Verwenden Sie die Methode Camera.release()
, wie im Beispielcode unten gezeigt, um eine Instanz des Camera
-Objekts freizugeben.
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, einschließlich solcher von Ihrer eigenen Anwendung, fehl und können dazu führen, dass Ihre oder andere Anwendungen heruntergefahren werden.
Mediendateien werden gespeichert
Von Nutzern erstellte Mediendateien wie Bilder und Videos sollten im externen Speicherverzeichnis (SD-Karte) eines Geräts 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 Speicherorte für Mediendateien auf einem Gerät. Es gibt jedoch nur zwei Standardspeicherorte, die du als Entwickler in Betracht ziehen solltest:
Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES
): Diese Methode gibt den standardmäßigen, freigegebenen und empfohlenen Speicherort zum Speichern von Bildern und Videos zurück. Dieses Verzeichnis ist öffentlich freigegeben, damit andere Anwendungen die an diesem Ort gespeicherten Dateien leicht finden, lesen, ändern und löschen können. Wenn Ihre Anwendung vom Nutzer deinstalliert wird, werden an diesem Speicherort gespeicherte Mediendateien nicht entfernt. Um Beeinträchtigungen der vorhandenen Bilder und Videos der Nutzer zu vermeiden, sollten Sie in diesem Verzeichnis ein Unterverzeichnis für die Mediendateien Ihrer Anwendung erstellen, wie im nachfolgenden Codebeispiel gezeigt. Diese Methode ist in Android 2.2 (API-Level 8) verfügbar. Entsprechende Aufrufe in früheren API-Versionen finden Sie unter Freigegebene Dateien speichern.Context.getExternalFilesDir
(Environment.DIRECTORY_PICTURES
): Diese Methode gibt einen Standardspeicherort zum Speichern von Bildern und Videos zurück, die Ihrer App zugeordnet sind. Wenn Ihre Anwendung deinstalliert wird, werden alle an diesem Speicherort gespeicherten Dateien entfernt. Für Dateien an diesem Speicherort wird keine Sicherheit erzwungen. Andere Anwendungen können sie lesen, ändern und löschen.
Der folgende Beispielcode zeigt, wie du einen File
- oder Uri
-Speicherort für eine Mediendatei erstellst, die beim Aufrufen der Kamera eines Geräts mit einem Intent
oder im Rahmen der Erstellung einer Kamera-App verwendet werden kann.
Kotlin
val MEDIA_TYPE_IMAGE = 1 val MEDIA_TYPE_VIDEO = 2 /** Create a file Uri for saving an image or video */ private fun getOutputMediaFileUri(type: Int): Uri { return Uri.fromFile(getOutputMediaFile(type)) } /** Create a File for saving an image or video */ private fun getOutputMediaFile(type: Int): File? { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. val mediaStorageDir = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp" ) // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist mediaStorageDir.apply { if (!exists()) { if (!mkdirs()) { Log.d("MyCameraApp", "failed to create directory") return null } } } // Create a media file name val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) return when (type) { MEDIA_TYPE_IMAGE -> { File("${mediaStorageDir.path}${File.separator}IMG_$timeStamp.jpg") } MEDIA_TYPE_VIDEO -> { File("${mediaStorageDir.path}${File.separator}VID_$timeStamp.mp4") } else -> null } }
Java
public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; /** Create a file Uri for saving an image or video */ private static Uri getOutputMediaFileUri(int type){ return Uri.fromFile(getOutputMediaFile(type)); } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else if(type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); } else { return null; } return mediaFile; }
Hinweis:Environment.getExternalStoragePublicDirectory()
ist ab Android 2.2 (API-Level 8) verfügbar. Wenn deine App auf Geräte mit älteren Android-Versionen ausgerichtet ist, verwende stattdessen Environment.getExternalStorageDirectory()
. Weitere Informationen finden Sie unter Freigegebene Dateien speichern.
Damit der URI Arbeitsprofile unterstützt,
konvertieren Sie den Datei-URI in einen Inhalts-URI. Fügen Sie dann den Inhalts-URI zu EXTRA_OUTPUT
einer Intent
hinzu.
Weitere Informationen zum Speichern von Dateien auf einem Android-Gerät finden Sie unter Datenspeicherung.
Kamerafunktionen
Android unterstützt eine Vielzahl von Kamerafunktionen, die Sie über Ihre Kamera-App steuern können, z. B. Bildformat, Blitzmodus, Fokuseinstellungen und viele mehr. In diesem Abschnitt werden gängige Kamerafunktionen und ihre Verwendung kurz erläutert. Auf die meisten Kamerafunktionen kann mit dem Objekt Camera.Parameters
zugegriffen werden. Es gibt jedoch einige wichtige Funktionen, die mehr als 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 Kameraparameterobjekt gesteuert werden, finden Sie unter den Links in der Liste unten zur API-Referenzdokumentation.
Funktion | API-Ebene | Beschreibung |
---|---|---|
Gesichtserkennung | 14 | Erkennen Sie menschliche Gesichter in einem Bild und verwenden Sie sie für den Fokus, die Messung und den Weißabgleich. |
Messbereiche | 14 | Legen Sie einen oder mehrere Bereiche innerhalb eines Bildes fest, um den Weißabgleich zu berechnen |
Schwerpunkte | 14 | Einen oder mehrere Bildbereiche für den Fokus festlegen |
White Balance Lock |
14 | Automatische Anpassung des Weißabgleichs starten oder beenden |
Exposure Lock |
14 | Automatische Belichtungsanpassungen starten oder stoppen |
Video Snapshot |
14 | Bild während der Videodrehung aufnehmen (Frame-Graben) |
Video im Zeitraffer | 11 | Für ein Zeitraffervideo einzelne Frames mit festgelegten Verzögerungen aufnehmen |
Multiple Cameras |
9 | Unterstützung mehrerer Kameras auf einem Gerät, einschließlich Front- und Rückkameras |
Focus Distance |
9 | Meldet Abstände zwischen der Kamera und Objekten, die im Fokus zu sein scheinen |
Zoom |
8 | Bildvergrößerung festlegen |
Exposure
Compensation |
8 | Belichtung erhöhen oder verringern |
GPS Data |
5 | Geografische Standortdaten in das Bild ein- oder weglassen |
White Balance |
5 | Weißabgleichmodus festlegen, der sich auf die Farbwerte im aufgenommenen Bild auswirkt |
Focus Mode |
5 | Hier kannst du festlegen, wie die Kamera auf ein Motiv fokussiert, z. B. „Automatisch“, „Fest“, „Makro“ oder „Unendlich“. |
Scene Mode |
5 | Einen voreingestellten Modus für bestimmte Arten von Fotografiesituationen anwenden, z. B. Nacht-, Strand-, Schnee- oder Kerzenlicht-Szenen |
JPEG Quality |
5 | Legen Sie die Komprimierungsstufe für ein JPEG-Bild fest, um die Qualität und Größe der Ausgabedatei zu erhöhen oder zu verringern. |
Flash Mode |
5 | Blitz ein- oder ausschalten oder automatische Einstellung verwenden |
Color Effects |
5 | Sie können einen Farbeffekt auf das aufgenommene Bild anwenden, z. B. Schwarzweiß, Sepiatönung oder Negativ. |
Anti-Banding |
5 | Reduziert den Effekt von Streifen in Farbverläufen aufgrund der JPEG-Komprimierung. |
Picture Format |
1 | Dateiformat für das Bild angeben |
Picture Size |
1 | Geben Sie die Pixelabmessungen des gespeicherten Bildes an. |
Hinweis:Diese Funktionen werden aufgrund von Hardwareunterschieden und Softwareimplementierung nicht auf allen Geräten unterstützt. Informationen zur Überprüfung der Verfügbarkeit von Funktionen auf dem Gerät, auf dem Ihre Anwendung ausgeführt wird, finden Sie unter Verfügbarkeit von Features prüfen.
Verfügbarkeit von Funktionen wird geprüft
Bei der Verwendung von Kamerafunktionen auf Android-Geräten solltest du zuerst wissen, dass nicht alle Kamerafunktionen auf allen Geräten unterstützt werden. Außerdem können Geräte, die eine bestimmte Funktion unterstützen, diese auf verschiedenen Stufen oder mit anderen Optionen unterstützen. Daher besteht ein Teil Ihres Entscheidungsprozesses bei der Entwicklung einer Kamera-App darin, zu entscheiden, welche Kamerafunktionen Sie auf welcher Stufe unterstützen möchten. Nachdem Sie diese Entscheidung getroffen haben, sollten Sie Code in Ihre Kamera-App einfügen, der prüft, ob die Gerätehardware diese Funktionen unterstützt und fehlerfrei funktioniert, wenn eine Funktion nicht verfügbar ist.
Sie können die Verfügbarkeit von Kamerafunktionen prüfen, indem Sie eine Instanz des Parameter-Objekts 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 die Autofokusfunktion 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 }
Für die meisten Kamerafunktionen können Sie die oben gezeigte Technik verwenden. Das Camera.Parameters
-Objekt bietet eine getSupported...()
-, is...Supported()
- oder getMax...()
-Methode, um festzustellen, ob und in welchem Umfang eine Funktion unterstützt wird.
Wenn für Ihre App bestimmte Kamerafunktionen erforderlich sind, können Sie sie in Ihrem App-Manifest ergänzen. Wenn Sie die Verwendung bestimmter Kamerafunktionen wie Blitz und Autofokus erklären, schränkt Google Play die Installation Ihrer App auf Geräten ein, die diese Funktionen nicht unterstützen. Eine Liste der Kamerafunktionen, die in deinem App-Manifest deklariert werden können, findest du in der Referenz zu Funktionen des Manifests.
Kamerafunktionen verwenden
Die meisten Kamerafunktionen werden über ein Camera.Parameters
-Objekt aktiviert und gesteuert. Um dieses Objekt zu erhalten, rufen Sie zuerst eine Instanz des Camera
-Objekts ab, rufen die Methode getParameters()
auf, ändern das zurückgegebene Parameterobjekt und setzen es dann wieder im Kameraobjekt zurück, wie im folgenden Beispielcode gezeigt:
Kotlin
val params: Camera.Parameters? = camera?.parameters params?.focusMode = Camera.Parameters.FOCUS_MODE_AUTO camera?.parameters = params
Java
// get Camera parameters Camera.Parameters params = camera.getParameters(); // set the focus mode params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); // set Camera parameters camera.setParameters(params);
Diese Technik funktioniert für fast alle Kamerafunktionen. Die meisten Parameter können jederzeit geändert werden, nachdem Sie eine Instanz des Camera
-Objekts abgerufen haben. Änderungen an Parametern sind in der Regel sofort für den Nutzer in der Kameravorschau der Anwendung sichtbar.
Auf Softwareseite kann es mehrere Frames geben, 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. Wenn Sie die Größe oder Ausrichtung der Kameravorschau ändern möchten, müssen Sie zuerst die Vorschau beenden, die Größe der Vorschau ändern und dann die Vorschau neu starten. Ab Android 4.0 (API-Level 14) kann die Ausrichtung der Vorschau geändert werden, ohne dass sie neu gestartet werden müssen.
Für die Implementierung anderer Kamerafunktionen ist mehr Code erforderlich, darunter:
- Mess- und Fokusbereiche
- Gesichtserkennung
- Zeitraffervideo
In den folgenden Abschnitten finden Sie einen kurzen Überblick über die Implementierung dieser Funktionen.
Mess- und Fokusbereiche
In einigen fotografischen Szenarien erzielen die automatische Fokussierung und die Belichtungsmessung möglicherweise nicht die gewünschten Ergebnisse. Ab Android 4.0 (API-Level 14) bietet Ihre Kamera-App zusätzliche Steuerelemente, mit denen Ihre App oder Nutzer Bereiche in einem Bild angeben können, die zum Festlegen von Fokus- oder Helligkeitseinstellungen verwendet werden sollen. Diese Werte werden dann an die Kamerahardware übergeben, damit sie Bilder oder Videos aufnehmen können.
Mess- und Fokusbereiche funktionieren ähnlich wie andere Kamerafunktionen, da sie über Methoden im Camera.Parameters
-Objekt gesteuert werden können. Der folgende Code zeigt, wie zwei Bereiche zur Belichtungsmessung 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 innerhalb des Sichtfelds der Kamera und einen Gewichtungswert, der der Kamera mitteilt, welche Wichtigkeit dieser Bereich für die Belichtungsmessung oder Fokusberechnungen erhalten soll.
Das Feld Rect
in einem Camera.Area
-Objekt beschreibt eine rechteckige Form, die auf einem Raster von 2.000 × 2.000 Einheiten abgebildet ist. Die Koordinaten -1000, -1000 stehen für die obere und linke Ecke des Kamerabilds und die Koordinaten 1000, 1000 für die untere rechte Ecke des Kamerabilds, wie in der folgenden Abbildung dargestellt.
Die Grenzen dieses Koordinatensystems entsprechen immer dem äußeren Rand des in der Kameravorschau sichtbaren Bilds und werden mit der Zoomstufe nicht verkleinert oder erweitert. Ebenso erfolgt bei der Drehung der Bildvorschau mit Camera.setDisplayOrientation()
keine Neuzuordnung des Koordinatensystems.
Gesichtserkennung
Bei Bildern, auf denen Personen zu sehen sind, sind Gesichter in der Regel der wichtigste Teil des Bildes. Sie sollten bei der Aufnahme sowohl für den Fokus als auch für die Bestimmung des Weißabgleichs verwendet werden. Das Framework von Android 4.0 (API-Level 14) bietet APIs, mit denen Gesichter erkannt und Bildeinstellungen mithilfe von Technologie zur Gesichtserkennung berechnet werden können.
Hinweis:Während die Gesichtserkennung ausgeführt wird, haben setWhiteBalance(String)
, setFocusAreas(List<Camera.Area>)
und setMeteringAreas(List<Camera.Area>)
keine Auswirkungen.
Für die Verwendung der Gesichtserkennung in Ihrer Kamera-App sind einige allgemeine Schritte erforderlich:
- Prüfen, ob die Gesichtserkennung auf dem Gerät unterstützt wird
- Gesichtserkennungs-Listener erstellen
- Dem Kameraobjekt den Gesichtserkennungs-Listener hinzufügen
- Gesichtserkennung nach der Vorschau (und nach jedem Neustart der Vorschau) starten
Die Gesichtserkennung wird nicht auf allen Geräten unterstützt. Wenn Sie prüfen möchten, ob diese Funktion unterstützt wird, rufen Sie getMaxNumDetectedFaces()
auf. Ein Beispiel für diese Prüfung finden Sie in der startFaceDetection()
-Beispielmethode unten.
Damit Sie bei Gesichtserkennung benachrichtigt werden und entsprechend reagieren können, muss Ihre Kamera-App einen Listener für Gesichtserkennungsereignisse einrichten. Dazu müssen Sie eine Listener-Klasse erstellen, die die Camera.FaceDetectionListener
-Schnittstelle implementiert (siehe Beispielcode unten).
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 App muss die Gesichtserkennung jedes Mal starten, wenn Sie die Kameravorschau starten oder neu starten. Erstellen Sie eine Methode zum Starten der Gesichtserkennung, damit Sie sie nach Bedarf aufrufen können, wie im folgenden Beispielcode 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(); } }
Die Gesichtserkennung muss jedes Mal gestartet werden, wenn Sie die Kameravorschau starten oder neu starten. Wenn Sie die Vorschauklasse verwenden, die unter Vorschauklasse erstellen beschrieben wird, fügen Sie die Methode startFaceDetection()
den Methoden surfaceCreated()
und 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. Versuche nicht, die Gesichtserkennung in der onCreate()
-Methode der Hauptaktivität deiner Kamera-App zu starten, da die Vorschau zu diesem Zeitpunkt der Ausführung deiner App nicht verfügbar ist.
Zeitraffervideo
Zeitraffervideos ermöglichen es Nutzern, Videoclips zu erstellen, in denen Fotos kombiniert werden, die im Abstand von wenigen Sekunden oder Minuten aufgenommen wurden. Diese Funktion verwendet MediaRecorder
, um die Bilder für eine Zeitraffersequenz aufzuzeichnen.
Wenn Sie ein Zeitraffervideo mit MediaRecorder
aufzeichnen möchten, müssen Sie das Rekorder-Objekt so konfigurieren, als ob Sie ein normales Video aufnehmen würden. Dazu setzen Sie die Anzahl der erfassten Bilder pro Sekunde auf einen niedrigen Wert und verwenden eine der Zeitrafferqualitätseinstellungen, 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 einer umfangreicheren Konfiguration für MediaRecorder
vorgenommen werden. Ein vollständiges Codebeispiel für die Konfiguration finden Sie unter MediaRecorder konfigurieren. Sobald die Konfiguration abgeschlossen ist, starten Sie die Videoaufnahme so, als würden Sie einen normalen Videoclip aufzeichnen. Weitere Informationen zum Konfigurieren und Ausführen von MediaRecorder
finden Sie unter Videos aufzeichnen.
In den Beispielen Camera2Video und HdrViewfinder wird die Verwendung der auf dieser Seite behandelten APIs näher erläutert.
Kamerafelder, die eine Berechtigung erfordern
Apps mit Android 10 (API-Level 29) oder höher müssen die Berechtigung CAMERA
haben, um auf die Werte der folgenden Felder zugreifen zu können, die von der Methode getCameraCharacteristics()
zurückgegeben werden:
LENS_POSE_ROTATION
LENS_POSE_TRANSLATION
LENS_INTRINSIC_CALIBRATION
LENS_RADIAL_DISTORTION
LENS_POSE_REFERENCE
LENS_DISTORTION
LENS_INFO_HYPERFOCAL_DISTANCE
LENS_INFO_MINIMUM_FOCUS_DISTANCE
SENSOR_REFERENCE_ILLUMINANT1
SENSOR_REFERENCE_ILLUMINANT2
SENSOR_CALIBRATION_TRANSFORM1
SENSOR_CALIBRATION_TRANSFORM2
SENSOR_COLOR_TRANSFORM1
SENSOR_COLOR_TRANSFORM2
SENSOR_FORWARD_MATRIX1
SENSOR_FORWARD_MATRIX2
Zusätzlicher Beispielcode
Beispiel-Apps können Sie unter Camera2Basic und offizielle CameraX-Beispiel-App herunterladen.