我正在尝试以编程方式检查 Android 智能手机是否具有微距相机。
尝试了
CameraManager
并通过它发现了相机的不同特性。然后找到微距相机的具体阈值,并将条件置于特性上,以找到微距相机在 Android 智能手机中的可用性。因为就我搜索而言,没有直接的方法来找到微距相机。
val cameraManager = context?.getSystemService(Context.CAMERA_SERVICE) as? CameraManager
cameraManager?.cameraIdList?.forEach { cameraId ->
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
val lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
val capabilities =
characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
capabilities?.let {
Log.d("macroCameraLog_2", "isMacroCameraSupported: CAMERA_ID $cameraId")
Log.d("macroCameraLog_2", "isMacroCameraSupported: HARD_WARE_LEVEL $it")
if (it >= CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3) {
Log.d("macroCameraLog_2", "isMacroCameraSupported: TRUE")
}
}
val afModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES)
afModes?.let { modes ->
Log.d("macroCameraLog_3", "isMacroCameraSupported: CAMERA_ID $cameraId")
Log.d(
"macroCameraLog_3",
"isMacroCameraSupported: MODES ${formatCharacteristicValue(modes)}"
)
if (modes.contains(CameraMetadata.CONTROL_AF_MODE_MACRO)) {
Log.d("macroCameraLog_3", "Macro AF mode is supported")
}
if (modes.contains(CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE)) {
Log.d("macroCameraLog_3", "CONTROL_Macro AF mode is supported")
}
}
if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
// Get the minimum focus distance
val minFocusDistance =
characteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)
?: return false
Log.d(
"macroCameraLog",
"isMacroCameraSupported: Min_Focus -> $minFocusDistance"
)
Log.d("macroCameraLog", "isMacroCameraSupported: Camera_ID -> $cameraId")
// Define a threshold for macro capability (e.g., less than or equal to 0.05 meters or 5 cm)
if (minFocusDistance in 0.01..0.05) {
Log.d(
"macroCameraLog",
"isMacroCameraSupported: Min_Focus -> $minFocusDistance"
)
Log.d("macroCameraLog", "isMacroCameraSupported: Camera_ID -> $cameraId")
}
}
// Check if it's a rear camera
if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
// Check for physical cameras in a multi-camera system
val physicalCameraIds = characteristics.physicalCameraIds
if (physicalCameraIds.isNotEmpty()) {
for (physicalCameraId in physicalCameraIds) {
val physicalCharacteristics =
cameraManager.getCameraCharacteristics(physicalCameraId)
val physicalFocalLengths =
physicalCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
val minFocusDistance =
physicalCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)
?: return false
// Define a threshold for macro capability (e.g., less than or equal to 0.05 meters or 5 cm)
Log.d(
"macroCameraLog",
"Physical_isMacroCameraSupported: Camera_ID -> $cameraId"
)
Log.d(
"macroCameraLog",
"Physical_isMacroCameraSupported: Min_Focus -> $minFocusDistance"
)
if (minFocusDistance in 0.01..0.05) {
Log.d(
"macroCameraLog",
"Physical_isMacroCameraSupported: Min_Focus -> $minFocusDistance"
)
Log.d(
"macroCameraLog",
"Physical_isMacroCameraSupported: Camera_ID -> $cameraId"
)
}
physicalFocalLengths?.let { focalLengths ->
for (focalLength in focalLengths) {
// Check for macro lens characteristics
if (focalLength in 1.0..2.0) {
// Macro lens found in a multi-camera system
// return true
}
}
}
}
}
}
}
我想出的唯一可能的解决方案是根据焦距、硬件水平、最小焦距和自动对焦模式等特定阈值检查微距相机的各种属性。但我没有找到任何可靠的解决方案来检查设备是否有微距摄像头。
通过检查各种相机特性(例如焦距、自动对焦模式、硬件级别和最小焦距)来确定设备是否具有微距相机,您就走在正确的道路上。由于Android不提供直接的API来识别微距相机,因此使用这些参数是最好的方法。但是,有几种方法可以改进微距相机的检测机制
fun isMacroCameraSupported(context: Context): Boolean {
val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
cameraManager.cameraIdList.forEach { cameraId ->
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
val lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
if (lensFacing != CameraCharacteristics.LENS_FACING_BACK) {
return@forEach
}
val afModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES)
if (afModes != null && afModes.contains(CameraMetadata.CONTROL_AF_MODE_MACRO)) {
Log.d("macroCameraLog", "Macro AF mode is supported for camera ID $cameraId")
}
val minFocusDistance = characteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)
if (minFocusDistance != null && minFocusDistance in 0.01..0.05) {
Log.d("macroCameraLog", "Macro capability found based on focus distance for camera ID $cameraId")
}
val focalLengths = characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
focalLengths?.let {
for (focalLength in focalLengths) {
if (focalLength in 1.0..2.0) {
Log.d("macroCameraLog", "Macro lens found based on focal length for camera ID $cameraId")
return true // A macro camera is detected
}
}
}
val hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
if (hardwareLevel != null && hardwareLevel >= CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3) {
Log.d("macroCameraLog", "High-end camera hardware detected for camera ID $cameraId")
}
val physicalCameraIds = characteristics.physicalCameraIds
if (physicalCameraIds.isNotEmpty()) {
physicalCameraIds.forEach { physicalCameraId ->
val physicalCharacteristics = cameraManager.getCameraCharacteristics(physicalCameraId)
val physicalFocalLengths = physicalCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
physicalFocalLengths?.forEach { focalLength ->
if (focalLength in 1.0..2.0) {
Log.d("macroCameraLog", "Macro lens detected in multi-camera system for physical camera ID $physicalCameraId")
return true
}
}
}
}
}
return false // if false -> No macro camera found
}
可以试试这个