QR码扫描摄像头在Android Studio中无法正常工作。

huangapple go评论73阅读模式
英文:

QR code scanne camera not working properly in android studio

问题

I am working on QR code scanner project. I took two activity such as main and scan. There are one EditText view and one button in the main activity. Here If you click on button scan activity run and scan QR code. Then the result will be showed in EditText. When I click on the button, at first all works properly. But clicking further more, it will not show the result in EditText.

Here is the MainAcivity.java:

package com.example.scanner_v1;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {
   private static final int REQUEST_CODE_SCAN = 100;
   private EditText editText;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

    editText = findViewById(R.id.editText);
    Button scanButton = findViewById(R.id.scanButton);
    scanButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, ScanActivity.class);
            startActivityForResult(intent, REQUEST_CODE_SCAN);
        }
    });
 }

 @Override
 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(resultCode, resultCode, data);
    if (requestCode == REQUEST_CODE_SCAN && resultCode == RESULT_OK && data != null) {
        String barcode = data.getStringExtra("barcode");
        editText.setText(barcode);
    }
 }
}

Here is the ScanActivity.java:

package com.example.scanner_v1;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.SurfaceView;
import android.widget.Toast;

import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;

import java.io.IOException;

public class ScanActivity extends AppCompatActivity {
   private static final int PERMISSION_REQUEST_CAMERA = 1;
   private SurfaceView surfaceView;
   private BarcodeDetector barcodeDetector;
   private CameraSource cameraSource;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_scan);

    surfaceView = findViewById(R.id.surfaceView);

    // Create BarcodeDetector and CameraSource
    barcodeDetector = new BarcodeDetector.Builder(this)
            .setBarcodeFormats(Barcode.QR_CODE)
            .build();
    cameraSource = new CameraSource.Builder(this, barcodeDetector)
            .setRequestedPreviewSize(640, 480)
            .setAutoFocusEnabled(true)
            .build();

    // Check for camera permission
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !=
          PackageManager.PERMISSION_GRANTED) {
         ActivityCompat.requestPermissions(this, new String[]
         {Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);
      } else {
        startCamera();
      }
   }

   private void startCamera() {
     try {
         if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !=
            PackageManager.PERMISSION_GRANTED) {
             return;
        }
        cameraSource.start(surfaceView.getHolder());
     } catch (IOException e) {
         e.printStackTrace();
     }

    barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
        @Override
        public void release() {

        }

        @Override
        public void receiveDetections(Detector.Detections<Barcode> detections) {
            SparseArray<Barcode> barcodes = detections.getDetectedItems();
            if (barcodes.size() > 0) {
                String barcodeValue = barcodes.valueAt(0).displayValue;
                Intent intent = new Intent();
                intent.putExtra("barcode", barcodeValue);
                setResult(RESULT_OK, intent);
                finish();
             }
         }
      });
 }

 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
 @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == PERMISSION_REQUEST_CAMERA) {
        if (grantResults.length > 0 && grantResults[0] ==
            PackageManager.PERMISSION_GRANTED) {
            startCamera();
        } else {
            Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show();
        }
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    barcodeDetector.release();
    cameraSource.release();
}
private stopCamera() {
    if (cameraSource != null) {
        cameraSource.stop();
    }
}

@Override
protected void onResume() {
    super.onResume();
    startCamera(); // Restart the camera preview when the activity resumes
}

  @Override
  protected void onPause() {
      super.onPause();
      stopCamera(); // Stop the camera preview when the activity pauses
  }
}

Here is the build.gradle file:

plugins {
    id 'com.android.application'
 }

android {
namespace 'com.example.scanner_v1'
compileSdk 33

defaultConfig {
    applicationId "com.example.scanner_v1"
    minSdk 24
    targetSdk 33
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}


 buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
        'proguard-rules.pro'
     }
 }
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
 }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    //Barcode
    implementation 'com.google.android.gms:play-services-vision:20.1.3'

}

Can you please suggest me a possible solution to solve this issue?

英文:

I am working on QR code scanner project. I took two activity such as main and scan. There are one EditText view and one button in the main activity. Here If you click on button scan activity run and scan QR code. Then the result will be showed in EditText. When I click on the button, at first all works properly. But clicking further more, it will not show the result in EditText.

Here is the MainAcivity.java:

    package com.example.scanner_v1;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE_SCAN = 100;
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editText);
Button scanButton = findViewById(R.id.scanButton);
scanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,ScanActivity.class);
startActivityForResult(intent,REQUEST_CODE_SCAN);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode,@Nullable Intent data){
super.onActivityResult(resultCode,resultCode,data);
if(requestCode == REQUEST_CODE_SCAN &amp;&amp; resultCode == RESULT_OK &amp;&amp; data != null){
String barcode = data.getStringExtra(&quot;barcode&quot;);
editText.setText(barcode);
}
}
}

Here is the ScanActivity.java:

