react-native-pdf417-scanner 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,15 @@ A comprehensive React Native SDK for live PDF417 barcode scanning with **native
13
13
  - **🛡️ Error Handling**: Comprehensive error reporting and recovery
14
14
  - **📝 TypeScript Support**: Full TypeScript definitions included
15
15
 
16
- ## What's New in v1.2.0
16
+ ## What's New in v1.4.0
17
+
18
+ - **🔧 Camera Fixes**: Resolved "Failed to start preview" errors with enhanced error handling
19
+ - **🔄 Retry Logic**: Automatic camera initialization retry (up to 3 attempts)
20
+ - **📱 Better Compatibility**: Improved Camera2 API configuration for various devices
21
+ - **🛠️ Enhanced Debugging**: Comprehensive logging and troubleshooting guide
22
+ - **⚡ Stability Improvements**: Better threading and surface texture handling
23
+
24
+ ## Previous Updates (v1.2.0)
17
25
 
18
26
  - **Native Camera View Component**: Show live camera feed instead of black screen
19
27
  - **Real-time Preview**: See exactly what the camera sees while scanning
@@ -529,24 +537,61 @@ const ScannerWithLifecycle = () => {
529
537
 
530
538
  ### Common Issues
531
539
 
532
- 1. **Camera Permission Denied**
540
+ 1. **"Failed to start preview" Error**
541
+ - **Cause**: Camera initialization issues, surface texture not ready, or device compatibility
542
+ - **Solution**: The package now includes automatic retry logic (up to 3 attempts)
543
+ - **Manual Fix**: Restart the app, check camera permissions, or try on a different device
544
+
545
+ 2. **Camera Permission Denied**
533
546
  - Ensure permissions are declared in AndroidManifest.xml
534
547
  - Request permissions before starting scanning
535
548
  - Handle permission denial gracefully
536
549
 
537
- 2. **Build Errors**
550
+ 3. **Camera Already in Use**
551
+ - Close other camera applications
552
+ - Restart the device if the issue persists
553
+ - Check if another part of your app is using the camera
554
+
555
+ 4. **Build Errors**
538
556
  - Verify all Gradle configurations are correct
539
557
  - Ensure ZXing dependencies are properly resolved
540
558
  - Clean and rebuild the project
541
559
 
542
- 3. **Scanner Not Working**
560
+ 5. **Scanner Not Working**
543
561
  - Check device camera functionality
544
562
  - Verify proper lighting conditions
545
563
  - Ensure PDF417 barcode is clearly visible
546
564
 
565
+ ### Camera Error Recovery
566
+
567
+ The package now includes enhanced error recovery:
568
+
569
+ ```typescript
570
+ const handleScanError = (error: PDF417ScanError) => {
571
+ if (error.code === 'CAMERA_ERROR') {
572
+ if (error.message.includes('permission')) {
573
+ // Handle permission issues
574
+ requestCameraPermission();
575
+ } else if (error.message.includes('preview')) {
576
+ // Handle camera preview issues - retry automatically
577
+ setTimeout(() => startScanning(), 1000);
578
+ }
579
+ }
580
+ };
581
+ ```
582
+
583
+ ### Device-Specific Issues
584
+
585
+ - **Samsung Devices**: Disable "Camera Assistant" if experiencing issues
586
+ - **Huawei/Honor**: Check "Phone Manager" permissions
587
+ - **Xiaomi**: Grant "Display pop-up windows" permission in MIUI settings
588
+
547
589
  ### Debug Mode
548
590
 
549
- Enable debug logging by setting the log level in your native module configuration.
591
+ Enable debug logging by checking Android logs:
592
+ ```bash
593
+ adb logcat | grep -E "(PDF417|Camera|ERROR)"
594
+ ```
550
595
 
551
596
  ## Requirements
552
597
 
@@ -1,6 +1,8 @@
1
1
  package com.pdf417scanner;
2
2
 
3
+ import android.Manifest;
3
4
  import android.content.Context;
5
+ import android.content.pm.PackageManager;
4
6
  import android.graphics.SurfaceTexture;
5
7
  import android.hardware.camera2.CameraAccessException;
6
8
  import android.hardware.camera2.CameraCaptureSession;
@@ -18,6 +20,7 @@ import android.view.Surface;
18
20
  import android.view.TextureView;
19
21
 
20
22
  import androidx.annotation.NonNull;
23
+ import androidx.core.app.ActivityCompat;
21
24
 
22
25
  import java.util.Arrays;
23
26
  import java.util.concurrent.Semaphore;
@@ -67,9 +70,24 @@ public class PDF417CameraView extends TextureView implements TextureView.Surface
67
70
  }
