Update 2: Any focus modes apparently don't work
Update 1: Problem seems to be isolated to my Samsung S8 device. It's working on Nexus 5X and Xiaomi phones
I've been trying to make FOCUS_MODE_CONTINUOUS_PICTURE work but to no avail. I've confirmed my device supports continuous auto picture via getSupportedFocusModes(), and not sure why it doesn't work.
Here's my code, continuous auto focus is being set in 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()
}
}
}
Any help would be appreciated. Thanks!