Julian Steenbakker

bug: fix pause not working correctly on android

@@ -49,6 +49,7 @@ class MobileScanner( @@ -49,6 +49,7 @@ class MobileScanner(
49 /// Internal variables 49 /// Internal variables
50 private var cameraProvider: ProcessCameraProvider? = null 50 private var cameraProvider: ProcessCameraProvider? = null
51 private var camera: Camera? = null 51 private var camera: Camera? = null
  52 + private var cameraSelector: CameraSelector? = null
52 private var preview: Preview? = null 53 private var preview: Preview? = null
53 private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null 54 private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null
54 private var scanner: BarcodeScanner? = null 55 private var scanner: BarcodeScanner? = null
@@ -61,6 +62,7 @@ class MobileScanner( @@ -61,6 +62,7 @@ class MobileScanner(
61 private var detectionSpeed: DetectionSpeed = DetectionSpeed.NO_DUPLICATES 62 private var detectionSpeed: DetectionSpeed = DetectionSpeed.NO_DUPLICATES
62 private var detectionTimeout: Long = 250 63 private var detectionTimeout: Long = 250
63 private var returnImage = false 64 private var returnImage = false
  65 + private var isPaused = false
64 66
65 companion object { 67 companion object {
66 /** 68 /**
@@ -250,7 +252,22 @@ class MobileScanner( @@ -250,7 +252,22 @@ class MobileScanner(
250 this.detectionTimeout = detectionTimeout 252 this.detectionTimeout = detectionTimeout
251 this.returnImage = returnImage 253 this.returnImage = returnImage
252 254
253 - if (camera?.cameraInfo != null && preview != null && textureEntry != null) { 255 + if (camera?.cameraInfo != null && preview != null && textureEntry != null && !isPaused) {
  256 +
  257 + // TODO: resume here for seamless transition
  258 +// if (isPaused) {
  259 +// resumeCamera()
  260 +// mobileScannerStartedCallback(
  261 +// MobileScannerStartParameters(
  262 +// if (portrait) width else height,
  263 +// if (portrait) height else width,
  264 +// currentTorchState,
  265 +// textureEntry!!.id(),
  266 +// numberOfCameras ?: 0
  267 +// )
  268 +// )
  269 +// return
  270 +// }
254 mobileScannerErrorCallback(AlreadyStarted()) 271 mobileScannerErrorCallback(AlreadyStarted())
255 272
256 return 273 return
@@ -353,6 +370,7 @@ class MobileScanner( @@ -353,6 +370,7 @@ class MobileScanner(
353 preview, 370 preview,
354 analysis 371 analysis
355 ) 372 )
  373 + cameraSelector = cameraPosition
356 } catch(exception: Exception) { 374 } catch(exception: Exception) {
357 mobileScannerErrorCallback(NoCamera()) 375 mobileScannerErrorCallback(NoCamera())
358 376
@@ -410,25 +428,39 @@ class MobileScanner( @@ -410,25 +428,39 @@ class MobileScanner(
410 * Pause barcode scanning. 428 * Pause barcode scanning.
411 */ 429 */
412 fun pause() { 430 fun pause() {
413 - if (isPaused()) { 431 + if (isPaused) {
414 throw AlreadyPaused() 432 throw AlreadyPaused()
415 } else if (isStopped()) { 433 } else if (isStopped()) {
416 throw AlreadyStopped() 434 throw AlreadyStopped()
417 } 435 }
418 436
419 - releaseCamera() 437 + pauseCamera()
420 } 438 }
421 439
422 /** 440 /**
423 * Stop barcode scanning. 441 * Stop barcode scanning.
424 */ 442 */
425 fun stop() { 443 fun stop() {
426 - if (!isPaused() && isStopped()) { 444 + if (!isPaused && isStopped()) {
427 throw AlreadyStopped() 445 throw AlreadyStopped()
428 } 446 }
429 447
430 releaseCamera() 448 releaseCamera()
431 - releaseTexture() 449 + }
  450 +
  451 + private fun pauseCamera() {
  452 + // Pause camera by unbinding all use cases
  453 + cameraProvider?.unbindAll()
  454 + isPaused = true
  455 + }
  456 +
  457 + private fun resumeCamera() {
  458 + // Resume camera by rebinding use cases
  459 + cameraProvider?.let { provider ->
  460 + val owner = activity as LifecycleOwner
  461 + cameraSelector?.let { provider.bindToLifecycle(owner, it, preview) }
  462 + }
  463 + isPaused = false
432 } 464 }
433 465
434 private fun releaseCamera() { 466 private fun releaseCamera() {
@@ -446,11 +478,13 @@ class MobileScanner( @@ -446,11 +478,13 @@ class MobileScanner(
446 it.zoomState.removeObservers(owner) 478 it.zoomState.removeObservers(owner)
447 it.cameraState.removeObservers(owner) 479 it.cameraState.removeObservers(owner)
448 } 480 }
  481 + textureEntry?.release()
  482 + textureEntry = null
  483 +
449 // Unbind the camera use cases, the preview is a use case. 484 // Unbind the camera use cases, the preview is a use case.
450 // The camera will be closed when the last use case is unbound. 485 // The camera will be closed when the last use case is unbound.
451 cameraProvider?.unbindAll() 486 cameraProvider?.unbindAll()
452 487
453 - // Release the texture for the preview.  
454 textureEntry?.release() 488 textureEntry?.release()
455 textureEntry = null 489 textureEntry = null
456 490
@@ -460,13 +494,7 @@ class MobileScanner( @@ -460,13 +494,7 @@ class MobileScanner(
460 lastScanned = null 494 lastScanned = null
461 } 495 }
462 496
463 - private fun releaseTexture() {  
464 - textureEntry?.release()  
465 - textureEntry = null  
466 - }  
467 -  
468 private fun isStopped() = camera == null && preview == null 497 private fun isStopped() = camera == null && preview == null
469 - private fun isPaused() = isStopped() && textureEntry != null  
470 498
471 /** 499 /**
472 * Toggles the flash light on or off. 500 * Toggles the flash light on or off.