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 zum Aufnehmen von Bildern und Videos beschrieben. Außerdem wird ein erweiterter Ansatz zum Erstellen benutzerdefinierter Kamerafunktionen für Ihre Nutzer erläutert.
Hinweis:Auf dieser Seite wird die Klasse Camera
beschrieben, die eingestellt wurde. Wir empfehlen die Verwendung der CameraX-Jetpack-Bibliothek oder, für bestimmte Anwendungsfälle, der Klasse camera2
. Sowohl CameraX als auch Camera2 funktionieren mit Android 5.0 (API-Level 21) und höher.
Weitere Informationen finden Sie in den folgenden Ressourcen:
Wissenswertes
Bevor Sie die Verwendung von Kameras auf Android-Geräten in Ihrer Anwendung aktivieren, sollten Sie sich einige Fragen dazu stellen, wie Ihre App diese Hardwarefunktion nutzen soll.
- Kamera erforderlich: Ist die Verwendung einer Kamera für Ihre Anwendung so wichtig, dass Sie nicht möchten, dass Ihre Anwendung auf einem Gerät ohne Kamera installiert wird? In diesem Fall sollten Sie die Kameraanforderung in Ihrem Manifest deklarieren.
- Schnelles Bild oder benutzerdefinierte Kamera: Wie wird die Kamera in Ihrer Anwendung verwendet? Möchten Sie nur schnell ein Foto oder einen Videoclip aufnehmen oder bietet Ihre Anwendung eine neue Möglichkeit, Kameras zu verwenden? Wenn Sie schnell ein Foto oder einen Clip aufnehmen möchten, können Sie vorhandene Kamera-Apps verwenden. Informationen zum Entwickeln einer benutzerdefinierten Kamerafunktion finden Sie im Abschnitt Kamera-App erstellen.
- Anforderung für Dienste im Vordergrund: Wann interagiert Ihre App mit der Kamera? Unter Android 9 (API-Level 28) und höher können Apps, die im Hintergrund ausgeführt werden, nicht auf die Kamera zugreifen. Daher sollten Sie die Kamera entweder verwenden, wenn sich Ihre App im Vordergrund befindet, oder als Teil eines Dienstes im Vordergrund.
- Speicher: Sollen die von Ihrer Anwendung generierten Bilder oder Videos nur für Ihre Anwendung sichtbar sein oder so freigegeben werden, dass 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 Ihre Anwendung deinstalliert wird? Im Abschnitt Mediendateien speichern erfahren Sie, wie Sie diese Optionen implementieren.
Grundlagen
Das Android-Framework unterstützt das Aufnehmen 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 von Gerätekameras. Sie kann zum Aufnehmen von Bildern oder Videos verwendet werden, wenn Sie eine Kameraanwendung entwickeln.
Camera
- Diese Klasse ist die ältere, eingestellte API zum Steuern 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
oderMediaStore.ACTION_VIDEO_CAPTURE
können Bilder oder Videos aufgenommen werden, ohne dasCamera
-Objekt direkt zu verwenden.
Manifestdeklarationen
Bevor Sie mit der Entwicklung Ihrer Anwendung mit der Camera API beginnen, sollten Sie darauf achten, dass Ihr Manifest die entsprechenden Deklarationen enthält, um die Verwendung von Kamerahardware und anderen zugehörigen Funktionen zu ermöglichen.
- Kameraberechtigung: Ihre Anwendung muss die Berechtigung zur Verwendung einer Gerätekamera anfordern.
<uses-permission android:name="android.permission.CAMERA" />
Hinweis:Wenn Sie die Kamera durch Aufrufen einer vorhandenen Kamera-App verwenden, muss Ihre Anwendung diese Berechtigung nicht anfordern.
- Kamerafunktionen: In Ihrer Anwendung muss auch die Verwendung von Kamerafunktionen deklariert werden, z. B.:
<uses-feature android:name="android.hardware.camera" />
Eine Liste der Kamerafunktionen finden Sie in der Manifestreferenz unter Features.
Wenn Sie Ihrem Manifest Kamerafunktionen hinzufügen, verhindert Google Play, dass Ihre Anwendung auf Geräten installiert wird, die keine Kamera haben oder die von Ihnen angegebenen Kamerafunktionen nicht unterstützen. Weitere Informationen zur Verwendung von funktionsbasierten Filtern mit Google Play finden Sie unter Google Play und funktionsbasierte Filterung.
Wenn Ihre Anwendung eine Kamera oder Kamerafunktion für den ordnungsgemäßen Betrieb verwenden kann, aber nicht erfordert, sollten Sie dies im Manifest angeben, indem Sie das Attribut
android:required
einfügen und auffalse
setzen:<uses-feature android:name="android.hardware.camera" android:required="false" />
- Speicherberechtigung: Ihre Anwendung kann Bilder oder Videos auf dem externen Speicher (SD-Karte) des Geräts speichern, wenn sie auf Android 10 (API-Level 29) oder niedriger ausgerichtet ist und Folgendes im Manifest angegeben ist.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Berechtigung für Audioaufnahmen: Wenn Sie Audioinhalte mit Videoaufnahmen aufzeichnen 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 Ihre App auf Android 5.0 (API-Level 21) oder höher ausgerichtet ist, müssen Sie auch deklarieren, dass Ihre App das GPS des Geräts verwendet:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ... <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. --> <uses-feature android:name="android.hardware.location.gps" />
Weitere Informationen zum Abrufen des Nutzerstandorts finden Sie unter Standortstrategien.
Vorhandene Kamera-Apps verwenden
Eine schnelle Möglichkeit, das Aufnehmen von Fotos oder Videos in Ihrer Anwendung zu ermöglichen, ohne viel zusätzlichen Code zu schreiben, ist die Verwendung eines Intent
, um eine vorhandene Android-Kameraanwendung aufzurufen.
Die Details werden in den Trainingslektionen Einfach Fotos aufnehmen und Einfach Videos aufnehmen beschrieben.
Kamera-App entwickeln
Einige Entwickler benötigen möglicherweise eine Kamera-Benutzeroberfläche, die an das Erscheinungsbild ihrer Anwendung angepasst ist oder spezielle Funktionen bietet. Wenn Sie Ihren eigenen Code zum Aufnehmen von Bildern schreiben, können Sie die Nutzerfreundlichkeit verbessern.
Hinweis: Der folgende Leitfaden bezieht sich auf die ältere, eingestellte Camera
API. Für neue oder erweiterte Kameraanwendungen wird die neuere android.hardware.camera2
API empfohlen.
So erstellen Sie eine benutzerdefinierte Kameraoberfläche für Ihre Anwendung:
- Kamera erkennen und darauf zugreifen: Erstellen Sie Code, um nach Kameras zu suchen und Zugriff anzufordern.
- Vorschauklasse erstellen: Erstellen Sie eine Kameravorschauklasse, die
SurfaceView
erweitert und dieSurfaceHolder
-Schnittstelle implementiert. In dieser Klasse werden die Livebilder der Kamera angezeigt. - Vorschaulayout erstellen: Nachdem Sie die Kamera-Vorschauklasse haben, erstellen Sie ein Ansichtslayout, das die Vorschau und die gewünschten Benutzeroberflächenelemente enthält.
- Listener für die Aufnahme einrichten: Verbinden Sie Listener für die Steuerelemente Ihrer Benutzeroberfläche, um die Aufnahme von Bildern oder Videos als Reaktion auf Nutzeraktionen wie das Drücken einer Schaltfläche zu starten.
- Dateien aufnehmen und speichern: Richten Sie den Code zum Aufnehmen von Bildern oder Videos und zum Speichern der Ausgabe ein.
- Kamera freigeben: Nachdem Sie die Kamera verwendet haben, muss Ihre Anwendung sie ordnungsgemäß freigeben, damit sie von anderen Anwendungen verwendet werden kann.
Die Kamerahardware ist eine gemeinsam genutzte Ressource, die sorgfältig verwaltet werden muss, damit Ihre Anwendung nicht mit anderen Anwendungen in Konflikt gerät, die sie möglicherweise auch verwenden möchten. In den folgenden Abschnitten wird beschrieben, wie Sie Kamerahardware erkennen, Zugriff auf eine Kamera anfordern, Bilder oder Videos aufnehmen und die Kamera freigeben, wenn Ihre Anwendung sie nicht mehr verwendet.
Achtung:Denken Sie daran, das Camera
-Objekt freizugeben, indem Sie Camera.release()
aufrufen, wenn Ihre Anwendung es nicht mehr verwendet. Wenn Ihre Anwendung die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Versuche, auf die Kamera zuzugreifen, fehl. Das gilt auch für Versuche Ihrer eigenen Anwendung. Außerdem kann es dazu führen, dass Ihre oder andere Anwendungen geschlossen werden.
Kamerahardware erkennen
Wenn für Ihre Anwendung keine Kamera mit einer Manifestdeklaration erforderlich ist, sollten Sie zur Laufzeit prüfen, ob eine Kamera verfügbar ist. Verwenden Sie für diese Prüfung die Methode PackageManager.hasSystemFeature()
, wie im Beispielcode unten gezeigt:
Kotlin
/** Check if this device has a camera */ private fun checkCameraHardware(context: Context): Boolean { if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { // this device has a camera return true } else { // no camera on this device return false } }
Java
/** Check if this device has a camera */ private boolean checkCameraHardware(Context context) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){ // this device has a camera return true; } else { // no camera on this device return false; } }
Android-Geräte können mehrere Kameras haben, z. B. eine nach hinten gerichtete Kamera für Fotos und eine nach vorn gerichtete Kamera 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 Sie festgestellt haben, dass das Gerät, auf dem Ihre Anwendung ausgeführt wird, eine Kamera hat, müssen Sie den Zugriff darauf anfordern, indem Sie eine Instanz von Camera
abrufen (es sei denn, Sie verwenden einen Intent für den Zugriff auf die Kamera).
Verwenden Sie die Methode Camera.open()
, um auf die primäre Kamera zuzugreifen. Achten Sie darauf, alle Ausnahmen abzufangen, wie im folgenden Code gezeigt:
Kotlin
/** A safe way to get an instance of the Camera object. */ fun getCameraInstance(): Camera? { return try { Camera.open() // attempt to get a Camera instance } catch (e: Exception) { // Camera is not available (in use or does not exist) null // returns null if camera is unavailable } }
Java
/** A safe way to get an instance of the Camera object. */ public static Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(); // attempt to get a Camera instance } catch (Exception e){ // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable }
Achtung:Prüfen Sie bei der Verwendung von Camera.open()
immer auf Ausnahmen. Wenn Sie nicht prüfen, ob Ausnahmen vorliegen, wenn die Kamera verwendet wird oder nicht vorhanden ist, wird Ihre Anwendung vom System geschlossen.
Auf Geräten mit Android 2.3 (API-Level 9) oder höher können Sie mit Camera.open(int)
auf bestimmte Kameras zugreifen. Mit dem Beispielcode oben wird auf die erste Rückkamera auf einem Gerät mit mehreren Kameras zugegriffen.
Kamerafunktionen prüfen
Sobald Sie Zugriff auf eine Kamera 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 Sie API-Level 9 oder höher verwenden, können Sie mit Camera.getCameraInfo()
ermitteln, ob sich eine Kamera auf der Vorder- oder Rückseite des Geräts befindet, und die Ausrichtung des Bildes bestimmen.
Vorschauklasse erstellen
Damit Nutzer effektiv Fotos oder Videos aufnehmen können, müssen sie sehen können, was die Gerätekamera aufnimmt. Eine Kameravorschauklasse ist ein SurfaceView
, das die Live-Bilddaten einer Kamera anzeigen kann, damit Nutzer ein Foto 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 zum Erstellen und Zerstören der Ansicht zu erfassen, die zum Zuweisen der Kamera-Vorschaueingabe 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 oben in den Kommentaren beschrieben. Beim Festlegen der Vorschaugröße müssen Sie Werte aus getSupportedPreviewSizes()
verwenden.
Legen Sie im setPreviewSize()
-Verfahren keine beliebigen Werte fest.
Hinweis:Mit der Einführung der
Mehrfenstermodus-Funktion in Android 7.0 (API-Level 24) und höher können Sie nicht mehr davon ausgehen, dass das Seitenverhältnis der Vorschau mit dem Ihrer Aktivität übereinstimmt, auch nachdem Sie setDisplayOrientation()
aufgerufen haben.
Je nach Fenstergröße und Seitenverhältnis müssen Sie möglicherweise eine breite Kameravorschau in ein Layout im Hochformat einpassen oder umgekehrt. Verwenden Sie dazu ein Letterbox-Layout.
Vorschau in einem Layout platzieren
Eine Kameravorschauklasse, wie im Beispiel im vorherigen Abschnitt gezeigt, muss zusammen mit anderen Steuerelementen der Benutzeroberfläche zum Aufnehmen eines Fotos oder Videos im Layout einer Aktivität platziert werden. In diesem Abschnitt erfahren Sie, wie Sie ein einfaches Layout und eine einfache Aktivität für die Vorschau erstellen.
Der folgende Layoutcode stellt eine sehr einfache Ansicht bereit, die zum Anzeigen einer Kameravorschau verwendet werden kann. In diesem Beispiel soll das FrameLayout
-Element der Container für die Kameravorschauklasse sein. Dieses Layout wird verwendet, damit zusätzliche Bildinformationen oder Steuerelemente auf die Live-Kameravorschau gelegt werden können.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@+id/camera_preview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" /> <Button android:id="@+id/button_capture" android:text="Capture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </LinearLayout>
Bei den meisten Geräten ist die Standardausrichtung der Kamera-Vorschau das Querformat. In diesem Beispiel wird ein horizontales (Querformat-)Layout angegeben. Der Code unten legt die Ausrichtung der Anwendung auf das Querformat fest. Um die Darstellung einer Kameravorschau zu vereinfachen, sollten Sie die Ausrichtung der Vorschauaktivität Ihrer Anwendung in Ihrem Manifest in „landscape“ ändern.
<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 Drehung 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, die Ausrichtung ändern und dann die Vorschau mit Camera.startPreview()
wieder starten.
Fügen Sie in der Aktivität für die Kameraansicht dem FrameLayout
-Element aus dem Beispiel oben die Vorschauklasse hinzu. Bei der Kameraaktivität muss die Kamera auch freigegeben werden, wenn sie pausiert oder heruntergefahren wird. Das folgende Beispiel zeigt, wie Sie eine Kameraaktivität ändern, um die in Vorschauklasse erstellen gezeigte Vorschauklasse anzuhängen.
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 obigen Beispiel bezieht sich auf die Beispielmethode unter Auf Kameras zugreifen.
Bilder aufnehmen
Nachdem Sie eine Vorschauklasse und ein Ansichtslayout erstellt haben, in dem sie angezeigt werden soll, können Sie mit Ihrer Anwendung Bilder aufnehmen. In Ihrem Anwendungscode müssen Sie Listener für die Steuerelemente der Benutzeroberfläche einrichten, damit auf eine Nutzeraktion mit dem Aufnehmen eines Bildes reagiert wird.
Verwenden Sie zum Abrufen eines Bildes die Methode Camera.takePicture()
. Diese Methode verwendet drei Parameter, die Daten von der Kamera empfangen.
Damit Sie Daten im JPEG-Format empfangen können, müssen Sie eine Camera.PictureCallback
-Schnittstelle implementieren, um die Bilddaten zu empfangen und in eine Datei zu schreiben. Im folgenden Code sehen Sie 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 das Aufnehmen eines Bildes durch Aufrufen der Methode Camera.takePicture()
aus. Das folgende Beispiel 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 mPicture
-Element im folgenden Beispiel bezieht sich auf den Beispielcode oben.
Achtung:Denken Sie daran, das Camera
-Objekt freizugeben, indem Sie Camera.release()
aufrufen, wenn Ihre Anwendung es nicht mehr verwendet. Informationen zum Lösen der Kamera finden Sie unter Kamera lösen.
Videos aufnehmen
Für die Videoaufnahme mit dem Android-Framework ist eine sorgfältige Verwaltung des Camera
-Objekts und eine Koordination mit der MediaRecorder
-Klasse erforderlich. Wenn Sie Videos mit Camera
aufnehmen, müssen Sie die Aufrufe Camera.lock()
und Camera.unlock()
verwalten, damit MediaRecorder
neben den Aufrufen Camera.open()
und Camera.release()
auf die Kamerahardware zugreifen kann.
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 Fotos mit einer Gerätekamera ist für die Videoaufnahme eine ganz bestimmte Reihenfolge von Aufrufen erforderlich. Sie müssen eine bestimmte Reihenfolge einhalten, um die Videoaufnahme mit Ihrer Anwendung vorzubereiten und durchzuführen.
- Kamera öffnen: Verwenden Sie
Camera.open()
, um eine Instanz des Kameraobjekts abzurufen. - Connect Preview: Bereitet eine Live-Kamerabildvorschau vor, indem eine
SurfaceView
überCamera.setPreviewDisplay()
mit der Kamera verbunden wird. - Vorschau starten: Rufe
Camera.startPreview()
auf, um mit der Anzeige der Live-Kamerabilder zu beginnen. - Video aufnehmen: Die folgenden Schritte müssen in der richtigen Reihenfolge ausgeführt werden, um ein Video aufzunehmen:
- Kamera entsperren: Entsperre die Kamera für die Verwendung durch
MediaRecorder
, indem duCamera.unlock()
aufrufst. - 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 die aktuelle Instanz vonCamera
Ihrer Anwendung.setAudioSource()
: Legen Sie die Audioquelle mitMediaRecorder.AudioSource.CAMCORDER
fest.setVideoSource()
: Verwenden SieMediaRecorder.VideoSource.CAMERA
, um die Videoquelle festzulegen.- Legen Sie das Videoausgabeformat und die Codierung fest. Verwenden Sie für Android 2.2 (API-Level 8) und höher die Methode
MediaRecorder.setProfile
und rufen Sie eine Profilinstanz mitCamcorderProfile.get()
ab. Bei Android-Versionen vor 2.2 müssen Sie das Videoausgabeformat und die Codierungsparameter festlegen:setOutputFormat()
: Legen Sie das Ausgabeformat fest. Geben Sie die Standardeinstellung oderMediaRecorder.OutputFormat.MPEG_4
an.setAudioEncoder()
: Legen Sie den Typ der Soundcodierung fest. Geben Sie die Standardeinstellung oderMediaRecorder.AudioEncoder.AMR_NB
an.setVideoEncoder()
: Legen Sie den Videocodierungstyp fest. Geben Sie die Standardeinstellung oderMediaRecorder.VideoEncoder.MPEG_4_SP
an.
setOutputFile()
: Legen Sie die Ausgabedatei fest. Verwenden Sie dazugetOutputMediaFile(MEDIA_TYPE_VIDEO).toString()
aus der Beispielmethode im Abschnitt Mediendateien speichern.setPreviewDisplay()
: Geben Sie dasSurfaceView
-Vorschaulayout-Element 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. - MediaRecorder vorbereiten: Bereiten Sie den
MediaRecorder
mit den bereitgestellten Konfigurationseinstellungen vor, indem SieMediaRecorder.prepare()
aufrufen. - MediaRecorder starten: Rufen Sie
MediaRecorder.start()
auf, um die Videoaufzeichnung zu starten.
- Kamera entsperren: Entsperre die Kamera für die Verwendung durch
- Videoaufzeichnung beenden: Rufen Sie die folgenden Methoden in der angegebenen Reihenfolge auf, um eine Videoaufzeichnung erfolgreich abzuschließen:
- MediaRecorder beenden: Die Videoaufzeichnung wird durch Aufrufen von
MediaRecorder.stop()
beendet. - MediaRecorder zurücksetzen: Optional können Sie die Konfigurationseinstellungen aus dem Recorder entfernen, indem Sie
MediaRecorder.reset()
aufrufen. - MediaRecorder freigeben: Geben Sie die
MediaRecorder
frei, indem SieMediaRecorder.release()
aufrufen. - Kamera sperren: Sperrt die Kamera, sodass sie in zukünftigen
MediaRecorder
-Sitzungen durch Aufrufen vonCamera.lock()
verwendet werden kann. Ab Android 4.0 (API-Level 14) ist dieser Aufruf nur erforderlich, wenn derMediaRecorder.prepare()
-Aufruf fehlschlägt.
- MediaRecorder beenden: Die Videoaufzeichnung wird durch Aufrufen von
- Vorschau beenden: Wenn Sie die Kamera nicht mehr benötigen, beenden Sie die Vorschau mit
Camera.stopPreview()
. - Kamera freigeben: Gibt die Kamera frei, damit sie von anderen Anwendungen verwendet werden kann, indem
Camera.release()
aufgerufen wird.
Hinweis:Es ist möglich, MediaRecorder
zu verwenden, ohne zuerst eine Kameravorschau zu erstellen. In diesem Fall können Sie die ersten Schritte dieses Vorgangs überspringen. Da Nutzer in der Regel eine Vorschau sehen möchten, bevor sie eine Aufzeichnung starten, wird dieser Vorgang hier nicht beschrieben.
Tipp:Wenn Ihre Anwendung normalerweise zum Aufzeichnen von Videos verwendet wird, legen Sie setRecordingHint(boolean)
vor dem Starten der Vorschau auf true
fest. Diese Einstellung kann dazu beitragen, die Zeit zu verkürzen, die zum Starten der Aufzeichnung benötigt wird.
MediaRecorder konfigurieren
Wenn Sie die Klasse MediaRecorder
zum Aufzeichnen von Videos verwenden, müssen Sie die Konfigurationsschritte in einer bestimmten Reihenfolge ausführen und dann die Methode MediaRecorder.prepare()
aufrufen, um die Konfiguration zu prüfen und zu implementieren. 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 Parameter für die Videoaufnahme für MediaRecorder
sind Standardeinstellungen festgelegt. Möglicherweise möchten Sie diese Einstellungen jedoch für Ihre Anwendung anpassen:
setVideoEncodingBitRate()
setVideoSize()
setVideoFrameRate()
setAudioEncodingBitRate()
setAudioChannels()
setAudioSamplingRate()
MediaRecorder starten und beenden
Wenn Sie die Videoaufzeichnung mit der Klasse MediaRecorder
starten und stoppen, müssen Sie eine bestimmte Reihenfolge einhalten, wie unten aufgeführt.
- Kamera mit
Camera.unlock()
entsperren - Konfigurieren Sie
MediaRecorder
wie im Codebeispiel oben. - Aufzeichnung mit
MediaRecorder.start()
starten - Video aufnehmen
- Aufnahme mit
MediaRecorder.stop()
beenden - Media Recorder mit
MediaRecorder.release()
freigeben - Kamera mit
Camera.lock()
verriegeln
Der folgende Beispielcode zeigt, wie eine Schaltfläche so konfiguriert wird, dass die Videoaufzeichnung mit der Kamera und der Klasse MediaRecorder
richtig gestartet und beendet wird.
Hinweis:Lassen Sie die Kamera nicht los, wenn Sie eine Videoaufnahme beenden, da sonst die Vorschau 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 unter MediaRecorder konfigurieren. Diese Methode kümmert sich um das Sperren der Kamera sowie das Konfigurieren und Vorbereiten der MediaRecorder
-Instanz.
Kamera lösen
Kameras sind eine Ressource, die von Anwendungen auf einem Gerät gemeinsam genutzt wird. Ihre Anwendung kann die Kamera verwenden, nachdem sie eine Instanz von Camera
erhalten hat. Sie müssen besonders darauf achten, das Kameraobjekt freizugeben, wenn Ihre Anwendung es nicht mehr verwendet und sobald Ihre Anwendung pausiert wird (Activity.onPause()
). Wenn Ihre Anwendung die Kamera nicht ordnungsgemäß freigibt, schlagen alle nachfolgenden Versuche, auf die Kamera zuzugreifen, einschließlich der Versuche Ihrer eigenen Anwendung, fehl und können dazu führen, dass Ihre oder andere Anwendungen geschlossen werden.
Verwenden Sie zum Freigeben einer Instanz des Camera
-Objekts 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, auch die Ihrer eigenen Anwendung, fehl und können dazu führen, dass Ihre oder andere Anwendungen geschlossen werden.
Mediendateien speichern
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 Verzeichnisspeicherorte zum Speichern von Mediendateien auf einem Gerät. Als Entwickler sollten Sie jedoch nur zwei Standardspeicherorte in Betracht ziehen:
Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES
): Diese Methode gibt den standardmäßigen, freigegebenen und empfohlenen Speicherort für das Speichern von Bildern und Videos zurück. Dieses Verzeichnis ist freigegeben (öffentlich), sodass andere Anwendungen Dateien, die an diesem Speicherort gespeichert sind, problemlos finden, lesen, ändern und löschen können. Wenn Ihre Anwendung vom Nutzer deinstalliert wird, werden die an diesem Speicherort gespeicherten Mediendateien nicht entfernt. Um zu vermeiden, dass die vorhandenen Bilder und Videos der Nutzer beeinträchtigt werden, sollten Sie in diesem Verzeichnis ein Unterverzeichnis für die Mediendateien Ihrer Anwendung erstellen, wie im folgenden Codebeispiel gezeigt. Diese Methode ist in Android 2.2 (API-Level 8) verfügbar. Informationen zu entsprechenden Aufrufen in früheren API-Versionen finden Sie unter Gemeinsam genutzte Dateien speichern.Context.getExternalFilesDir
(Environment.DIRECTORY_PICTURES
): Diese Methode gibt einen Standardspeicherort zum Speichern von Bildern und Videos zurück, die mit Ihrer Anwendung verknüpft sind. Wenn Ihre Anwendung deinstalliert wird, werden alle an diesem Speicherort gespeicherten Dateien entfernt. Für Dateien an diesem Speicherort wird keine Sicherheit erzwungen und andere Anwendungen können sie lesen, ändern und löschen.
Der folgende Beispielcode zeigt, wie Sie einen File
- oder Uri
-Speicherort für eine Mediendatei erstellen, der beim Aufrufen der Kamera eines Geräts mit einem Intent
oder im Rahmen einer Kamera-App verwendet werden kann.
Kotlin
val MEDIA_TYPE_IMAGE = 1 val MEDIA_TYPE_VIDEO = 2 /** Create a file Uri for saving an image or video */ private fun getOutputMediaFileUri(type: Int): Uri { return Uri.fromFile(getOutputMediaFile(type)) } /** Create a File for saving an image or video */ private fun getOutputMediaFile(type: Int): File? { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. val mediaStorageDir = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp" ) // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist mediaStorageDir.apply { if (!exists()) { if (!mkdirs()) { Log.d("MyCameraApp", "failed to create directory") return null } } } // Create a media file name val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) return when (type) { MEDIA_TYPE_IMAGE -> { File("${mediaStorageDir.path}${File.separator}IMG_$timeStamp.jpg") } MEDIA_TYPE_VIDEO -> { File("${mediaStorageDir.path}${File.separator}VID_$timeStamp.mp4") } else -> null } }
Java
public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; /** Create a file Uri for saving an image or video */ private static Uri getOutputMediaFileUri(int type){ return Uri.fromFile(getOutputMediaFile(type)); } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else if(type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); } else { return null; } return mediaFile; }
Hinweis:Environment.getExternalStoragePublicDirectory()
ist ab Android 2.2 (API-Level 8) verfügbar. Wenn Sie Geräte mit älteren Android-Versionen ausrichten, 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 Kameraanwendung steuern können, z. B. Bildformat, Blitzmodus und Fokuseinstellungen. In diesem Abschnitt werden die gängigen Kamerafunktionen aufgeführt und kurz erläutert. Die meisten Kamerafunktionen können über das Camera.Parameters
-Objekt aufgerufen und eingestellt werden. Für einige wichtige Funktionen sind jedoch mehr als nur einfache Einstellungen in Camera.Parameters
erforderlich. Diese Funktionen werden in den folgenden Abschnitten behandelt:
Allgemeine Informationen zur Verwendung von Funktionen, die über Camera.Parameters
gesteuert werden, finden Sie im Abschnitt Kamerafunktionen verwenden. Weitere Informationen zur Verwendung von Funktionen, die über das Objekt „Kameraparameter“ gesteuert werden, finden Sie in der API-Referenzdokumentation unter den Links in der Funktionsliste unten.
Tabelle 1 Häufig verwendete Kamerafunktionen, sortiert nach dem Android-API‑Level, in dem sie eingeführt wurden.
Funktion | API-Level | Beschreibung |
---|---|---|
Gesichtserkennung | 14 | Gesichter 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 für den Fokus festlegen |
White Balance Lock |
14 | Automatisches Anpassen des Weißabgleichs beenden oder starten |
Exposure Lock |
14 | Automatische Belichtungsanpassung aktivieren oder deaktivieren |
Video Snapshot |
14 | Während der Videoaufnahme ein Foto aufnehmen (Einzelbild) |
Zeitraffervideo | 11 | Mit festgelegten Verzögerungen Bilder aufnehmen, um ein Zeitraffervideo zu erstellen |
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 scheinbar im Fokus sind. |
Zoom |
8 | Bildvergrößerung festlegen |
Exposure
Compensation |
8 | Lichtexposition erhöhen oder verringern |
GPS Data |
5 | Geografische Standortdaten mit dem Bild einfügen oder weglassen |
White Balance |
5 | Stellen Sie den Weißabgleichsmodus ein, 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 | Einen voreingestellten Modus für bestimmte Arten von Fotosituationen anwenden, z. B. für Nacht-, Strand-, Schnee- oder Kerzenscheinszenen |
JPEG Quality |
5 | Legen Sie die Komprimierungsstufe für ein JPEG-Bild fest. Dadurch wird die Qualität und Größe der Bildausgabedatei erhöht oder verringert. |
Flash Mode |
5 | Blitz aktivieren, deaktivieren oder automatische Einstellung verwenden |
Color Effects |
5 | Sie können dem aufgenommenen Bild einen Farbeffekt hinzufügen, z. B. Schwarz-Weiß, Sepia oder Negativ. |
Anti-Banding |
5 | Reduziert den Effekt von Banding in Farbverläufen aufgrund der JPEG-Komprimierung |
Picture Format |
1 | Dateiformat für das Bild angeben |
Picture Size |
1 | Pixelabmessungen des gespeicherten Bilds angeben |
Hinweis:Diese Funktionen werden aufgrund von Hardwareunterschieden und Softwareimplementierung nicht auf allen Geräten unterstützt. Informationen zum Prüfen der Verfügbarkeit von Funktionen auf dem Gerät, auf dem Ihre Anwendung ausgeführt wird, finden Sie unter Verfügbarkeit von Funktionen prüfen.
Verfügbarkeit von Funktionen prüfen
Wenn Sie 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 können Geräte, die eine bestimmte Funktion unterstützen, diese in unterschiedlichem Umfang oder mit unterschiedlichen Optionen unterstützen. Daher müssen Sie bei der Entwicklung einer Kameraanwendung auch entscheiden, welche Kamerafunktionen Sie in welchem Umfang unterstützen möchten. Nachdem Sie diese Entscheidung getroffen haben, sollten Sie Code in Ihre Kameraanwendung einfügen, der prüft, ob die Gerätehardware diese Funktionen unterstützt, und bei Nichtverfügbarkeit einer Funktion ordnungsgemäß fehlschlägt.
Sie können die Verfügbarkeit von Kamerafunktionen prüfen, indem Sie eine Instanz des Parameterobjekts einer Kamera abrufen und die relevanten Methoden aufrufen. Das folgende Codebeispiel zeigt, 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 }
Sie können die oben beschriebene Methode für die meisten Kamerafunktionen verwenden. Das Camera.Parameters
-Objekt bietet eine getSupported...()
-, is...Supported()
- oder getMax...()
-Methode, um festzustellen, ob (und in welchem Umfang) eine Funktion unterstützt wird.
Wenn Ihre Anwendung bestimmte Kamerafunktionen benötigt, damit sie richtig funktioniert, können Sie diese durch Ergänzungen in Ihrem Anwendungsmanifest anfordern. Wenn Sie die Verwendung bestimmter Kamerafunktionen wie Blitz und Autofokus deklarieren, wird die Installation Ihrer Anwendung auf Geräten, die diese Funktionen nicht unterstützen, bei Google Play eingeschränkt. Eine Liste der Kamerafunktionen, die im App-Manifest deklariert werden können, finden Sie in der Funktionsreferenz für das Manifest.
Kamerafunktionen verwenden
Die meisten Kamerafunktionen werden mit einem 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, 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 und die meisten Parameter können jederzeit geändert werden, nachdem Sie eine Instanz des Camera
-Objekts erhalten haben. Änderungen an Parametern sind in der Regel sofort in der Kameravorschau der Anwendung sichtbar.
Auf der Softwareseite kann es mehrere Frames dauern, bis Parameteränderungen wirksam werden, da die Kamerahardware die neuen Anweisungen verarbeitet und dann aktualisierte Bilddaten sendet.
Wichtig:Einige Kamerafunktionen können nicht beliebig geändert werden. Wenn Sie beispielsweise die Größe oder Ausrichtung der Kameravorschau ändern möchten, müssen Sie die Vorschau zuerst beenden, die Größe der Vorschau ändern und die Vorschau dann 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 Fokusbereiche
- Gesichtserkennung
- Zeitraffer-Video
In den folgenden Abschnitten finden Sie eine kurze Anleitung zur Implementierung dieser Funktionen.
Messung und Fokusbereiche
In einigen fotografischen Situationen liefern die automatische Fokussierung und Lichtmessung möglicherweise nicht die gewünschten Ergebnisse. Ab Android 4.0 (API-Level 14) kann Ihre Kameraanwendung zusätzliche Steuerelemente bereitstellen, mit denen Ihre App oder Nutzer Bereiche in einem Bild angeben können, die zum Bestimmen von Fokus- oder Helligkeitseinstellungen verwendet werden sollen. Diese Werte werden dann an die Kamerahardware übergeben, damit sie beim Aufnehmen von Bildern oder Videos verwendet werden können.
Bereiche für die Belichtungsmessung und den Fokus funktionieren sehr ähnlich wie andere Kamerafunktionen. Sie werden über Methoden im Camera.Parameters
-Objekt gesteuert. Im folgenden Code wird gezeigt, wie zwei Bereiche für die Lichtmessung für eine Instanz von Camera
festgelegt werden:
Kotlin
// Create an instance of Camera camera = getCameraInstance() // set Camera parameters val params: Camera.Parameters? = camera?.parameters params?.apply { if (maxNumMeteringAreas > 0) { // check that metering areas are supported meteringAreas = ArrayList<Camera.Area>().apply { val areaRect1 = Rect(-100, -100, 100, 100) // specify an area in center of image add(Camera.Area(areaRect1, 600)) // set weight to 60% val areaRect2 = Rect(800, -1000, 1000, -800) // specify an area in upper right of image add(Camera.Area(areaRect2, 400)) // set weight to 40% } } camera?.parameters = this }
Java
// Create an instance of Camera camera = getCameraInstance(); // set Camera parameters Camera.Parameters params = camera.getParameters(); if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>(); Rect areaRect1 = new Rect(-100, -100, 100, 100); // specify an area in center of image meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60% Rect areaRect2 = new Rect(800, -1000, 1000, -800); // specify an area in upper right of image meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40% params.setMeteringAreas(meteringAreas); } camera.setParameters(params);
Das Camera.Area
-Objekt enthält zwei Datenparameter: ein Rect
-Objekt zum Angeben eines Bereichs im Sichtfeld der Kamera und einen Gewichtungswert, der der Kamera mitteilt, welche Bedeutung diesem Bereich bei der Lichtmessung oder Fokusberechnung beigemessen werden soll.
Das Feld Rect
in einem Camera.Area
-Objekt beschreibt eine rechteckige Form, die auf ein Raster mit 2.000 × 2.000 Einheiten abgebildet wird. Die Koordinaten -1000, -1000 stehen für die obere linke Ecke des Kamerabilds und die Koordinaten 1000, 1000 für die untere rechte Ecke des Kamerabilds, wie in der Abbildung unten dargestellt.
Abbildung 1: Die roten Linien veranschaulichen das Koordinatensystem zum Angeben eines Camera.Area
in einer Kameravorschau. Das blaue Rechteck 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 in der Kameravorschau sichtbaren Bildes und werden nicht mit dem Zoomfaktor verkleinert oder vergrößert. Auch bei einer Drehung der Bildvorschau mit Camera.setDisplayOrientation()
wird das Koordinatensystem nicht neu zugeordnet.
Gesichtserkennung
Bei Bildern mit Personen sind Gesichter in der Regel der wichtigste Teil des Bildes. Sie sollten sowohl für die Fokussierung als auch für den Weißabgleich beim Aufnehmen eines Bildes verwendet werden. Das Framework für Android 4.0 (API-Level 14) bietet APIs zum Identifizieren von Gesichtern und Berechnen von Bildeinstellungen mithilfe der Gesichtserkennungstechnologie.
Hinweis:Während die Gesichtserkennung läuft, haben setWhiteBalance(String)
, setFocusAreas(List<Camera.Area>)
und setMeteringAreas(List<Camera.Area>)
keine Auswirkungen.
Für die Verwendung der Gesichtserkennung in Ihrer Kameraanwendung sind einige allgemeine Schritte erforderlich:
- Prüfen, ob die Gesichtserkennung auf dem Gerät unterstützt wird
- Listener für die Gesichtserkennung erstellen
- Gesichtserkennungs-Listener zum Kameraobjekt hinzufügen
- Gesichtserkennung nach der Vorschau starten (und nach jedem Neustart der Vorschau)
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 in der Beispielmethode startFaceDetection()
unten.
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 Camera.FaceDetectionListener
-Schnittstelle implementiert, wie im Beispielcode unten gezeigt.
Kotlin
internal class MyFaceDetectionListener : Camera.FaceDetectionListener { override fun onFaceDetection(faces: Array<Camera.Face>, camera: Camera) { if (faces.isNotEmpty()) { Log.d("FaceDetection", ("face detected: ${faces.size}" + " Face 1 Location X: ${faces[0].rect.centerX()}" + "Y: ${faces[0].rect.centerY()}")) } } }
Java
class MyFaceDetectionListener implements Camera.FaceDetectionListener { @Override public void onFaceDetection(Face[] faces, Camera camera) { if (faces.length > 0){ Log.d("FaceDetection", "face detected: "+ faces.length + " Face 1 Location X: " + faces[0].rect.centerX() + "Y: " + faces[0].rect.centerY() ); } } }
Nachdem Sie diese Klasse erstellt haben, legen Sie sie im Camera
-Objekt Ihrer Anwendung fest, wie im folgenden Beispielcode gezeigt:
Kotlin
camera?.setFaceDetectionListener(MyFaceDetectionListener())
Java
camera.setFaceDetectionListener(new MyFaceDetectionListener());
Ihre Anwendung muss die Gesichtserkennungsfunktion jedes Mal starten (oder neu 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 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 (oder neu starten), wenn Sie die Kameravorschau starten (oder neu starten). Wenn Sie die in Vorschauklasse erstellen gezeigte Vorschauklasse verwenden, fügen Sie die startFaceDetection()
-Methode sowohl der surfaceCreated()
- als auch der surfaceChanged()
-Methode in Ihrer Vorschauklasse hinzu, wie im folgenden Beispielcode 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:Rufen Sie diese Methode nach dem Aufrufen von startPreview()
auf. Versuchen Sie nicht, die Gesichtserkennung in der Methode onCreate()
der Hauptaktivität Ihrer Kamera-App zu starten, da die Vorschau zu diesem Zeitpunkt in der Ausführung Ihrer Anwendung noch nicht verfügbar ist.
Zeitraffer-Video
Mit Zeitraffervideos können Nutzer Videoclips erstellen, in denen Bilder kombiniert werden, die im Abstand von wenigen Sekunden oder Minuten aufgenommen wurden. Diese Funktion verwendet MediaRecorder
, um die Bilder für eine Zeitraffersequenz aufzunehmen.
Wenn Sie mit MediaRecorder
ein Zeitraffervideo aufnehmen möchten, müssen Sie das Recorder-Objekt so konfigurieren, als würden Sie ein normales Video aufnehmen. Stellen Sie die erfassten Bilder pro Sekunde auf einen niedrigen Wert ein und verwenden Sie eine der Zeitraffer-Qualitä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 umfassenderen Konfiguration für MediaRecorder
vorgenommen werden. Ein vollständiges Beispiel für den Konfigurationscode finden Sie unter MediaRecorder konfigurieren. Sobald die Konfiguration abgeschlossen ist, starten Sie die Videoaufzeichnung wie bei einem normalen Videoclip. Weitere Informationen zum Konfigurieren und Ausführen von MediaRecorder
finden Sie unter Videos aufnehmen.
Die Beispiele Camera2Video und HdrViewfinder veranschaulichen die Verwendung der auf dieser Seite behandelten APIs.
Kamerafelder, für die eine Berechtigung erforderlich ist
Apps, die unter Android 10 (API‑Level 29) oder höher ausgeführt werden, 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 im Camera2Basic-Beispiel und in der offiziellen CameraX-Beispiel-App.