Java 使用摄像头扫描二维码导致应用程序崩溃|可能修复?
我正在尝试使用设备摄像头和移动视觉API扫描二维码。为此,我创建了一个Java 使用摄像头扫描二维码导致应用程序崩溃|可能修复?,java,android,camera,Java,Android,Camera,我正在尝试使用设备摄像头和移动视觉API扫描二维码。为此,我创建了一个SurfaceView,将图像流提取到SurfaceView,并启用了条码检测器,然后使用所需的方法读取检测到的二维码。以下是活动的代码: QrScanActivity.class public class QrScanActivity extends AppCompatActivity { private SurfaceView cameraView; private TextView barcodeInfo
SurfaceView
,将图像流提取到SurfaceView
,并启用了条码检测器
,然后使用所需的方法读取检测到的二维码。以下是活动的代码:
QrScanActivity.class
public class QrScanActivity extends AppCompatActivity
{
private SurfaceView cameraView;
private TextView barcodeInfo;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
private static final String TAG = "QR_ACTIVITY";
private static final int REQUEST_CAMERA = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qr_scan);
cameraView = (SurfaceView) findViewById(R.id.camera_view);
barcodeInfo = (TextView) findViewById(R.id.code_info);
barcodeDetector =
new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(QrScanActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
}
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException ie) {
Log.e("CAMERA SOURCE", ie.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
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) {
barcodeInfo.post(new Runnable() { // Use the post method of the TextView
public void run() {
barcodeInfo.setText( // Update the TextView
barcodes.valueAt(0).displayValue
);
}
});
}
}
});
}
private void requestCameraPermission() {
Log.i("CAM","CAMERA permission has NOT been granted. Requesting permission.");
// BEGIN_INCLUDE(camera_permission_request)
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA))
{
Snackbar.make(findViewById(android.R.id.content), R.string.permission_camera_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(QrScanActivity.this,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
})
.show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
// END_INCLUDE(camera_permission_request)
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA)
{
Log.i(TAG, "Received response for Camera permission request.");
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "CAMERA permission has now been granted. Showing preview.");
Snackbar.make(findViewById(android.R.id.content), R.string.permision_available_camera,
Snackbar.LENGTH_SHORT).show();
} else {
Log.i(TAG, "CAMERA permission was NOT granted.");
Snackbar.make(findViewById(android.R.id.content), R.string.permissions_not_granted,
Snackbar.LENGTH_SHORT).show();
}
}
else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
公共类QrScanActivity扩展了AppCompatActivity
{
私人水面观景摄像师;
私有文本视图条码信息;
专用条码检测器条码检测器;
私人摄像源摄像源;
私有静态最终字符串TAG=“QR\U活动”;
专用静态最终int请求\u摄像机=0;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u qr\u scan);
cameraView=(SurfaceView)findViewById(R.id.camera\U视图);
barcodeInfo=(TextView)findViewById(R.id.code\u信息);
条形码检测器=
新条形码检测器.Builder(此)
.setBarcodeFormats(条形码.QR\U码)
.build();
cameraSource=新的cameraSource
.Builder(这是条形码检测器)
.setRequestedPreviewSize(640480)
.build();
cameraView.getHolder().addCallback(新的SurfaceHolder.Callback()){
@凌驾
已创建的公共空白表面(表面持有人){
if(ActivityCompat.checkSelfPermission(QrScanActivity.this、Manifest.permission.CAMERA)
!=PackageManager.权限(已授予){
requestCameraPermission();
}
试一试{
cameraSource.start(cameraView.getHolder());
}捕获(IOIE){
Log.e(“摄像机源”,即getMessage());
}
}
@凌驾
公共空白表面更改(表面文件夹持有者、整型格式、整型宽度、整型高度){
}
@凌驾
公共空间表面覆盖(表面覆盖物持有人){
cameraSource.stop();
}
});
条形码检测器.setProcessor(新检测器.Processor(){
@凌驾
公开无效释放(){
}
@凌驾
公共空隙接收检测(检测器。检测){
最终SparseArray条形码=检测。getDetectedItems();
如果(条形码大小()!=0){
post(new Runnable(){//使用TextView的post方法
公开募捐{
barcodeInfo.setText(//更新TextView
条形码.valueAt(0).显示值
);
}
});
}
}
});
}
私有void requestCameraPermission(){
Log.i(“CAM”,“尚未授予摄像头权限。正在请求权限”);
//开始包括(摄像机许可请求)
if(ActivityCompat.shouldshowRequestPermissionRegulation(这是Manifest.permission.CAMERA))
{
Snackbar.make(findviewbyd(android.R.id.content)、R.string.permission\u camera\u原理、,
蛇形杆。长度(不确定)
.setAction(R.string.ok,new View.OnClickListener(){
@凌驾
公共void onClick(视图){
ActivityCompat.requestPermissions(QrScanActivity.this,
新字符串[]{Manifest.permission.CAMERA},
请求(摄像头);
}
})
.show();
}否则{
ActivityCompat.requestPermissions(这个新字符串[]{Manifest.permission.CAMERA},
请求(摄像头);
}
//结束包括(摄像机许可请求)
}
@凌驾
public void onRequestPermissionsResult(int-requestCode,@NonNull字符串[]权限,
@非空int[]grantResults){
if(requestCode==请求\摄像机)
{
Log.i(标记“已收到照相机许可请求的响应”);
if(grantResults.length==1&&grantResults[0]==PackageManager.PERMISSION\u已授予){
Log.i(标记“相机权限已授予。显示预览”);
Snackbar.make(findviewbyd(android.R.id.content)、R.string.permission\u available\u camera、,
Snackbar.LENGTH_SHORT).show();
}否则{
Log.i(标记“未授予相机许可”);
Snackbar.make(findviewbyd(android.R.id.content)、R.string.permissions\u not\u provided、,
Snackbar.LENGTH_SHORT).show();
}
}
否则{
super.onRequestPermissionsResult(请求代码、权限、授权结果);
}
}
}
活动\u qr\u scan.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_qr_scan"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:layout_width="400dp"
android:layout_height="280dp"
android:layout_marginTop="30dp"
android:id="@+id/camera_view"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/code_info"
android:layout_below="@+id/camera_view"
android:textSize="20sp"
android:layout_marginTop="30dp"
android:layout_centerHorizontal="true"
android:text="Nothing to read."
/>
</RelativeLayout>
运行应用程序时获得的logcat:
Logcat
E/AndroidRuntime:致命异常:主
进程:com.shreybank.shrey,PID:12044
java.lang.RuntimeException:无法连接到摄影机服务
在android.hardware.Camera。(Camera.java:518)
打开(Camera.java:360)
位于com.google.android.gms.vision.CameraSource.zzBZ(未知来源)
位于com.google.android.gms.vision.CameraSource.start(未知源)
在com.shreybank.shrey.activities.QrScanActivity$1.surfaceCreated(QrScanActivity.jav
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_READ_CAMERA);
}
else {
// Already grant Camera permission. Now call your QR scan Activity
}
}else {
// call your QR scan Activity
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_READ_CAMERA: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission has granted . Call the QR scan Activity
} else {
// permission denied
}
return;
}
}
}
public class QrScanActivity extends AppCompatActivity
{
private SurfaceView cameraView;
private TextView barcodeInfo;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
private static final String TAG = "QR_ACTIVITY";
private static final int REQUEST_CAMERA = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qr_scan);
int permissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA);
if(permissionCheck == PackageManager.PERMISSION_GRANTED)
initCameraSource
else
requestCameraPermission();
}
private void requestCameraPermission() {
Log.i("CAM","CAMERA permission has NOT been granted. Requesting permission.");
// BEGIN_INCLUDE(camera_permission_request)
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA))
{
Snackbar.make(findViewById(android.R.id.content), R.string.permission_camera_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(QrScanActivity.this,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
})
.show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
// END_INCLUDE(camera_permission_request)
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA)
{
Log.i(TAG, "Received response for Camera permission request.");
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "CAMERA permission has now been granted. Showing preview.");
initCameraSource();
} else {
Log.i(TAG, "CAMERA permission was NOT granted.");
Snackbar.make(findViewById(android.R.id.content), R.string.permissions_not_granted,
Snackbar.LENGTH_SHORT).show();
}
}
else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void initCameraSource(){
cameraView = (SurfaceView) findViewById(R.id.camera_view);
barcodeInfo = (TextView) findViewById(R.id.code_info);
barcodeDetector =
new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(QrScanActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
}
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException ie) {
Log.e("CAMERA SOURCE", ie.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
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) {
barcodeInfo.post(new Runnable() { // Use the post method of the TextView
public void run() {
barcodeInfo.setText( // Update the TextView
barcodes.valueAt(0).displayValue
);
}
});
}
}
});
}
}