Not: Bu sayfa, Kamera2 paketiyle ilgilidir. Uygulamanız Camera2'nin belirli, alt düzey özelliklerini gerektirmiyorsa KameraX'i kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümleri destekler.
Birçok modern Android cihazın ön, arka veya her iki tarafında iki veya daha fazla kamera bulunur. Her lensin; seri çekim, manuel kontrol veya hareket izleme gibi benzersiz becerileri olabilir. Çekleri yatırmak için kullanılan bir uygulama yalnızca arka yüzdeki ilk kamerayı kullanabilirken bir sosyal medya uygulamasında varsayılan olarak ön kamera kullanılabilir, ancak kullanıcılara mevcut tüm objektifler arasında geçiş yapma seçeneği sunulur. Ayrıca kullanıcının seçimlerini de hatırlayabilir.
Bu sayfada, uygulamanızda hangi lensi kullanacağınıza karar verebilmeniz için kamera lenslerinin ve özelliklerinin nasıl listeleneceği ele alınmaktadır. Aşağıdaki kod snippet'i tüm kameraların bir listesini alır ve bunlar üzerinde yinelemeler yapar:
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()); ... }
cameraLensFacing
değişkeni, kameranın cihaz ekranına göre baktığı yönü tanımlar ve aşağıdaki değerlerden birine sahiptir:
CameraMetadata.LENS_FACING_FRONT
CameraMetadata.LENS_FACING_BACK
CameraMetadata.LENS_FACING_EXTERNAL
Lense yönelik yapılandırma hakkında daha fazla bilgi için CameraCharacteristics.LENS_FACING
bölümüne bakın.
Önceki kod örneğindeki cameraCapabilities
değişkeni, kameranın çıkış olarak standart kareler üretip üretemeyeceği (örneğin, yalnızca derinlik sensörü verileri yerine) dahil olmak üzere çeşitli özelliklerle ilgili bilgiler içerir. CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
özelliğinin, isBackwardCompatible
içinde bayrak olarak depolanan kameranın listelenen özelliklerinden
biri olup olmadığına bakabilirsiniz.
Makul varsayılanlar seçin
Uygulamanızda varsayılan olarak belirli bir kamerayı açmak istersiniz (kullanılabiliyorsa). Örneğin, bir selfie uygulaması büyük olasılıkla ön kamerayı açarken, bir artırılmış gerçeklik uygulaması arka kamerayla başlayabilir. Aşağıdaki işlev belirli bir yöne bakan ilk kamerayı döndürür:
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; }
Kamera değiştirmeyi etkinleştir
Birçok kamera uygulaması, kullanıcılara kameralar arasında geçiş yapma seçeneği sunar:
Birçok cihazda aynı yöne bakan birden fazla kamera bulunur. Bazılarının harici USB kameraları da vardır. Kullanıcılara, farklı kameralar arasında geçiş yapmalarına olanak tanıyan bir kullanıcı arayüzü sağlamak amacıyla olası her objektif yapılandırması için kullanılabilir ilk kamerayı seçin.
Bir sonraki kamerayı seçmek için evrensel bir mantık olmasa da aşağıdaki kod çoğu kullanım alanında işe yarar:
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; }
Bu kod, birçok farklı yapılandırmaya sahip çok sayıda cihazda kullanılabilir. Uç durumların hesaba katılması hakkında daha fazla bilgi için CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
bölümüne bakın.
Uyumlu uygulamalar oluşturma
Hâlâ kullanımdan kaldırılan Camera API'yi kullanan uygulamalarda Camera.getNumberOfCameras()
tarafından iade edilen kamera sayısı OEM uygulamasına bağlıdır. Sistemde mantıksal bir çok kamera varsa uygulamanın geriye dönük uyumluluğunu sağlamak amacıyla bu yöntem, her mantıksal kamera ve altındaki fiziksel kamera grubu için yalnızca bir kamera gösterir.
Tüm kameraları görmek için Camera2 API'sini kullanın.
Kamera yönleri hakkında daha fazla arka plan bilgisi için Camera.CameraInfo.orientation
bölümüne bakın.
Genel olarak, tüm kameraları orientation
sorgulamak için Camera.getCameraInfo()
API'yi kullanın ve kameralar arasında geçiş yapan kullanıcılara mevcut her yön için yalnızca bir kamera gösterin.
Tüm cihaz türlerini karşılar
Uygulamanızın her zaman bir veya iki kamerası olan bir avuç içi cihazda çalıştığını varsaymayın. Bunun yerine, uygulama için en uygun kameraları seçin. Belirli bir kameraya ihtiyacınız yoksa istediğiniz yöne bakan ilk kamerayı seçin. Harici bir kamera bağlıysa, kullanıcının varsayılan olarak kamerayı tercih ettiğini varsayabilirsiniz.