@ -54,6 +54,9 @@ interface QRScannerService { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  addListener(listener: ScanListener): void; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  onStream(callback: (stream: MediaStream | null) => void): void; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  cleanup(): Promise< void > ; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  getAvailableCameras(): Promise< MediaDeviceInfo [ ] > ; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  switchCamera(deviceId: string): Promise< void > ; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  getCurrentCamera(): Promise< MediaDeviceInfo  |  null > ; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					interface ScanListener { 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -87,7 +90,15 @@ const config: CapacitorConfig = { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      formats: ['QR_CODE'], 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      detectorSize: 1.0, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      lensFacing: 'back', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      googleBarcodeScannerModuleInstallState: true 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      googleBarcodeScannerModuleInstallState: true, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      // Additional camera options 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      cameraOptions: { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        quality: 0.8, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        allowEditing: false, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        resultType: 'uri', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        sourceType: 'CAMERA', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        saveToGallery: false 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}; 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -281,4 +292,514 @@ export async function createBuildConfig(mode: string) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					- Track memory usage 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					- Monitor camera performance 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					- Check error rates 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					- Analyze user feedback 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					- Analyze user feedback 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					## Camera Handling 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### Camera Switching Implementation 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					The QR scanner supports camera switching on both mobile and desktop platforms through a unified interface. 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#### Platform-Specific Implementations 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Mobile (Capacitor)** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Uses `@capacitor-mlkit/barcode-scanning`  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Supports front/back camera switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Native camera access through platform APIs 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Optimized for mobile performance 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // CapacitorQRScanner.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   async startScan(options?: QRScannerOptions): Promise< void >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     const scanOptions: StartScanOptions = { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       formats: [BarcodeFormat.QrCode], 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       lensFacing: options?.camera === "front" ?  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         LensFacing.Front : LensFacing.Back 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     await BarcodeScanner.startScan(scanOptions); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Web (Desktop)** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Uses browser's MediaDevices API 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Supports multiple camera devices 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Dynamic camera enumeration 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Real-time camera switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // WebInlineQRScanner.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   async getAvailableCameras(): Promise< MediaDeviceInfo [ ] >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     const devices = await navigator.mediaDevices.enumerateDevices(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     return devices.filter(device => device.kind === 'videoinput'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   async switchCamera(deviceId: string): Promise< void >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Stop current stream 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     await this.stopScan(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Start new stream with selected camera 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     this.stream = await navigator.mediaDevices.getUserMedia({ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       video: { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         deviceId: { exact: deviceId }, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         width: { ideal: 1280 }, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         height: { ideal: 720 } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Update video and restart scanning 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     if (this.video) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.video.srcObject = this.stream; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       await this.video.play(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     this.scanQRCode(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### Core Interfaces 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					interface QRScannerService { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  // ... existing methods ... 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  /** Get available cameras */ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  getAvailableCameras(): Promise< MediaDeviceInfo [ ] > ; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  /** Switch to a specific camera */ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  switchCamera(deviceId: string): Promise< void > ; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  /** Get current camera info */ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  getCurrentCamera(): Promise< MediaDeviceInfo  |  null > ; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					interface QRScannerOptions { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  /** Camera to use ('front' or 'back' for mobile) */ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  camera?: "front" | "back"; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  /** Whether to show a preview of the camera feed */ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  showPreview?: boolean; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  /** Whether to play a sound on successful scan */ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					  playSound?: boolean; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### UI Components 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					The camera switching UI adapts to the platform: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Mobile Interface** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Simple toggle button for front/back cameras 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Positioned in bottom-right corner 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Clear visual feedback during switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Native camera controls 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```vue 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < button   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     v-if="isNativePlatform" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     @click ="toggleMobileCamera" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     class="camera-switch-btn" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   > 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     < font-awesome  icon = "camera-rotate"  / >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     Switch Camera 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < / button >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Desktop Interface** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Dropdown menu with all available cameras 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera labels and device IDs 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Real-time camera switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Responsive design 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```vue 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < select   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     v-model="selectedCameraId" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     @change ="onCameraChange" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     class="camera-select-dropdown" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   > 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     < option   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       v-for="camera in availableCameras"  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       :key="camera.deviceId" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       :value="camera.deviceId" 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     > 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       {{ camera.label || `Camera ${camera.deviceId.slice(0, 4)}`  }} 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     < / option >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < / select >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### Error Handling 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					The camera switching implementation includes comprehensive error handling: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Common Error Scenarios** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera in use by another application 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Permission denied during switch 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Device not available 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Stream initialization failure 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera switch timeout 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Error Response** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private async handleCameraSwitch(deviceId: string): Promise< void >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     try { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.updateCameraState("initializing", "Switching camera..."); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       await this.switchCamera(deviceId); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.updateCameraState("active", "Camera switched successfully"); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } catch (error) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.updateCameraState("error", "Failed to switch camera"); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       throw error; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					3. **User Feedback** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Visual indicators during switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Error notifications 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera state updates 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Permission request dialogs 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### State Management 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					The camera system maintains several states: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Camera States** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   type CameraState = 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "initializing"  // Camera is being initialized 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "ready"        // Camera is ready to use 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "active"       // Camera is actively streaming 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "in_use"       // Camera is in use by another application 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "permission_denied" // Camera permission was denied 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "not_found"    // No camera found on device 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "error"        // Generic error state 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     | "off";         // Camera is off 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **State Transitions** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Initialization → Ready 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Ready → Active 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Active → Switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Switching → Active/Error 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Any state → Off (on cleanup) 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### Best Practices 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Camera Access** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Always check permissions before switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Handle camera busy states 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Implement proper cleanup 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Monitor camera state changes 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Performance** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Optimize camera resolution 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Handle stream switching efficiently 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Manage memory usage 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Implement proper cleanup 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					3. **User Experience** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Clear visual feedback 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Smooth camera transitions 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Intuitive camera controls 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Responsive UI updates 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Accessible camera selection 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					4. **Security** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Secure camera access 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Permission management 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Device validation 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Stream security 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### Testing 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Test Scenarios** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera switching on both platforms 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Permission handling 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Error conditions 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Multiple camera devices 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera busy states 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Stream initialization 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - UI responsiveness 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Test Environment** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Multiple mobile devices 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Various desktop browsers 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Different camera configurations 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Network conditions 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Permission states 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					### Capacitor Implementation Details 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#### MLKit Barcode Scanner Configuration 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Plugin Setup** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // capacitor.config.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   const config: CapacitorConfig = { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     plugins: { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       MLKitBarcodeScanner: { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         formats: ['QR_CODE'], 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         detectorSize: 1.0, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         lensFacing: 'back', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         googleBarcodeScannerModuleInstallState: true, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         // Additional camera options 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         cameraOptions: { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           quality: 0.8, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           allowEditing: false, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           resultType: 'uri', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           sourceType: 'CAMERA', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           saveToGallery: false 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   }; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Camera Management** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // CapacitorQRScanner.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   export class CapacitorQRScanner implements QRScannerService { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     private currentLensFacing: LensFacing = LensFacing.Back; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     async getAvailableCameras(): Promise< MediaDeviceInfo [ ] >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // On mobile, we have two fixed cameras 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       return [ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           deviceId: 'back', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           label: 'Back Camera', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           kind: 'videoinput' 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         }, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           deviceId: 'front', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           label: 'Front Camera', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           kind: 'videoinput' 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       ] as MediaDeviceInfo[]; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     async switchCamera(deviceId: string): Promise< void >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       if (!this.isScanning) return; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       const newLensFacing = deviceId === 'front' ?  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         LensFacing.Front : LensFacing.Back; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // Stop current scan 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       await this.stopScan(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // Update lens facing 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.currentLensFacing = newLensFacing; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // Restart scan with new camera 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       await this.startScan({ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         camera: deviceId as 'front' | 'back' 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       }); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     async getCurrentCamera(): Promise< MediaDeviceInfo  |  null >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       return { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         deviceId: this.currentLensFacing === LensFacing.Front ? 'front' : 'back', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         label: this.currentLensFacing === LensFacing.Front ?  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           'Front Camera' : 'Back Camera', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         kind: 'videoinput' 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       } as MediaDeviceInfo; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					3. **Camera State Management** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // CapacitorQRScanner.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private async handleCameraState(): Promise< void >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     try { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // Check if camera is available 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       const { camera } = await BarcodeScanner.checkPermissions(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       if (camera === 'denied') { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         this.updateCameraState('permission_denied'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         return; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // Check if camera is in use 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       const isInUse = await this.isCameraInUse(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       if (isInUse) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         this.updateCameraState('in_use'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         return; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.updateCameraState('ready'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } catch (error) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.updateCameraState('error', error.message); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private async isCameraInUse(): Promise< boolean >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     try { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // Try to start a test scan 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       await BarcodeScanner.startScan({ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         formats: [BarcodeFormat.QrCode], 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         lensFacing: this.currentLensFacing 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       }); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       // If successful, stop it immediately 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       await BarcodeScanner.stopScan(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       return false; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } catch (error) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       return error.message.includes('camera in use'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					4. **Error Handling** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // CapacitorQRScanner.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private async handleCameraError(error: Error): Promise< void >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     switch (error.name) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       case 'CameraPermissionDenied': 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         this.updateCameraState('permission_denied'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         break; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       case 'CameraInUse': 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         this.updateCameraState('in_use'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         break; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       case 'CameraUnavailable': 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         this.updateCameraState('not_found'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         break; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       default: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         this.updateCameraState('error', error.message); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#### Platform-Specific Considerations 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **iOS Implementation** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera permissions in Info.plist 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Privacy descriptions 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera usage description 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Background camera access 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```xml 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   <!--  ios/App/App/Info.plist  -->  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < key > NSCameraUsageDescription< / key >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < string > We need access to your camera to scan QR codes< / string >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < key > NSPhotoLibraryUsageDescription< / key >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < string > We need access to save scanned QR codes< / string >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Android Implementation** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera permissions in AndroidManifest.xml 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Runtime permission handling 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera features declaration 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Hardware feature requirements 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```xml 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   <!--  android/app/src/main/AndroidManifest.xml  -->  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < uses-permission  android:name = "android.permission.CAMERA"  / >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < uses-feature  android:name = "android.hardware.camera"  / >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   < uses-feature  android:name = "android.hardware.camera.autofocus"  / >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					3. **Platform-Specific Features** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - iOS: Camera orientation handling 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Android: Camera resolution optimization 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Both: Battery usage optimization 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Both: Memory management 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // Platform-specific optimizations 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private getPlatformSpecificOptions(): StartScanOptions { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     const baseOptions: StartScanOptions = { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       formats: [BarcodeFormat.QrCode], 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       lensFacing: this.currentLensFacing 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     if (Capacitor.getPlatform() === 'ios') { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       return { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         ...baseOptions, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         // iOS-specific options 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         cameraOptions: { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           quality: 0.7, // Lower quality for better performance 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           allowEditing: false, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           resultType: 'uri' 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       }; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } else if (Capacitor.getPlatform() === 'android') { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       return { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         ...baseOptions, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         // Android-specific options 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         cameraOptions: { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           quality: 0.8, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           allowEditing: false, 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           resultType: 'uri', 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					           saveToGallery: false 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       }; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     return baseOptions; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#### Performance Optimization 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Battery Usage** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // CapacitorQRScanner.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private optimizeBatteryUsage(): void { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Reduce scan frequency when battery is low 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     if (this.isLowBattery()) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.scanInterval = 2000; // 2 seconds between scans 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } else { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       this.scanInterval = 1000; // 1 second between scans 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private isLowBattery(): boolean { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Check battery level if available 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     if (Capacitor.isPluginAvailable('Battery')) { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       const { level } = await Battery.getBatteryLevel(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					       return level <  0.2 ;  / /  20 %  or  lower  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     return false; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Memory Management** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ```typescript 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   // CapacitorQRScanner.ts 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   private async cleanupResources(): Promise< void >  { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Stop scanning 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     await this.stopScan(); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Clear any stored camera data 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     this.currentLensFacing = LensFacing.Back; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Remove listeners 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     this.listenerHandles.forEach(handle => handle()); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     this.listenerHandles = []; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					      
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     // Reset state 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     this.isScanning = false; 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     this.updateCameraState('off'); 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   } 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   ``` 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#### Testing on Capacitor 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					1. **Device Testing** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test on multiple iOS devices 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test on multiple Android devices 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test different camera configurations 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test with different screen sizes 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test with different OS versions 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					2. **Camera Testing** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test front camera switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test back camera switching 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test camera permissions 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test camera in use scenarios 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test low light conditions 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test different QR code sizes 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Test different QR code distances 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					3. **Performance Testing** 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Battery usage monitoring 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Memory usage monitoring 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Camera switching speed 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - QR code detection speed 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - App responsiveness 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					   - Background/foreground transitions