Skip to content

Commit fe01295

Browse files
authored
fix: Fix Android focus not using correct focus point (mrousavy#958)
This commit fixes mrousavy#758. I was having the same issue and looked into it a bit. I found [this StackOverflow answer](https://stackoverflow.com/a/60585382) which described a solution to the same problem. Rather than manually calculate the focus point, we can get the PreviewView to do it for us. This fixes the issue because the PreviewView factors in any scaling or resizing of the view on the screen, which we weren't doing before. The only potential issue is that this needs to run on the UI thread (which is what the `withContext` is doing), but I've tested it with frame processors enabled and disabled, and have found no issues in either case.
1 parent a7e66ed commit fe01295

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

android/src/main/java/com/mrousavy/camera/CameraView+Focus.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.mrousavy.camera
22

33
import androidx.camera.core.FocusMeteringAction
4-
import androidx.camera.core.SurfaceOrientedMeteringPointFactory
54
import com.facebook.react.bridge.ReadableMap
65
import kotlinx.coroutines.guava.await
6+
import kotlinx.coroutines.withContext
77
import java.util.concurrent.TimeUnit
88

99
suspend fun CameraView.focus(pointMap: ReadableMap) {
@@ -16,8 +16,11 @@ suspend fun CameraView.focus(pointMap: ReadableMap) {
1616
val x = pointMap.getDouble("x") * dpi
1717
val y = pointMap.getDouble("y") * dpi
1818

19-
val factory = SurfaceOrientedMeteringPointFactory(this.width.toFloat(), this.height.toFloat())
20-
val point = factory.createPoint(x.toFloat(), y.toFloat())
19+
// Getting the point from the previewView needs to be run on the UI thread
20+
val point = withContext(coroutineScope.coroutineContext) {
21+
previewView.meteringPointFactory.createPoint(x.toFloat(), y.toFloat());
22+
}
23+
2124
val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF or FocusMeteringAction.FLAG_AE)
2225
.setAutoCancelDuration(5, TimeUnit.SECONDS) // auto-reset after 5 seconds
2326
.build()

android/src/main/java/com/mrousavy/camera/CameraView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class CameraView(context: Context, private val frameProcessorThread: ExecutorSer
121121
private val cameraExecutor = Executors.newSingleThreadExecutor()
122122
internal val takePhotoExecutor = Executors.newSingleThreadExecutor()
123123
internal val recordVideoExecutor = Executors.newSingleThreadExecutor()
124-
private var coroutineScope = CoroutineScope(Dispatchers.Main)
124+
internal var coroutineScope = CoroutineScope(Dispatchers.Main)
125125

126126
internal var camera: Camera? = null
127127
internal var imageCapture: ImageCapture? = null

0 commit comments

Comments
 (0)