68
71
 
69
72
  public void startCamera() {
73
+ Log.d(TAG, "Starting camera...");
70
74
  startBackgroundThread();
71
- if (isAvailable()) {
72
- openCamera(getWidth(), getHeight());
75
+
76
+ // Add a small delay to ensure background thread is ready
77
+ if (backgroundHandler != null) {
78
+ backgroundHandler.post(() -> {
79
+ if (isAvailable()) {
80
+ openCamera(getWidth(), getHeight());
81
+ } else {
82
+ Log.d(TAG, "Surface texture not available yet, waiting...");
83
+ // Will be called from onSurfaceTextureAvailable
84
+ }
85
+ });
86
+ } else {
87
+ Log.e(TAG, "Background handler not ready");
88
+ if (cameraReadyListener != null) {
89
+ cameraReadyListener.onCameraError("Camera initialization failed");
90
+ }
73
91
  }
74
92
  }
75
93
 
@@ -118,21 +136,47 @@ public class PDF417CameraView extends TextureView implements TextureView.Surface
118
136
 
119
137
  private void openCamera(int width, int height) {
120
138
  try {
139
+ // Check camera permission first
140
+ if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA)
141
+ != PackageManager.PERMISSION_GRANTED) {
142
+ Log.e(TAG, "Camera permission not granted");
143
+ if (cameraReadyListener != null) {
144
+ cameraReadyListener.onCameraError("Camera permission not granted");
145
+ }
146
+ return;
147
+ }
148
+
121
149
  if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
122
150
  throw new RuntimeException("Time out waiting to lock camera opening.");
123
151
  }
124
152
 
125
153
  cameraId = selectCamera();
126
154
  if (cameraId == null) {
155
+ Log.e(TAG, "No suitable camera found");
127
156
  if (cameraReadyListener != null) {
128
157
  cameraReadyListener.onCameraError("No suitable camera found");
129
158
  }
159
+ cameraOpenCloseLock.release();
130
160
  return;
131
161
  }
132
162
 
163
+ Log.d(TAG, "Opening camera: " + cameraId);
133
164
  cameraManager.openCamera(cameraId, stateCallback, backgroundHandler);
