Los modos de enfoque automático no funcionan en Samsung S8

Actualización 2: aparentemente, los modos de enfoque no funcionan

Actualización 1: el problema parece estar aislado en mi dispositivo Samsung S8. Está funcionando en teléfonos Nexus 5X y Xiaomi

He intentado hacer que FOCUS_MODE_CONTINUOUS_PICTURE funcione, pero fue en vano. Confirmé que mi dispositivo admite imágenes automáticas continuas a través de getSupportedFocusModes() y no estoy seguro de por qué no funciona.

Aquí está mi código, el enfoque automático continuo se establece en startCamera() :

 class CaptureReceiptFragment : Fragment(), CaptureReceiptContract.View { private val MY_PERMISSIONS_REQUEST_CAMERA = 1 private var camera: Camera? = null private var hasCameraPermission: Boolean? = null private lateinit var preview: CameraPreview override var presenter: CaptureReceiptContract.Presenter? = null private val picture = Camera.PictureCallback { data, camera -> val pictureStorageDir = File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), getAppName()) presenter?.saveReceipt(pictureStorageDir, data) } override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val root = inflater!!.inflate(R.layout.capturereceipt_frag, container, false) return root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) hasCameraPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED if (hasCameraPermission!!) { showCameraErrorMsg() } else { capturereceipt_button_capturereceipt.setOnClickListener { captureReceipt() } startCameraOnCreate() } } override fun onResume() { super.onResume() presenter?.start() if (hasCameraPermission!!) { showCameraErrorMsg() } else { startCamera() setCameraRotation() } } override fun onPause() { super.onPause() camera?.release() camera = null } override fun gotoReceiptList() { //TODO } override fun goBack() { //TODO } private fun startCameraOnCreate() { preview = CameraPreview(context) capturereceipt_framelayout_viewfinder.addView(preview) startCamera() } private fun startCamera() { if (camera == null) { camera = Camera.open() if (camera == null) { showCameraErrorMsg() } else { val params: Camera.Parameters? = camera!!.parameters if (params!!.getSupportedFocusModes() .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { params.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE; } camera?.parameters = params preview.camera = camera capturereceipt_textview_cameraerrormsg.visibility = View.GONE capturereceipt_framelayout_viewfinder.visibility = View.VISIBLE } } } private fun showCameraErrorMsg() { capturereceipt_textview_cameraerrormsg.visibility = View.VISIBLE capturereceipt_framelayout_viewfinder.visibility = View.GONE } override fun captureReceipt() { camera?.takePicture(null, null, picture) } private fun getOutputPictureFile(): File? { val appName = getAppName() val pictureStorageDir = File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), appName) if (!pictureStorageDir.exists()) { pictureStorageDir.mkdirs() } val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) return File(pictureStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg") } private fun getAppName(): String { val appInfo = context.getApplicationInfo() val stringId = appInfo.labelRes if (stringId == 0) { return appInfo.nonLocalizedLabel.toString() } else { return this.getString(stringId) } } fun setCameraDisplayOrientation() { val info = Camera.CameraInfo() Camera.getCameraInfo(CAMERA_FACING_BACK, info) val rotation = activity.windowManager.defaultDisplay.rotation var degrees = 0 when (rotation) { Surface.ROTATION_0 -> degrees = 0 Surface.ROTATION_90 -> degrees = 90 Surface.ROTATION_180 -> degrees = 180 Surface.ROTATION_270 -> degrees = 270 } var result: Int if (info.facing == CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360 result = (360 - result) % 360 // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360 } camera?.setDisplayOrientation(result); } fun setCameraRotation() { val info: Camera.CameraInfo = Camera.CameraInfo() Camera.getCameraInfo(CAMERA_FACING_BACK, info) val rotation = activity.windowManager.defaultDisplay.rotation var degrees = 0 when(rotation) { Surface.ROTATION_0 -> degrees = 0 Surface.ROTATION_90 -> degrees = 90 Surface.ROTATION_180 -> degrees = 180 Surface.ROTATION_270 -> degrees = 270 } val rotate = (info.orientation - degrees + 360) % 360 camera?.setDisplayOrientation(rotate) val params: Camera.Parameters = camera!!.parameters params.setRotation(rotate) camera?.parameters = params } companion object { @JvmStatic fun newInstance(): CaptureReceiptFragment { return CaptureReceiptFragment() } } 

}

Cualquier ayuda sería apreciada. ¡Gracias!

Finalmente me di count: parece que los parameters del modo de enfoque automático se deben establecer de forma diferente en Samsung S8.

Esto es lo que intenté que falló:

  1. Configuración de los modos de enfoque automático (AUTO, CONTINUOUS_PICTURE, INFINITY) antes de comenzar la vista previa
  2. Scheduled camera.autoFocus() para ejecutar cada segundo de forma inmediata después de la camera.open

Esto es lo que intenté que funcionó:

  1. Poner foco continuo o camera.autoFocus() en un button onClick
  2. Retrasando la configuration de enfoque continuo por 1 segundo después de camera.open() <- esto es lo que resolvió mi problema

Mi código para el n. ° 2:

 private val autoFocusExecutor = ScheduledThreadPoolExecutor(1) fun startCamera() { if (camera == null) { camera = Camera.open() if (camera == null) { showCameraErrorMsg() } else { preview.camera = camera capturereceipt_textview_cameraerrormsg.visibility = View.GONE capturereceipt_framelayout_viewfinder.visibility = View.VISIBLE autoFocusExecutor.schedule(Sc{ val params: Camera.Parameters = camera!!.parameters if (params.getSupportedFocusModes() .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { //TODO: Auto focus not working params.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE } camera?.parameters = params }, 1000, TimeUnit.MILLISECONDS) } } }