Julian Steenbakker
Committed by GitHub

Merge pull request #51 from juliansteenbakker/hot-reload

bug: fixed hot reload not working
@@ -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