fix deprecated getter use; fix leaking of display listener instances
Showing
1 changed file
with
36 additions
and
15 deletions
| @@ -26,6 +26,7 @@ import android.util.Size | @@ -26,6 +26,7 @@ import android.util.Size | ||
| 26 | import android.hardware.display.DisplayManager | 26 | import android.hardware.display.DisplayManager |
| 27 | import android.view.WindowManager | 27 | import android.view.WindowManager |
| 28 | import android.content.Context | 28 | import android.content.Context |
| 29 | +import android.os.Build | ||
| 29 | 30 | ||
| 30 | 31 | ||
| 31 | class MobileScanner( | 32 | class MobileScanner( |
| @@ -43,6 +44,7 @@ class MobileScanner( | @@ -43,6 +44,7 @@ class MobileScanner( | ||
| 43 | private var scanner = BarcodeScanning.getClient() | 44 | private var scanner = BarcodeScanning.getClient() |
| 44 | private var lastScanned: List<String?>? = null | 45 | private var lastScanned: List<String?>? = null |
| 45 | private var scannerTimeout = false | 46 | private var scannerTimeout = false |
| 47 | + private var displayListener: MobileScannerDisplayListener? = null | ||
| 46 | 48 | ||
| 47 | /// Configurable variables | 49 | /// Configurable variables |
| 48 | var scanWindow: List<Float>? = null | 50 | var scanWindow: List<Float>? = null |
| @@ -171,11 +173,22 @@ class MobileScanner( | @@ -171,11 +173,22 @@ class MobileScanner( | ||
| 171 | } | 173 | } |
| 172 | 174 | ||
| 173 | // Return the best resolution for the actual device orientation. | 175 | // Return the best resolution for the actual device orientation. |
| 174 | - // By default camera set its resolution to width 480 and height 640 which is too low for ML KIT. | ||
| 175 | - // If we return an higher resolution than device can handle, camera package take the most relevant one available. | ||
| 176 | - // Resolution set must take care of device orientation to preserve aspect ratio. | ||
| 177 | - private fun getResolution(windowManager: WindowManager, cameraResolution: Size): Size { | ||
| 178 | - val rotation = windowManager.defaultDisplay.rotation | 176 | + // |
| 177 | + // By default the resolution is 480x640, which is too low for ML Kit. | ||
| 178 | + // If the given resolution is not supported by the display, | ||
| 179 | + // the closest available resolution is used. | ||
| 180 | + // | ||
| 181 | + // The resolution should be adjusted for the display rotation, to preserve the aspect ratio. | ||
| 182 | + @Suppress("deprecation") | ||
| 183 | + private fun getResolution(cameraResolution: Size): Size { | ||
| 184 | + val rotation = if (Build.VERSION.SDK_INT >= 30) { | ||
| 185 | + activity.applicationContext.display!!.rotation | ||
| 186 | + } else { | ||
| 187 | + val windowManager = activity.applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager | ||
| 188 | + | ||
| 189 | + windowManager.defaultDisplay.rotation | ||
| 190 | + } | ||
| 191 | + | ||
| 179 | val widthMaxRes = cameraResolution.width | 192 | val widthMaxRes = cameraResolution.width |
| 180 | val heightMaxRes = cameraResolution.height | 193 | val heightMaxRes = cameraResolution.height |
| 181 | 194 | ||
| @@ -187,7 +200,6 @@ class MobileScanner( | @@ -187,7 +200,6 @@ class MobileScanner( | ||
| 187 | return targetResolution | 200 | return targetResolution |
| 188 | } | 201 | } |
| 189 | 202 | ||
| 190 | - | ||
| 191 | /** | 203 | /** |
| 192 | * Start barcode scanning by initializing the camera and barcode scanner. | 204 | * Start barcode scanning by initializing the camera and barcode scanner. |
| 193 | */ | 205 | */ |
| @@ -253,19 +265,21 @@ class MobileScanner( | @@ -253,19 +265,21 @@ class MobileScanner( | ||
| 253 | val analysisBuilder = ImageAnalysis.Builder() | 265 | val analysisBuilder = ImageAnalysis.Builder() |
| 254 | .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) | 266 | .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) |
| 255 | val displayManager = activity.applicationContext.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager | 267 | val displayManager = activity.applicationContext.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager |
| 256 | - val windowManager = activity.applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager | ||
| 257 | 268 | ||
| 258 | if (cameraResolution != null) { | 269 | if (cameraResolution != null) { |
| 270 | + // TODO: migrate to ResolutionSelector with ResolutionStrategy when upgrading to camera 1.3.0 | ||
| 259 | // Override initial resolution | 271 | // Override initial resolution |
| 260 | - analysisBuilder.setTargetResolution(getResolution(windowManager, cameraResolution)) | ||
| 261 | - // Listen future orientation change to apply the custom resolution | ||
| 262 | - displayManager.registerDisplayListener(object : DisplayManager.DisplayListener { | ||
| 263 | - override fun onDisplayAdded(displayId: Int) {} | ||
| 264 | - override fun onDisplayRemoved(displayId: Int) {} | ||
| 265 | - override fun onDisplayChanged(displayId: Int) { | ||
| 266 | - analysisBuilder.setTargetResolution(getResolution(windowManager, cameraResolution)) | 272 | + analysisBuilder.setTargetResolution(getResolution(cameraResolution)) |
| 273 | + | ||
| 274 | + if (displayListener == null) { | ||
| 275 | + displayListener = MobileScannerDisplayListener { | ||
| 276 | + analysisBuilder.setTargetResolution(getResolution(cameraResolution)) | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + displayManager.registerDisplayListener( | ||
| 280 | + displayListener, null, | ||
| 281 | + ) | ||
| 267 | } | 282 | } |
| 268 | - }, null) | ||
| 269 | } | 283 | } |
| 270 | 284 | ||
| 271 | val analysis = analysisBuilder.build().apply { setAnalyzer(executor, captureOutput) } | 285 | val analysis = analysisBuilder.build().apply { setAnalyzer(executor, captureOutput) } |
| @@ -316,6 +330,13 @@ class MobileScanner( | @@ -316,6 +330,13 @@ class MobileScanner( | ||
| 316 | throw AlreadyStopped() | 330 | throw AlreadyStopped() |
| 317 | } | 331 | } |
| 318 | 332 | ||
| 333 | + if (displayListener != null) { | ||
| 334 | + val displayManager = activity.applicationContext.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager | ||
| 335 | + | ||
| 336 | + displayManager.unregisterDisplayListener(displayListener) | ||
| 337 | + displayListener = null | ||
| 338 | + } | ||
| 339 | + | ||
| 319 | val owner = activity as LifecycleOwner | 340 | val owner = activity as LifecycleOwner |
| 320 | camera?.cameraInfo?.torchState?.removeObservers(owner) | 341 | camera?.cameraInfo?.torchState?.removeObservers(owner) |
| 321 | cameraProvider?.unbindAll() | 342 | cameraProvider?.unbindAll() |
-
Please register or login to post a comment