Navaron Bracke

fix deprecated getter use; fix leaking of display listener instances

... ... @@ -26,6 +26,7 @@ import android.util.Size
import android.hardware.display.DisplayManager
import android.view.WindowManager
import android.content.Context
import android.os.Build
class MobileScanner(
... ... @@ -43,6 +44,7 @@ class MobileScanner(
private var scanner = BarcodeScanning.getClient()
private var lastScanned: List<String?>? = null
private var scannerTimeout = false
private var displayListener: MobileScannerDisplayListener? = null
/// Configurable variables
var scanWindow: List<Float>? = null
... ... @@ -171,11 +173,22 @@ class MobileScanner(
}
// Return the best resolution for the actual device orientation.
// By default camera set its resolution to width 480 and height 640 which is too low for ML KIT.
// If we return an higher resolution than device can handle, camera package take the most relevant one available.
// Resolution set must take care of device orientation to preserve aspect ratio.
private fun getResolution(windowManager: WindowManager, cameraResolution: Size): Size {
val rotation = windowManager.defaultDisplay.rotation
//
// By default the resolution is 480x640, which is too low for ML Kit.
// If the given resolution is not supported by the display,
// the closest available resolution is used.
//
// The resolution should be adjusted for the display rotation, to preserve the aspect ratio.
@Suppress("deprecation")
private fun getResolution(cameraResolution: Size): Size {
val rotation = if (Build.VERSION.SDK_INT >= 30) {
activity.applicationContext.display!!.rotation
} else {
val windowManager = activity.applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.rotation
}
val widthMaxRes = cameraResolution.width
val heightMaxRes = cameraResolution.height
... ... @@ -187,7 +200,6 @@ class MobileScanner(
return targetResolution
}
/**
* Start barcode scanning by initializing the camera and barcode scanner.
*/
... ... @@ -253,19 +265,21 @@ class MobileScanner(
val analysisBuilder = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
val displayManager = activity.applicationContext.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val windowManager = activity.applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
if (cameraResolution != null) {
// TODO: migrate to ResolutionSelector with ResolutionStrategy when upgrading to camera 1.3.0
// Override initial resolution
analysisBuilder.setTargetResolution(getResolution(windowManager, cameraResolution))
// Listen future orientation change to apply the custom resolution
displayManager.registerDisplayListener(object : DisplayManager.DisplayListener {
override fun onDisplayAdded(displayId: Int) {}
override fun onDisplayRemoved(displayId: Int) {}
override fun onDisplayChanged(displayId: Int) {
analysisBuilder.setTargetResolution(getResolution(windowManager, cameraResolution))
analysisBuilder.setTargetResolution(getResolution(cameraResolution))
if (displayListener == null) {
displayListener = MobileScannerDisplayListener {
analysisBuilder.setTargetResolution(getResolution(cameraResolution))
}
}, null)
displayManager.registerDisplayListener(
displayListener, null,
)
}
}
val analysis = analysisBuilder.build().apply { setAnalyzer(executor, captureOutput) }
... ... @@ -316,6 +330,13 @@ class MobileScanner(
throw AlreadyStopped()
}
if (displayListener != null) {
val displayManager = activity.applicationContext.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
displayManager.unregisterDisplayListener(displayListener)
displayListener = null
}
val owner = activity as LifecycleOwner
camera?.cameraInfo?.torchState?.removeObservers(owner)
cameraProvider?.unbindAll()
... ...