Hinweis:Diese Seite bezieht sich auf das Paket Camera2. Sofern Ihre App keine bestimmten Low-Level-Funktionen von Camera2 erfordert, empfehlen wir die Verwendung von CameraX. CameraX und 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- und Rückseite oder auf beiden Seiten. Jede Linse kann einzigartige Funktionen haben, z. B. Serienaufnahme, manuelle Steuerung oder Bewegungserkennung. Eine App zum Einreichen von Schecks verwendet möglicherweise nur die erste Rückkamera, während eine Social-Media-App standardmäßig eine Frontkamera verwendet. Nutzer haben jedoch die Möglichkeit, zwischen allen verfügbaren Objektiven zu wechseln. Er kann sich auch ihre Entscheidungen merken.
Auf dieser Seite erfahren Sie, wie Sie Kameraobjektive und ihre Funktionen auflisten, damit Sie in Ihrer App entscheiden können, welches Objektiv in einer bestimmten Situation verwendet werden soll. Das folgende Code-Snippet ruft eine Liste aller Kameras ab und iteriert diese:
Kotlin
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) } ... }
Java
try { String[] cameraIdList = cameraManager.getCameraIdList(); // may be empty // iterate over available camera devices for (String cameraId : cameraIdList) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId); int cameraLensFacing = characteristics.get(CameraCharacteristics.LENS_FACING); int[] cameraCapabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); // check if the selected camera device supports basic features // ensures backward compatibility with the original Camera API boolean isBackwardCompatible = false; for (int capability : cameraCapabilities) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) { isBackwardCompatible = true; break; } } ... } } catch (CameraAccessException e) { Log.e(TAG, e.getMessage()); ... }
Die Variable cameraLensFacing
beschreibt die Richtung, in die die Kamera relativ zum Gerätebildschirm gerichtet ist. Sie hat einen der folgenden Werte:
CameraMetadata.LENS_FACING_FRONT
CameraMetadata.LENS_FACING_BACK
CameraMetadata.LENS_FACING_EXTERNAL
Weitere Informationen zur Konfiguration mit der Oberseite des Objektivs finden Sie unter CameraCharacteristics.LENS_FACING
.
Die Variable cameraCapabilities
aus dem vorherigen Codebeispiel enthält Informationen zu verschiedenen Funktionen, einschließlich der Frage, 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, die als Flag in isBackwardCompatible
gespeichert ist.
Intelligente Standardeinstellungen auswählen
In Ihrer App möchten Sie wahrscheinlich eine bestimmte Kamera standardmäßig öffnen (falls verfügbar). Bei einer Selfie-App wird beispielsweise wahrscheinlich die Frontkamera geöffnet, während bei einer Augmented-Reality-App die Rückkamera verwendet wird. Mit der folgenden Funktion wird die erste Kamera zurückgegeben, die in eine bestimmte Richtung gerichtet ist:
Kotlin
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) } } }
Java
public String getFirstCameraIdFacing(CameraManager cameraManager, @Nullable Integer facing) { if (facing == null) facing = CameraMetadata.LENS_FACING_BACK; String cameraId = null; try { // Get a list of all compatible cameras String[] cameraIdList = cameraManager.getCameraIdList(); // Iterate over the list of cameras and return the first one matching desired // lens-facing configuration and backward compatibility for (String id : cameraIdList) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); int[] capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); for (int capability : capabilities) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE && characteristics.get(CameraCharacteristics.LENS_FACING).equals(facing)) { cameraId = id; break; } } } // If no camera matches the desired orientation, return the first one from the list cameraId = cameraIdList[0]; } catch (CameraAccessException e) { Log.e(TAG, "getFirstCameraIdFacing: " + e.getMessage()); } return cameraId; }
Kamerawechsel aktivieren
Bei vielen Kamera-Apps haben Nutzer die Möglichkeit, zwischen den Kameras zu wechseln:
![](https://developer.android.com/static/images/training/camera/camera2/camera-enumeration-1.png?authuser=6&hl=de)
Viele Geräte haben mehrere Kameras, die in dieselbe Richtung zeigen. Einige haben sogar externe USB-Kameras. Wenn Sie Nutzern eine Benutzeroberfläche geben möchten, mit der sie zwischen verschiedenen nach außen gerichteten Kameras wechseln können, wählen Sie für jede mögliche Konfiguration mit Objektivausrichtung die erste verfügbare Kamera aus.
Es gibt zwar keine universelle Logik für die Auswahl der nächsten Kamera, der folgende Code funktioniert jedoch für die meisten Anwendungsfälle:
Kotlin
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) } }
Java
public List<String> filterCompatibleCameras(CameraManager cameraManager, String[] cameraIds) { final List<String> compatibleCameras = new ArrayList<>(); try { for (String id : cameraIds) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); int[] capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); for (int capability : capabilities) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) { compatibleCameras.add(id); } } } } catch (CameraAccessException e) { Log.e(TAG, "filterCompatibleCameras: " + e.getMessage()); } return compatibleCameras; } public List<String> filterCameraIdsFacing(CameraManager cameraManager, List<String> cameraIds, int lensFacing) { final List<String> compatibleCameras = new ArrayList<>(); try { for (String id : cameraIds) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); if (characteristics.get(CameraCharacteristics.LENS_FACING) == lensFacing) { compatibleCameras.add(id); } } } catch (CameraAccessException e) { Log.e(TAG, "filterCameraIdsFacing: " + e.getMessage()); } return compatibleCameras; } public String getNextCameraId(CameraManager cameraManager, @Nullable String currentCameraId) { String nextCameraId = null; try { // Get all front, back, and external cameras in 3 separate lists List<String> compatibleCameraIds = filterCompatibleCameras(cameraManager, cameraManager.getCameraIdList()); List<String> backCameras = filterCameraIdsFacing(cameraManager, compatibleCameraIds, CameraMetadata.LENS_FACING_BACK); List<String> frontCameras = filterCameraIdsFacing(cameraManager, compatibleCameraIds, CameraMetadata.LENS_FACING_FRONT); List<String>externalCameras = filterCameraIdsFacing(cameraManager, compatibleCameraIds, CameraMetadata.LENS_FACING_EXTERNAL); // The recommended order of iteration is: all external, first back, first front List<String> allCameras = new ArrayList<>(externalCameras); if (!backCameras.isEmpty()) allCameras.add(backCameras.get(0)); if (!frontCameras.isEmpty()) allCameras.add(frontCameras.get(0)); // Get the index of the currently selected camera in the list int cameraIndex = allCameras.indexOf(currentCameraId); // The selected camera may not be in the list, for example it could be an // external camera that has been removed by the user if (cameraIndex == -1) { // Return the first camera from the list nextCameraId = !allCameras.isEmpty() ? allCameras.get(0) : null; else { if (!allCameras.isEmpty()) { // Return the next camera from the list, wrap around if necessary nextCameraId = allCameras.get((cameraIndex + 1) % allCameras.size()); } } } catch (CameraAccessException e) { Log.e(TAG, "getNextCameraId: " + e.getMessage()); } return nextCameraId; }
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 Anwendungen, die noch die eingestellte Camera API verwenden, hängt die Anzahl der von Camera.getNumberOfCameras()
zurückgegebenen Kameras von der Implementierung des OEMs ab. Wenn das System ein logisches Mehrfachkamerasystem enthält, wird zur Aufrechterhaltung der Abwärtskompatibilität der Anwendung bei dieser Methode nur eine Kamera für jede logische Kamera und die zugrunde liegende physische Kamerasgruppe freigegeben.
Verwende die Camera2 API, um alle Kameras anzuzeigen.
Weitere Hintergrundinformationen zu Kameraausrichtungen finden Sie unter Camera.CameraInfo.orientation
.
Im Allgemeinen kannst du die Camera.getCameraInfo()
API verwenden, um alle orientation
-Kameras abzufragen. Nutzer, die zwischen Kameras wechseln, jeweils nur eine Kamera für jede verfügbare Ausrichtung verfügbar machen.
Für alle Gerätetypen geeignet
Gehen Sie nicht davon aus, dass Ihre App immer auf einem Handheld-Gerät mit ein oder zwei Kameras ausgeführt wird. Wählen Sie stattdessen die am besten geeigneten Kameras für die App aus. Wenn Sie keine bestimmte Kamera benötigen, wählen Sie die erste Kamera aus, die in die gewünschte Richtung zeigt. Wenn eine externe Kamera angeschlossen ist, gehen Sie möglicherweise davon aus, dass der Nutzer sie als Standardkamera bevorzugt.