Showing
1 changed file
with
80 additions
and
74 deletions
| @@ -24,7 +24,6 @@ import io.flutter.plugin.common.MethodChannel | @@ -24,7 +24,6 @@ import io.flutter.plugin.common.MethodChannel | ||
| 24 | import io.flutter.plugin.common.PluginRegistry | 24 | import io.flutter.plugin.common.PluginRegistry |
| 25 | import io.flutter.view.TextureRegistry | 25 | import io.flutter.view.TextureRegistry |
| 26 | import java.io.File | 26 | import java.io.File |
| 27 | -import java.net.URI | ||
| 28 | 27 | ||
| 29 | 28 | ||
| 30 | class MobileScanner(private val activity: Activity, private val textureRegistry: TextureRegistry) | 29 | class MobileScanner(private val activity: Activity, private val textureRegistry: TextureRegistry) |
| @@ -39,6 +38,7 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -39,6 +38,7 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 39 | 38 | ||
| 40 | private var cameraProvider: ProcessCameraProvider? = null | 39 | private var cameraProvider: ProcessCameraProvider? = null |
| 41 | private var camera: Camera? = null | 40 | private var camera: Camera? = null |
| 41 | + private var preview: Preview? = null | ||
| 42 | private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null | 42 | private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null |
| 43 | 43 | ||
| 44 | // @AnalyzeMode | 44 | // @AnalyzeMode |
| @@ -120,86 +120,91 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -120,86 +120,91 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 120 | 120 | ||
| 121 | @ExperimentalGetImage | 121 | @ExperimentalGetImage |
| 122 | private fun start(call: MethodCall, result: MethodChannel.Result) { | 122 | private fun start(call: MethodCall, result: MethodChannel.Result) { |
| 123 | - if (camera != null) { | ||
| 124 | - result.error(TAG, "Called start() while already started!", null) | ||
| 125 | - return | ||
| 126 | - } | ||
| 127 | - | ||
| 128 | - val facing: Int = call.argument<Int>("facing") ?: 0 | ||
| 129 | - val ratio: Int? = call.argument<Int>("ratio") | ||
| 130 | - val torch: Boolean = call.argument<Boolean>("torch") ?: false | ||
| 131 | - val formats: List<Int>? = call.argument<List<Int>>("formats") | ||
| 132 | - | ||
| 133 | - if (formats != null) { | ||
| 134 | - val formatsList: MutableList<Int> = mutableListOf() | ||
| 135 | - for (index in formats) { | ||
| 136 | - formatsList.add(BarcodeFormats.values()[index].intValue) | ||
| 137 | - } | ||
| 138 | - scanner = if (formatsList.size == 1) { | ||
| 139 | - BarcodeScanning.getClient( BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first()).build()); | ||
| 140 | - } else { | ||
| 141 | - BarcodeScanning.getClient( BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first(), *formatsList.subList(1, formatsList.size).toIntArray() ).build()); | 123 | + if (camera != null && preview != null) { |
| 124 | + val resolution = preview!!.resolutionInfo!!.resolution | ||
| 125 | + val portrait = camera!!.cameraInfo.sensorRotationDegrees % 180 == 0 | ||
| 126 | + val width = resolution.width.toDouble() | ||
| 127 | + val height = resolution.height.toDouble() | ||
| 128 | + val size = if (portrait) mapOf("width" to width, "height" to height) else mapOf("width" to height, "height" to width) | ||
| 129 | + val answer = mapOf("textureId" to textureEntry!!.id(), "size" to size, "torchable" to camera!!.cameraInfo.hasFlashUnit()) | ||
| 130 | + result.success(answer) | ||
| 131 | + } else { | ||
| 132 | + val facing: Int = call.argument<Int>("facing") ?: 0 | ||
| 133 | + val ratio: Int? = call.argument<Int>("ratio") | ||
| 134 | + val torch: Boolean = call.argument<Boolean>("torch") ?: false | ||
| 135 | + val formats: List<Int>? = call.argument<List<Int>>("formats") | ||
| 136 | + | ||
| 137 | + if (formats != null) { | ||
| 138 | + val formatsList: MutableList<Int> = mutableListOf() | ||
| 139 | + for (index in formats) { | ||
| 140 | + formatsList.add(BarcodeFormats.values()[index].intValue) | ||
| 141 | + } | ||
| 142 | + scanner = if (formatsList.size == 1) { | ||
| 143 | + BarcodeScanning.getClient(BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first()).build()) | ||
| 144 | + } else { | ||
| 145 | + BarcodeScanning.getClient(BarcodeScannerOptions.Builder().setBarcodeFormats(formatsList.first(), *formatsList.subList(1, formatsList.size).toIntArray()).build()) | ||
| 146 | + } | ||
| 142 | } | 147 | } |
| 143 | - } | ||
| 144 | - | ||
| 145 | - val future = ProcessCameraProvider.getInstance(activity) | ||
| 146 | - val executor = ContextCompat.getMainExecutor(activity) | ||
| 147 | 148 | ||
| 148 | - future.addListener({ | ||
| 149 | - cameraProvider = future.get() | ||
| 150 | - cameraProvider!!.unbindAll() | ||
| 151 | - textureEntry = textureRegistry.createSurfaceTexture() | 149 | + val future = ProcessCameraProvider.getInstance(activity) |
| 150 | + val executor = ContextCompat.getMainExecutor(activity) | ||
| 152 | 151 | ||
| 153 | - // Preview | ||
| 154 | - val surfaceProvider = Preview.SurfaceProvider { request -> | ||
| 155 | - val texture = textureEntry!!.surfaceTexture() | ||
| 156 | - texture.setDefaultBufferSize(request.resolution.width, request.resolution.height) | ||
| 157 | - val surface = Surface(texture) | ||
| 158 | - request.provideSurface(surface, executor) { } | ||
| 159 | - } | 152 | + future.addListener({ |
| 153 | + cameraProvider = future.get() | ||
| 154 | + cameraProvider!!.unbindAll() | ||
| 155 | + textureEntry = textureRegistry.createSurfaceTexture() | ||
| 160 | 156 | ||
| 161 | - // Build the preview to be shown on the Flutter texture | ||
| 162 | - val previewBuilder = Preview.Builder() | ||
| 163 | - if (ratio != null) { | ||
| 164 | - previewBuilder.setTargetAspectRatio(ratio) | ||
| 165 | - } | ||
| 166 | - val preview = previewBuilder.build().apply { setSurfaceProvider(surfaceProvider) } | 157 | + // Preview |
| 158 | + val surfaceProvider = Preview.SurfaceProvider { request -> | ||
| 159 | + val texture = textureEntry!!.surfaceTexture() | ||
| 160 | + texture.setDefaultBufferSize(request.resolution.width, request.resolution.height) | ||
| 161 | + val surface = Surface(texture) | ||
| 162 | + request.provideSurface(surface, executor) { } | ||
| 163 | + } | ||
| 167 | 164 | ||
| 168 | - // Build the analyzer to be passed on to MLKit | ||
| 169 | - val analysisBuilder = ImageAnalysis.Builder() | ||
| 170 | - .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) | ||
| 171 | - if (ratio != null) { | ||
| 172 | - analysisBuilder.setTargetAspectRatio(ratio) | ||
| 173 | - } | ||
| 174 | - val analysis = analysisBuilder.build().apply { setAnalyzer(executor, analyzer) } | 165 | + // Build the preview to be shown on the Flutter texture |
| 166 | + val previewBuilder = Preview.Builder() | ||
| 167 | + if (ratio != null) { | ||
| 168 | + previewBuilder.setTargetAspectRatio(ratio) | ||
| 169 | + } | ||
| 170 | + preview = previewBuilder.build().apply { setSurfaceProvider(surfaceProvider) } | ||
| 175 | 171 | ||
| 176 | - // Select the correct camera | ||
| 177 | - val selector = if (facing == 0) CameraSelector.DEFAULT_FRONT_CAMERA else CameraSelector.DEFAULT_BACK_CAMERA | 172 | + // Build the analyzer to be passed on to MLKit |
| 173 | + val analysisBuilder = ImageAnalysis.Builder() | ||
| 174 | + .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) | ||
| 175 | + if (ratio != null) { | ||
| 176 | + analysisBuilder.setTargetAspectRatio(ratio) | ||
| 177 | + } | ||
| 178 | + val analysis = analysisBuilder.build().apply { setAnalyzer(executor, analyzer) } | ||
| 178 | 179 | ||
| 179 | - camera = cameraProvider!!.bindToLifecycle(activity as LifecycleOwner, selector, preview, analysis) | 180 | + // Select the correct camera |
| 181 | + val selector = if (facing == 0) CameraSelector.DEFAULT_FRONT_CAMERA else CameraSelector.DEFAULT_BACK_CAMERA | ||
| 180 | 182 | ||
| 181 | - val analysisSize = analysis.resolutionInfo?.resolution ?: Size(0, 0) | ||
| 182 | - val previewSize = preview.resolutionInfo?.resolution ?: Size(0, 0) | ||
| 183 | - Log.i("LOG", "Analyzer: $analysisSize") | ||
| 184 | - Log.i("LOG", "Preview: $previewSize") | 183 | + camera = cameraProvider!!.bindToLifecycle(activity as LifecycleOwner, selector, preview, analysis) |
| 185 | 184 | ||
| 186 | - // Register the torch listener | ||
| 187 | - camera!!.cameraInfo.torchState.observe(activity) { state -> | ||
| 188 | - // TorchState.OFF = 0; TorchState.ON = 1 | ||
| 189 | - sink?.success(mapOf("name" to "torchState", "data" to state)) | ||
| 190 | - } | 185 | + val analysisSize = analysis.resolutionInfo?.resolution ?: Size(0, 0) |
| 186 | + val previewSize = preview!!.resolutionInfo?.resolution ?: Size(0, 0) | ||
| 187 | + Log.i("LOG", "Analyzer: $analysisSize") | ||
| 188 | + Log.i("LOG", "Preview: $previewSize") | ||
| 191 | 189 | ||
| 192 | - // Enable torch if provided | ||
| 193 | - camera!!.cameraControl.enableTorch(torch) | 190 | + // Register the torch listener |
| 191 | + camera!!.cameraInfo.torchState.observe(activity) { state -> | ||
| 192 | + // TorchState.OFF = 0; TorchState.ON = 1 | ||
| 193 | + sink?.success(mapOf("name" to "torchState", "data" to state)) | ||
| 194 | + } | ||
| 194 | 195 | ||
| 195 | - val resolution = preview.resolutionInfo!!.resolution | ||
| 196 | - val portrait = camera!!.cameraInfo.sensorRotationDegrees % 180 == 0 | ||
| 197 | - val width = resolution.width.toDouble() | ||
| 198 | - val height = resolution.height.toDouble() | ||
| 199 | - val size = if (portrait) mapOf("width" to width, "height" to height) else mapOf("width" to height, "height" to width) | ||
| 200 | - val answer = mapOf("textureId" to textureEntry!!.id(), "size" to size, "torchable" to camera!!.cameraInfo.hasFlashUnit()) | ||
| 201 | - result.success(answer) | ||
| 202 | - }, executor) | 196 | + // Enable torch if provided |
| 197 | + camera!!.cameraControl.enableTorch(torch) | ||
| 198 | + | ||
| 199 | + val resolution = preview!!.resolutionInfo!!.resolution | ||
| 200 | + val portrait = camera!!.cameraInfo.sensorRotationDegrees % 180 == 0 | ||
| 201 | + val width = resolution.width.toDouble() | ||
| 202 | + val height = resolution.height.toDouble() | ||
| 203 | + val size = if (portrait) mapOf("width" to width, "height" to height) else mapOf("width" to height, "height" to width) | ||
| 204 | + val answer = mapOf("textureId" to textureEntry!!.id(), "size" to size, "torchable" to camera!!.cameraInfo.hasFlashUnit()) | ||
| 205 | + result.success(answer) | ||
| 206 | + }, executor) | ||
| 207 | + } | ||
| 203 | } | 208 | } |
| 204 | 209 | ||
| 205 | private fun toggleTorch(call: MethodCall, result: MethodChannel.Result) { | 210 | private fun toggleTorch(call: MethodCall, result: MethodChannel.Result) { |
| @@ -235,18 +240,19 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -235,18 +240,19 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 235 | } | 240 | } |
| 236 | 241 | ||
| 237 | private fun stop(result: MethodChannel.Result) { | 242 | private fun stop(result: MethodChannel.Result) { |
| 238 | - if (camera == null) { | 243 | + if (camera == null && preview == null) { |
| 239 | result.error(TAG,"Called stop() while already stopped!", null) | 244 | result.error(TAG,"Called stop() while already stopped!", null) |
| 240 | return | 245 | return |
| 241 | } | 246 | } |
| 242 | 247 | ||
| 243 | val owner = activity as LifecycleOwner | 248 | val owner = activity as LifecycleOwner |
| 244 | - camera!!.cameraInfo.torchState.removeObservers(owner) | ||
| 245 | - cameraProvider!!.unbindAll() | ||
| 246 | - textureEntry!!.release() | 249 | + camera?.cameraInfo?.torchState?.removeObservers(owner) |
| 250 | + cameraProvider?.unbindAll() | ||
| 251 | + textureEntry?.release() | ||
| 247 | 252 | ||
| 248 | // analyzeMode = AnalyzeMode.NONE | 253 | // analyzeMode = AnalyzeMode.NONE |
| 249 | camera = null | 254 | camera = null |
| 255 | + preview = null | ||
| 250 | textureEntry = null | 256 | textureEntry = null |
| 251 | cameraProvider = null | 257 | cameraProvider = null |
| 252 | 258 |
-
Please register or login to post a comment