165
+ } catch (CameraAccessException e) {
166
+ Log.e(TAG, "Camera access exception", e);
167
+ cameraOpenCloseLock.release();
168
+ if (cameraReadyListener != null) {
169
+ cameraReadyListener.onCameraError("Camera access denied: " + e.getMessage());
170
+ }
171
+ } catch (SecurityException e) {
172
+ Log.e(TAG, "Security exception opening camera", e);
173
+ cameraOpenCloseLock.release();
174
+ if (cameraReadyListener != null) {
175
+ cameraReadyListener.onCameraError("Camera security error: " + e.getMessage());
176
+ }
134
177
  } catch (Exception e) {
135
- Log.e(TAG, "Error opening camera", e);
178
+ Log.e(TAG, "Unexpected error opening camera", e);
179
+ cameraOpenCloseLock.release();
136
180
  if (cameraReadyListener != null) {
137
181
  cameraReadyListener.onCameraError("Failed to open camera: " + e.getMessage());
138
182
  }
@@ -193,44 +237,93 @@ public class PDF417CameraView extends TextureView implements TextureView.Surface
193
237
  private void createCameraPreviewSession() {
194
238
  try {
195
239
  SurfaceTexture texture = getSurfaceTexture();
240
+ if (texture == null) {
241
+ Log.e(TAG, "Surface texture not available, retrying...");
242
+ // Retry after a short delay
243
+ backgroundHandler.postDelayed(() -> {
244
+ if (cameraDevice != null) {
245
+ createCameraPreviewSession();
246
+ }
247
+ }, 100);
248
+ return;
249
+ }
250
+
251
+ // Ensure surface texture is properly configured
252
+ if (previewSize == null) {
253
+ Log.e(TAG, "Preview size not set");
254
+ if (cameraReadyListener != null) {
255
+ cameraReadyListener.onCameraError("Preview size not configured");
256
+ }
257
+ return;
258
+ }
259
+
196
260
  texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
197
261
  Surface surface = new Surface(texture);
198
262
 
199
263
  CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
200
264
  builder.addTarget(surface);
265
+
266
+ // Enhanced camera settings for better compatibility
201
267
  builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
268
+ builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
269
+ builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
270
+
271
+ // Set initial flash mode
272
+ builder.set(CaptureRequest.FLASH_MODE, torchEnabled ?
273
+ CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_OFF);
202
274
 
203
275
  cameraDevice.createCaptureSession(Arrays.asList(surface),
204
276
  new CameraCaptureSession.StateCallback() {
205
277
  @Override
206
278
  public void onConfigured(@NonNull CameraCaptureSession session) {
207
- if (cameraDevice == null) return;
279
+ if (cameraDevice == null) {
280
+ Log.w(TAG, "Camera device null during session configuration");
281
+ return;
282
+ }
208
283
 
209
284
  captureSession = session;
210
285
  try {
211
- session.setRepeatingRequest(builder.build(), null, backgroundHandler);
286
+ CaptureRequest request = builder.build();
287
+ session.setRepeatingRequest(request, null, backgroundHandler);
288
+ Log.d(TAG, "Camera preview started successfully");
212
289
  if (cameraReadyListener != null) {
213
290
  cameraReadyListener.onCameraReady();
214
291
  }
215
292
  } catch (CameraAccessException e) {
216
293
  Log.e(TAG, "Error starting camera preview", e);
217
294
  if (cameraReadyListener != null) {
218
- cameraReadyListener.onCameraError("Failed to start preview");
295
+ cameraReadyListener.onCameraError("Failed to start preview: " + e.getMessage());
296
+ }
297
+ } catch (IllegalStateException e) {
298
+ Log.e(TAG, "Camera in illegal state", e);
299
+ if (cameraReadyListener != null) {
300
+ cameraReadyListener.onCameraError("Camera state error: " + e.getMessage());
219
301
  }
220
302
  }
221
303
  }
222
304
 
223
305
  @Override
224
306
  public void onConfigureFailed(@NonNull CameraCaptureSession session) {
307
+ Log.e(TAG, "Camera session configuration failed");
225
308
  if (cameraReadyListener != null) {
226
- cameraReadyListener.onCameraError("Failed to configure camera");
309
+ cameraReadyListener.onCameraError("Failed to configure camera session");
227
310
  }
228
311
  }
229
- }, null);
312
+
313
+ @Override
314
+ public void onClosed(@NonNull CameraCaptureSession session) {
315
+ Log.d(TAG, "Camera session closed");
316
+ }
317
+ }, backgroundHandler);
230
318
  } catch (CameraAccessException e) {
231
319
  Log.e(TAG, "Error creating camera preview session", e);
232
320
  if (cameraReadyListener != null) {
233
- cameraReadyListener.onCameraError("Failed to create preview session");
321
+ cameraReadyListener.onCameraError("Failed to create preview session: " + e.getMessage());
322
+ }
323
+ } catch (Exception e) {
324
+ Log.e(TAG, "Unexpected error in camera preview session", e);
325
+ if (cameraReadyListener != null) {
326
+ cameraReadyListener.onCameraError("Unexpected camera error: " + e.getMessage());
234
327
  }
235
328
  }
236
329
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-pdf417-scanner",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "React Native SDK for PDF417 barcode scanning with native camera view",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",