Hinweis: Diese Seite bezieht sich auf das Camera2-Paket. Sofern Ihre App keine speziellen, Low-Level-Funktionen von Camera2 benötigt, empfehlen wir die Verwendung von CameraX. Sowohl CameraX als auch Camera2 unterstützen Android 5.0 (API-Level 21) und höher.
Viele moderne Android-Geräte haben zwei oder mehr Kameras auf der Vorder- oder Rückseite oder auf beiden Seiten des Geräts. Jedes Objektiv kann einzigartige Funktionen haben, z. B. Serienaufnahme, manuelle Steuerung oder Bewegungserkennung. Eine App zum Einzahlen von Schecks verwendet möglicherweise nur die erste rückwärtsgerichtete Kamera, während eine Social-Media-App standardmäßig eine nach vorne gerichtete Kamera verwendet, Nutzern aber die Möglichkeit gibt, zwischen allen verfügbaren Objektiven zu wechseln. Außerdem kann es sich die Auswahl der Nutzer merken.
Auf dieser Seite wird beschrieben, wie Sie Kameraobjektive und ihre Funktionen auflisten, damit Sie in Ihrer App entscheiden können, welches Objektiv in einer bestimmten Situation verwendet werden soll. Mit dem folgenden Code-Snippet wird eine Liste aller Kameras abgerufen und durchlaufen:
try { val cameraIdList = cameraManager.cameraIdList // may be empty // iterate over available camera devices. for (cameraId in cameraIdList) { val characteristics = cameraManager.getCameraCharacteristics(cameraId) val cameraLensFacing = characteristics.get(CameraCharacteristics.LENS_FACING) val cameraCapabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) // check if the selected camera device supports basic features // ensures backward compatibility with the original Camera API. val isBackwardCompatible = cameraCapabilities?.contains( CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE ) ?: false // ... } } catch (e: CameraAccessException) { e.message?.let { Log.e(TAG, it) } // ... }
Die Variable cameraLensFacing beschreibt die Richtung, in die die Kamera relativ zum Gerätebildschirm zeigt, und hat einen der folgenden Werte:
CameraMetadata.LENS_FACING_FRONTCameraMetadata.LENS_FACING_BACKCameraMetadata.LENS_FACING_EXTERNAL
Weitere Informationen zur Konfiguration der Kameraausrichtung finden Sie unter CameraCharacteristics.LENS_FACING.
Die Variable cameraCapabilities aus dem vorherigen Codebeispiel enthält Informationen zu verschiedenen Funktionen, z. B. ob die Kamera Standardframes als Ausgabe erzeugen kann (im Gegensatz zu beispielsweise nur Tiefensensordaten). Sie können prüfen, ob CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE eine der aufgeführten Funktionen der Kamera ist. Diese wird als Flag in isBackwardCompatible gespeichert.
Sinnvolle Standardeinstellungen auswählen
In Ihrer App möchten Sie wahrscheinlich standardmäßig eine bestimmte Kamera öffnen (falls verfügbar). Eine Selfie-App öffnet beispielsweise wahrscheinlich die Frontkamera, während eine Augmented-Reality-App möglicherweise mit der Rückkamera startet. Die folgende Funktion gibt die erste Kamera zurück, die in eine bestimmte Richtung zeigt:
fun getFirstCameraIdFacing( cameraManager: CameraManager, facing: Int = CameraMetadata.LENS_FACING_BACK ): String? { try { // Get list of all compatible cameras. val cameraIds = cameraManager.cameraIdList.filter { val characteristics = cameraManager.getCameraCharacteristics(it) val capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) capabilities?.contains( CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE ) ?: false } // Iterate over the list of cameras and return the first one matching desired // lens-facing configuration. cameraIds.forEach { val characteristics = cameraManager.getCameraCharacteristics(it) if (characteristics.get(CameraCharacteristics.LENS_FACING) == facing) { return it } } // If no camera matched desired orientation, return the first one from the list. return cameraIds.firstOrNull() } catch (e: CameraAccessException) { e.message?.let { Log.e(TAG, it) } return null } }
Kamerawechsel aktivieren
In vielen Kamera-Apps können Nutzer zwischen Kameras wechseln:
Viele Geräte haben mehrere Kameras, die in dieselbe Richtung zeigen. Einige haben sogar externe USB-Kameras. Wenn du Nutzern eine Benutzeroberfläche bieten möchtest, über die sie zwischen verschiedenen Kameras wechseln können, wähle die erste verfügbare Kamera für jede mögliche Objektivkonfiguration aus.
Es gibt zwar keine universelle Logik für die Auswahl der nächsten Kamera, aber der folgende Code funktioniert für die meisten Anwendungsfälle:
fun filterCompatibleCameras( cameraIds: Array<String>, cameraManager: CameraManager ): List<String> { return cameraIds.filter { val characteristics = cameraManager.getCameraCharacteristics(it) characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)?.contains( CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE ) ?: false } } fun filterCameraIdsFacing( cameraIds: List<String>, cameraManager: CameraManager, facing: Int ): List<String> { return cameraIds.filter { val characteristics = cameraManager.getCameraCharacteristics(it) characteristics.get(CameraCharacteristics.LENS_FACING) == facing } } fun getNextCameraId(cameraManager: CameraManager, currCameraId: String? = null): String? { // Get all front, back and external cameras in 3 separate lists. val cameraIds = filterCompatibleCameras(cameraManager.cameraIdList, cameraManager) val backCameras = filterCameraIdsFacing( cameraIds, cameraManager, CameraMetadata.LENS_FACING_BACK ) val frontCameras = filterCameraIdsFacing( cameraIds, cameraManager, CameraMetadata.LENS_FACING_FRONT ) val externalCameras = filterCameraIdsFacing( cameraIds, cameraManager, CameraMetadata.LENS_FACING_EXTERNAL ) // The recommended order of iteration is: all external, first back, first front. val allCameras = ( externalCameras + listOf( backCameras.firstOrNull(), frontCameras.firstOrNull() ) ).filterNotNull() // Get the index of the currently selected camera in the list. val cameraIndex = allCameras.indexOf(currCameraId) // The selected camera may not be in the list, for example it could be an // external camera that has been removed by the user. return if (cameraIndex == -1) { // Return the first camera from the list. allCameras.getOrNull(0) } else { // Return the next camera from the list, wrap around if necessary. allCameras.getOrNull((cameraIndex + 1) % allCameras.size) } }
Dieser Code funktioniert für eine große Anzahl von Geräten mit vielen verschiedenen Konfigurationen. Weitere Informationen zur Berücksichtigung von Grenzfällen finden Sie unter CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA.
Kompatible Apps erstellen
Bei Apps, die noch die verworfene Camera API verwenden, hängt die Anzahl der Kameras, die von Camera.getNumberOfCameras() zurückgegeben werden, von der OEM-Implementierung ab. Wenn im System eine logische Multikamera vorhanden ist, wird mit dieser Methode nur eine Kamera für jede logische Kamera und die zugrunde liegende Gruppe physischer Kameras verfügbar gemacht, um die Abwärtskompatibilität der App zu gewährleisten. Verwende die Camera2 API, um alle Kameras zu sehen.
Weitere Hintergrundinformationen zur Kameraausrichtung findest du unter Camera.CameraInfo.orientation.
Im Allgemeinen solltest du die Camera.getCameraInfo() API verwenden, um alle orientations der Kamera abzufragen, und Nutzern, die zwischen Kameras wechseln, nur eine Kamera für jede verfügbare Ausrichtung anzeigen.
Alle Gerätetypen berücksichtigen
Gehe nicht davon aus, dass deine App immer auf einem Mobilgerät mit einer oder zwei Kameras ausgeführt wird. Wähle stattdessen die am besten geeigneten Kameras für die App aus. Wenn du keine bestimmte Kamera benötigst, wähle die erste Kamera aus, die in die gewünschte Richtung zeigt. Wenn die Kamera, die in eine bestimmte Richtung zeigt, nicht verfügbar ist, überlegen Sie, ob der Nutzer seine Fahrt mit einer anderen Kamera fortsetzen kann. Schränke die Verfügbarkeit deiner App auf bestimmten Geräten nicht aufgrund der Kamerahardware ein. Wenn eine externe Kamera angeschlossen ist, bevorzugt der Nutzer diese wahrscheinlich als Standard.