Julian Steenbakker

feat: add available camera information in startcallback on android

@@ -240,6 +240,7 @@ class MobileScanner( @@ -240,6 +240,7 @@ class MobileScanner(
240 240
241 cameraProviderFuture.addListener({ 241 cameraProviderFuture.addListener({
242 cameraProvider = cameraProviderFuture.get() 242 cameraProvider = cameraProviderFuture.get()
  243 + val nrOfCameras = cameraProvider?.availableCameraInfos?.size
243 244
244 if (cameraProvider == null) { 245 if (cameraProvider == null) {
245 mobileScannerErrorCallback(CameraError()) 246 mobileScannerErrorCallback(CameraError())
@@ -340,7 +341,8 @@ class MobileScanner( @@ -340,7 +341,8 @@ class MobileScanner(
340 if (portrait) width else height, 341 if (portrait) width else height,
341 if (portrait) height else width, 342 if (portrait) height else width,
342 camera?.cameraInfo?.hasFlashUnit() ?: false, 343 camera?.cameraInfo?.hasFlashUnit() ?: false,
343 - textureEntry!!.id() 344 + textureEntry!!.id(),
  345 + nrOfCameras ?: 0
344 ) 346 )
345 ) 347 )
346 }, executor) 348 }, executor)
@@ -178,7 +178,8 @@ class MobileScannerHandler( @@ -178,7 +178,8 @@ class MobileScannerHandler(
178 result.success(mapOf( 178 result.success(mapOf(
179 "textureId" to it.id, 179 "textureId" to it.id,
180 "size" to mapOf("width" to it.width, "height" to it.height), 180 "size" to mapOf("width" to it.width, "height" to it.height),
181 - "torchable" to it.hasFlashUnit 181 + "torchable" to it.hasFlashUnit,
  182 + "nrOfCameras" to it.nrOfCameras
182 )) 183 ))
183 } 184 }
184 }, 185 },
@@ -4,5 +4,6 @@ class MobileScannerStartParameters( @@ -4,5 +4,6 @@ class MobileScannerStartParameters(
4 val width: Double = 0.0, 4 val width: Double = 0.0,
5 val height: Double, 5 val height: Double,
6 val hasFlashUnit: Boolean, 6 val hasFlashUnit: Boolean,
7 - val id: Long 7 + val id: Long,
  8 + val nrOfCameras: Int
8 ) 9 )
@@ -47,6 +47,8 @@ class _BarcodeScannerWithControllerState @@ -47,6 +47,8 @@ class _BarcodeScannerWithControllerState
47 } 47 }
48 } 48 }
49 49
  50 + int? nrOfCameras;
  51 +
50 @override 52 @override
51 Widget build(BuildContext context) { 53 Widget build(BuildContext context) {
52 return Scaffold( 54 return Scaffold(
@@ -57,6 +59,12 @@ class _BarcodeScannerWithControllerState @@ -57,6 +59,12 @@ class _BarcodeScannerWithControllerState
57 return Stack( 59 return Stack(
58 children: [ 60 children: [
59 MobileScanner( 61 MobileScanner(
  62 + onScannerStarted: (arguments) {
  63 + if (arguments?.nrOfCameras != null) {
  64 + nrOfCameras = arguments!.nrOfCameras;
  65 + setState(() {});
  66 + }
  67 + },
60 controller: controller, 68 controller: controller,
61 errorBuilder: (context, error, child) { 69 errorBuilder: (context, error, child) {
62 return ScannerErrorWidget(error: error); 70 return ScannerErrorWidget(error: error);
@@ -146,7 +154,9 @@ class _BarcodeScannerWithControllerState @@ -146,7 +154,9 @@ class _BarcodeScannerWithControllerState
146 }, 154 },
147 ), 155 ),
148 iconSize: 32.0, 156 iconSize: 32.0,
149 - onPressed: () => controller.switchCamera(), 157 + onPressed: nrOfCameras != null && nrOfCameras! < 2
  158 + ? null
  159 + : () => controller.switchCamera(),
150 ), 160 ),
151 IconButton( 161 IconButton(
152 color: Colors.white, 162 color: Colors.white,
@@ -225,12 +225,12 @@ class _MobileScannerState extends State<MobileScanner> @@ -225,12 +225,12 @@ class _MobileScannerState extends State<MobileScanner>
225 return Stack( 225 return Stack(
226 alignment: Alignment.center, 226 alignment: Alignment.center,
227 children: [ 227 children: [
228 - _scanner(value.size, value.webId, value.textureId), 228 + _scanner(value.size, value.webId, value.textureId, value.nrOfCameras),
229 widget.overlay!, 229 widget.overlay!,
230 ], 230 ],
231 ); 231 );
232 } else { 232 } else {
233 - return _scanner(value.size, value.webId, value.textureId); 233 + return _scanner(value.size, value.webId, value.textureId, value.nrOfCameras);
234 } 234 }
235 }, 235 },
236 ); 236 );
@@ -238,7 +238,7 @@ class _MobileScannerState extends State<MobileScanner> @@ -238,7 +238,7 @@ class _MobileScannerState extends State<MobileScanner>
238 ); 238 );
239 } 239 }
240 240
241 - Widget _scanner(Size size, String? webId, int? textureId) { 241 + Widget _scanner(Size size, String? webId, int? textureId, int? nrOfCameras) {
242 return ClipRect( 242 return ClipRect(
243 child: LayoutBuilder( 243 child: LayoutBuilder(
244 builder: (_, constraints) { 244 builder: (_, constraints) {
@@ -304,6 +304,7 @@ class MobileScannerController { @@ -304,6 +304,7 @@ class MobileScannerController {
304 304
305 isStarting = false; 305 isStarting = false;
306 return startArguments.value = MobileScannerArguments( 306 return startArguments.value = MobileScannerArguments(
  307 + nrOfCameras: startResult['nrOfCameras'] as int?,
307 size: size, 308 size: size,
308 hasTorch: hasTorch, 309 hasTorch: hasTorch,
309 textureId: kIsWeb ? null : startResult['textureId'] as int?, 310 textureId: kIsWeb ? null : startResult['textureId'] as int?,
@@ -15,10 +15,15 @@ class MobileScannerArguments { @@ -15,10 +15,15 @@ class MobileScannerArguments {
15 /// The texture id of the capture used internally if device is web. 15 /// The texture id of the capture used internally if device is web.
16 final String? webId; 16 final String? webId;
17 17
  18 + /// Indicates how many cameras are available.
  19 + /// Only available on Android
  20 + final int? nrOfCameras;
  21 +
18 MobileScannerArguments({ 22 MobileScannerArguments({
19 required this.size, 23 required this.size,
20 required this.hasTorch, 24 required this.hasTorch,
21 this.textureId, 25 this.textureId,
22 this.webId, 26 this.webId,
  27 + this.nrOfCameras
23 }); 28 });
24 } 29 }