@@ -83,6 +83,7 @@ public final class BarcodeCaptureActivity extends AppCompatActivity implements B
8383 private GestureDetector gestureDetector ;
8484
8585 private ImageView imgViewBarcodeCaptureUseFlash ;
86+ private ImageView imgViewSwitchCamera ;
8687
8788 public static int SCAN_MODE = SCAN_MODE_ENUM .QR .ordinal ();
8889
@@ -110,29 +111,35 @@ public void onCreate(Bundle icicle) {
110111
111112 String buttonText = "" ;
112113 try {
113- buttonText = (String ) getIntent ().getStringExtra ("cancelButtonText" );
114- } catch (Exception e ) {
115- buttonText = "Cancel" ;
116- Log .e ("BCActivity:onCreate()" , "onCreate: " + e .getLocalizedMessage ());
117- }
118- imgViewBarcodeCaptureUseFlash = findViewById (R .id .imgViewBarcodeCaptureUseFlash );
119- Button btnBarcodeCaptureCancel = findViewById (R .id .btnBarcodeCaptureCancel );
120- btnBarcodeCaptureCancel .setText (buttonText );
121- btnBarcodeCaptureCancel .setOnClickListener (this );
122- imgViewBarcodeCaptureUseFlash .setOnClickListener (this );
123- imgViewBarcodeCaptureUseFlash .setVisibility (FlutterBarcodeScannerPlugin .isShowFlashIcon ? View .VISIBLE : View .GONE );
124- mPreview = findViewById (R .id .preview );
125- mGraphicOverlay = findViewById (R .id .graphicOverlay );
126-
127- // read parameters from the intent used to launch the activity.
128- boolean autoFocus = true ;
129- boolean useFlash = false ;
114+ buttonText = (String ) getIntent ().getStringExtra ("cancelButtonText" );
115+ } catch (Exception e ) {
116+ buttonText = "Cancel" ;
117+ Log .e ("BCActivity:onCreate()" , "onCreate: " + e .getLocalizedMessage ());
118+ }
119+
120+ Button btnBarcodeCaptureCancel = findViewById (R .id .btnBarcodeCaptureCancel );
121+ btnBarcodeCaptureCancel .setText (buttonText );
122+ btnBarcodeCaptureCancel .setOnClickListener (this );
123+
124+ imgViewBarcodeCaptureUseFlash = findViewById (R .id .imgViewBarcodeCaptureUseFlash );
125+ imgViewBarcodeCaptureUseFlash .setOnClickListener (this );
126+ imgViewBarcodeCaptureUseFlash .setVisibility (FlutterBarcodeScannerPlugin .isShowFlashIcon ? View .VISIBLE : View .GONE );
127+
128+ imgViewSwitchCamera = findViewById (R .id .imgViewSwitchCamera );
129+ imgViewSwitchCamera .setOnClickListener (this );
130+
131+ mPreview = findViewById (R .id .preview );
132+ mGraphicOverlay = findViewById (R .id .graphicOverlay );
130133
131- // Check for the camera permission before accessing the camera. If the
132- // permission is not granted yet, request permission.
133- int rc = ActivityCompat .checkSelfPermission (this , Manifest .permission .CAMERA );
134+ // read parameters from the intent used to launch the activity.
135+ boolean autoFocus = true ;
136+ boolean useFlash = false ;
137+
138+ // Check for the camera permission before accessing the camera. If the
139+ // permission is not granted yet, request permission.
140+ int rc = ActivityCompat .checkSelfPermission (this , Manifest .permission .CAMERA );
134141 if (rc == PackageManager .PERMISSION_GRANTED ) {
135- createCameraSource (autoFocus , useFlash );
142+ createCameraSource (autoFocus , useFlash , CameraSource . CAMERA_FACING_BACK );
136143 } else {
137144 requestCameraPermission ();
138145 }
@@ -193,7 +200,7 @@ public boolean onTouchEvent(MotionEvent e) {
193200 * the constant.
194201 */
195202 @ SuppressLint ("InlinedApi" )
196- private void createCameraSource (boolean autoFocus , boolean useFlash ) {
203+ private void createCameraSource (boolean autoFocus , boolean useFlash , int cameraFacing ) {
197204 Context context = getApplicationContext ();
198205
199206 // A barcode detector is created to track barcodes. An associated multi-processor instance
@@ -220,19 +227,23 @@ private void createCameraSource(boolean autoFocus, boolean useFlash) {
220227 // to other detection examples to enable the barcode detector to detect small barcodes
221228 // at long distances.
222229 CameraSource .Builder builder = new CameraSource .Builder (getApplicationContext (), barcodeDetector )
223- .setFacing (CameraSource . CAMERA_FACING_BACK )
230+ .setFacing (cameraFacing )
224231 .setRequestedPreviewSize (1600 , 1024 )
225- .setRequestedFps (15.0f );
232+ .setRequestedFps (15.0f )
233+ .setFlashMode (useFlash ? Camera .Parameters .FLASH_MODE_TORCH : null );
226234
227235 // make sure that auto focus is an available option
228236 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .ICE_CREAM_SANDWICH ) {
229237 builder = builder .setFocusMode (
230238 autoFocus ? Camera .Parameters .FOCUS_MODE_CONTINUOUS_PICTURE : null );
231239 }
232240
233- mCameraSource = builder
234- .setFlashMode (useFlash ? Camera .Parameters .FLASH_MODE_TORCH : null )
235- .build ();
241+ // Stop & release current camera source before creating a new one.
242+ if (mCameraSource != null ) {
243+ mCameraSource .stop ();
244+ mCameraSource .release ();
245+ }
246+ mCameraSource = builder .build ();
236247 }
237248
238249 /**
@@ -296,7 +307,7 @@ public void onRequestPermissionsResult(int requestCode,
296307 // we have permission, so create the camerasource
297308 boolean autoFocus = true ;
298309 boolean useFlash = false ;
299- createCameraSource (autoFocus , useFlash );
310+ createCameraSource (autoFocus , useFlash , CameraSource . CAMERA_FACING_BACK );
300311 return ;
301312 }
302313
@@ -406,9 +417,28 @@ public void onClick(View v) {
406417 barcode .displayValue = "-1" ;
407418 FlutterBarcodeScannerPlugin .onBarcodeScanReceiver (barcode );
408419 finish ();
420+ } else if (i == R .id .imgViewSwitchCamera ) {
421+ int currentFacing = mCameraSource .getCameraFacing ();
422+ boolean autoFocus = mCameraSource .getFocusMode () != null ;
423+ boolean useFlash = flashStatus == USE_FLASH .ON .ordinal ();
424+ createCameraSource (autoFocus , useFlash , getInverseCameraFacing (currentFacing ));
425+ startCameraSource ();
409426 }
410427 }
411428
429+ private int getInverseCameraFacing (int cameraFacing ) {
430+ if (cameraFacing == CameraSource .CAMERA_FACING_FRONT ) {
431+ return CameraSource .CAMERA_FACING_BACK ;
432+ }
433+
434+ if (cameraFacing == CameraSource .CAMERA_FACING_BACK ) {
435+ return CameraSource .CAMERA_FACING_FRONT ;
436+ }
437+
438+ // Fallback to camera at the back.
439+ return CameraSource .CAMERA_FACING_BACK ;
440+ }
441+
412442 /**
413443 * Turn on and off flash light based on flag
414444 *
0 commit comments