package com.example.scanner_v1;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.SurfaceView;
import android.widget.Toast;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
public class ScanActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CAMERA = 1;
private SurfaceView surfaceView;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
surfaceView = findViewById(R.id.surfaceView);
// Create BarcodeDetector and CameraSource
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setAutoFocusEnabled(true)
.build();
// Check for camera permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != 
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] 
{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);
} else {
startCamera();
}
}
private void startCamera() {
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != 
PackageManager.PERMISSION_GRANTED) {
return;
}
cameraSource.start(surfaceView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
barcodeDetector.setProcessor(new Detector.Processor&lt;Barcode&gt;() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections&lt;Barcode&gt; detections) {
SparseArray&lt;Barcode&gt; barcodes = detections.getDetectedItems();
if (barcodes.size() &gt; 0) {
String barcodeValue = barcodes.valueAt(0).displayValue;
Intent intent = new Intent();
intent.putExtra(&quot;barcode&quot;, barcodeValue);
setResult(RESULT_OK, intent);
finish();
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CAMERA) {
if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == 
PackageManager.PERMISSION_GRANTED) {
startCamera();
} else {
Toast.makeText(this, &quot;Camera permission denied&quot;, Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
barcodeDetector.release();
cameraSource.release();
}
private void stopCamera() {
if (cameraSource != null) {
cameraSource.stop();
}
}
@Override
protected void onResume() {
super.onResume();
startCamera(); // Restart the camera preview when the activity resumes
}
@Override
protected void onPause() {
super.onPause();
stopCamera(); // Stop the camera preview when the activity pauses
}
}

Here is the build.gradle file:

    plugins {
id &#39;com.android.application&#39;
}
android {
namespace &#39;com.example.scanner_v1&#39;
compileSdk 33
defaultConfig {
applicationId &quot;com.example.scanner_v1&quot;
minSdk 24
targetSdk 33
versionCode 1
versionName &quot;1.0&quot;
testInstrumentationRunner &quot;androidx.test.runner.AndroidJUnitRunner&quot;
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(&#39;proguard-android-optimize.txt&#39;), 
&#39;proguard-rules.pro&#39;
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation &#39;androidx.appcompat:appcompat:1.6.1&#39;
implementation &#39;com.google.android.material:material:1.8.0&#39;
implementation &#39;androidx.constraintlayout:constraintlayout:2.1.4&#39;
testImplementation &#39;junit:junit:4.13.2&#39;
androidTestImplementation &#39;androidx.test.ext:junit:1.1.5&#39;
androidTestImplementation &#39;androidx.test.espresso:espresso-core:3.5.1&#39;
//Barcode
implementation &#39;com.google.android.gms:play-services-vision:20.1.3&#39;
}

Can you please suggest me a possible solution to solve this issue?

答案1

得分: 1

将初始化代码移到startCamera()方法之外,因为在单击startCamera()时再次对cameraSourcebarcodeDetector进行重新初始化,对象应该在ScanActivity的onCreate()方法中仅初始化一次。

在您的ScanActivity中覆盖onBackPressed()方法,并调用finish()来关闭活动并释放摄像头对象。

以下是来自您示例的代码片段:

onCreate()方法中执行以下操作:

private static final int PERMISSION_REQUEST_CAMERA = 1;
private SurfaceView surfaceView;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_scan);

    surfaceView = findViewById(R.id.surfaceView);

    barcodeDetector = new BarcodeDetector.Builder(this)
        .setBarcodeFormats(Barcode.QR_CODE)
        .build();
    cameraSource = new CameraSource.Builder(this, barcodeDetector)
        .setRequestedPreviewSize(640, 480)
        .setAutoFocusEnabled(true)
        .build();

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !=
        PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]
        {Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);
    } else {
        startCamera();
    }
}

更新onDestroy()onBackPressed()如下:

@Override
protected void onDestroy() {
    super.onDestroy();
    if (barcodeDetector != null) {
        barcodeDetector.release();
    }
    if (cameraSource != null) {
        cameraSource.stop();
        cameraSource.release();
    }
}

@Override
public void onBackPressed() {
    finish();
}
英文:

Move the initialization code out of the startCamera() method as you are reinitializing cameraSource and barcodeDetector again when you are clicking on startCamera(), objects should be initialized only once in the onCreate() method of the ScanActivity.

In your ScanActivity Override the onBackPressed() method and call finish() to close the activity and release the camera objects.


Here is a sample snippet from your example:

Do following in onCreate() funtion:

private static final int PERMISSION_REQUEST_CAMERA = 1;
private SurfaceView surfaceView;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
surfaceView = findViewById(R.id.surfaceView);
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setAutoFocusEnabled(true)
.build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != 
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] 
{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);
} else {
startCamera();
}
}

Update onDestroy() & onBackPressed() like this:

@Override
protected void onDestroy() {
super.onDestroy();
if (barcodeDetector != null) {
barcodeDetector.release();
}
if (cameraSource != null) {
cameraSource.stop();
cameraSource.release();
}
}
@Override
public void onBackPressed() {
finish();
}

huangapple
  • 本文由 发表于 2023年3月8日 16:20:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75670715.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定