Google 显示 2 个代码时视觉崩溃
Google Vision crashes when 2 codes are presented
我在我的应用程序中使用 google 视觉来读取条形码和二维码。这很好用,但是当扫描的表面有 2 个代码彼此相邻时,它会崩溃,如下图所示。
即使代码被单独扫描正确扫描,也会发生这种情况。有谁知道如何阻止这种情况发生?
这里是管理扫码的代码activity:
public class ScanningActivity extends AppCompatActivity {
SurfaceView cameraPreview;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
final Integer requestCameraPermissionID = 1001;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity_add_scanner);
final int height = getSurfaceViewHeight();
final int width = getSurfaceViewWidth();
cameraPreview = findViewById(R.id.surfaceview_scanner);
barcodeDetector = new BarcodeDetector.Builder(AddScanningActivity.this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
cameraSource = new CameraSource.Builder(AddScanningActivity.this, barcodeDetector)
.setAutoFocusEnabled(true)
.setRequestedPreviewSize(width, height)
.build();
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0) {
Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(100);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
cameraSource.release();
}
});
}
}
});
cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AddScanningActivity.this,
new String[]{Manifest.permission.CAMERA}, requestCameraPermissionID);
return;
}
try {
cameraSource.start(cameraPreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}, 100);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
}
private Integer getSurfaceViewHeight() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Integer screenHeight = size.y;
Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
final int statusBarHeight = rectangle.top;
int[] attrs = new int[]{R.attr.actionBarSize};
TypedArray ta = this.obtainStyledAttributes(attrs);
final int actionBarHeight = ta.getDimensionPixelSize(0, -1);
ta.recycle();
return screenHeight - statusBarHeight - actionBarHeight;
}
private Integer getSurfaceViewWidth() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size.x;
}
}
问题是在释放 cameraSource 之前第二次调用了 receiveDetections 方法。然后第二次调用时,该方法再次尝试释放cameraSource,但是已经不可用了,导致报错。下面是工作代码,只有一个小的简单变化,即使用布尔值 'codeDetected':
public class AddScanningActivity extends AppCompatActivity {
SurfaceView cameraPreview;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
final Integer requestCameraPermissionID = 1001;
Boolean codeDetected = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity_add_scanner);
final int height = getSurfaceViewHeight();
final int width = getSurfaceViewWidth();
cameraPreview = findViewById(R.id.surfaceview_scanner);
barcodeDetector = new BarcodeDetector.Builder(AddScanningActivity.this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
cameraSource = new CameraSource.Builder(AddScanningActivity.this, barcodeDetector)
.setAutoFocusEnabled(true)
.setRequestedPreviewSize(width, height)
.build();
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0 && !codeDetected) {
codeDetected = true;
Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(100);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
cameraSource.release();
}
});
}
}
});
cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AddScanningActivity.this,
new String[]{Manifest.permission.CAMERA}, requestCameraPermissionID);
return;
}
try {
cameraSource.start(cameraPreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}, 100);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
}
private Integer getSurfaceViewHeight() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Integer screenHeight = size.y;
Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
final int statusBarHeight = rectangle.top;
int[] attrs = new int[] {R.attr.actionBarSize};
TypedArray ta = this.obtainStyledAttributes(attrs);
final int actionBarHeight = ta.getDimensionPixelSize(0, -1);
ta.recycle();
return screenHeight - statusBarHeight - actionBarHeight;
}
private Integer getSurfaceViewWidth() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size.x;
}
}
我在我的应用程序中使用 google 视觉来读取条形码和二维码。这很好用,但是当扫描的表面有 2 个代码彼此相邻时,它会崩溃,如下图所示。
即使代码被单独扫描正确扫描,也会发生这种情况。有谁知道如何阻止这种情况发生?
这里是管理扫码的代码activity:
public class ScanningActivity extends AppCompatActivity {
SurfaceView cameraPreview;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
final Integer requestCameraPermissionID = 1001;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity_add_scanner);
final int height = getSurfaceViewHeight();
final int width = getSurfaceViewWidth();
cameraPreview = findViewById(R.id.surfaceview_scanner);
barcodeDetector = new BarcodeDetector.Builder(AddScanningActivity.this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
cameraSource = new CameraSource.Builder(AddScanningActivity.this, barcodeDetector)
.setAutoFocusEnabled(true)
.setRequestedPreviewSize(width, height)
.build();
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0) {
Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(100);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
cameraSource.release();
}
});
}
}
});
cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AddScanningActivity.this,
new String[]{Manifest.permission.CAMERA}, requestCameraPermissionID);
return;
}
try {
cameraSource.start(cameraPreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}, 100);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
}
private Integer getSurfaceViewHeight() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Integer screenHeight = size.y;
Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
final int statusBarHeight = rectangle.top;
int[] attrs = new int[]{R.attr.actionBarSize};
TypedArray ta = this.obtainStyledAttributes(attrs);
final int actionBarHeight = ta.getDimensionPixelSize(0, -1);
ta.recycle();
return screenHeight - statusBarHeight - actionBarHeight;
}
private Integer getSurfaceViewWidth() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size.x;
}
}
问题是在释放 cameraSource 之前第二次调用了 receiveDetections 方法。然后第二次调用时,该方法再次尝试释放cameraSource,但是已经不可用了,导致报错。下面是工作代码,只有一个小的简单变化,即使用布尔值 'codeDetected':
public class AddScanningActivity extends AppCompatActivity {
SurfaceView cameraPreview;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
final Integer requestCameraPermissionID = 1001;
Boolean codeDetected = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity_add_scanner);
final int height = getSurfaceViewHeight();
final int width = getSurfaceViewWidth();
cameraPreview = findViewById(R.id.surfaceview_scanner);
barcodeDetector = new BarcodeDetector.Builder(AddScanningActivity.this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
cameraSource = new CameraSource.Builder(AddScanningActivity.this, barcodeDetector)
.setAutoFocusEnabled(true)
.setRequestedPreviewSize(width, height)
.build();
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0 && !codeDetected) {
codeDetected = true;
Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(100);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
cameraSource.release();
}
});
}
}
});
cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AddScanningActivity.this,
new String[]{Manifest.permission.CAMERA}, requestCameraPermissionID);
return;
}
try {
cameraSource.start(cameraPreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}, 100);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
}
private Integer getSurfaceViewHeight() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Integer screenHeight = size.y;
Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
final int statusBarHeight = rectangle.top;
int[] attrs = new int[] {R.attr.actionBarSize};
TypedArray ta = this.obtainStyledAttributes(attrs);
final int actionBarHeight = ta.getDimensionPixelSize(0, -1);
ta.recycle();
return screenHeight - statusBarHeight - actionBarHeight;
}
private Integer getSurfaceViewWidth() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size.x;
}
}