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.
|
|
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. **
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
72
|
-
|
|
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, "
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|