【问题标题】:How to scan QRCode in android如何在安卓中扫描二维码
【发布时间】:2012-01-12 05:43:09
【问题描述】:

我找到了a tutorial,了解如何扫描条形码。但在我的应用程序中,我必须扫描二维码。如何在 Android 中扫描二维码?

【问题讨论】:

标签: java android qr-code


【解决方案1】:

您可以使用zxing轻松扫描二维码在您的gradle中添加以下依赖项

compile 'com.journeyapps:zxing-android-embedded:3.1.0@aar'
compile 'com.google.zxing:core:3.2.0'

然后在您的ActivityFragment

   IntentIntegrator scanIntegrator = new IntentIntegrator(context);
                scanIntegrator.setPrompt("Scan");
                scanIntegrator.setBeepEnabled(true);
                //The following line if you want QR code
                scanIntegrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES);
                scanIntegrator.setCaptureActivity(CaptureActivityAnyOrientation.class);
                scanIntegrator.setOrientationLocked(true);
                scanIntegrator.setBarcodeImageEnabled(true);
                scanIntegrator.initiateScan();

然后在onActivityResult中捕获结果

   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if (scanningResult != null) {
            if (scanningResult.getContents() != null) {
                scanContent = scanningResult.getContents().toString();
                scanFormat = scanningResult.getFormatName().toString();
            }

            Toast.makeText(this,scanContent+"   type:"+scanFormat,Toast.LENGTH_SHORT).show();

        }else{
            Toast.makeText(this,"Nothing scanned",Toast.LENGTH_SHORT).show();
        }
    }

看看这个sample project,希望对你有帮助。

【讨论】:

  • 什么是 CaptureActivityAnyOrientation?
【解决方案2】:
try {
    Intent intent = new Intent("com.google.zxing.client.android.SCAN");
    intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); // "PRODUCT_MODE for bar codes

    startActivityForResult(intent, 0);
} catch (Exception e) {    
    Uri marketUri = Uri.parse("market://details?id=com.google.zxing.client.android");
    Intent marketIntent = new Intent(Intent.ACTION_VIEW,marketUri);
    startActivity(marketIntent);
}

onActivityResult():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 0) {
        if (resultCode == RESULT_OK) {
            String contents = data.getStringExtra("SCAN_RESULT");
        }
        if(resultCode == RESULT_CANCELLED){
            //handle cancel
        }
    }
}

【讨论】:

  • 我必须在不安装任何其他扫描仪的情况下从我的项目中扫描二维码。这可能吗?请提出您的建议。
  • @sandhya.M 是的,有办法。您必须下载 Zxing 的源代码。它的开源。生成 core.jar 文件并将其添加为外部 jar。
  • 只有 core.jar 文件就足够了。或者任何其他源文件我也必须添加它
  • 不行,只能用core.jar编译
  • 我只是这样做了。但是我无法扫描二维码。
【解决方案3】:

一种方法是使用 AppCompatActivity 和 ZXingScannerView.ResultHandler 接口。

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;;

import com.android.volley.VolleyError;
import com.example.team.merchant.functional.Request;
import com.example.team.merchant.functional.ResponseListener;
import com.google.zxing.Result;

import me.dm7.barcodescanner.zxing.ZXingScannerView;

/**
 * Created by Prakhar on 5/16/2016.
 */
public class MerchantScannerActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler {
    private ZXingScannerView mScannerView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        RelativeLayout relativeLayout = new RelativeLayout(this);

        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(60, 60);
        params.setMargins(0, 50, 50, 0);
        params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);


        Button switchCamera = new Button(this); //declare a button in layout for camera change option
        switchCamera.setLayoutParams(params);
        switchCamera.setBackgroundResource(R.drawable.switch_camera);
        relativeLayout.addView(switchCamera);
        final int i = getFrontCameraId();
        if (i == -1) {
            switchCamera.setVisibility(View.GONE);
        }


        mScannerView = new ZXingScannerView(this);   // Programmatically initialize the scanner view
        relativeLayout.addView(mScannerView);

        setContentView(relativeLayout);
        final int[] id = {0};
        switchCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mScannerView.stopCamera();
                if (id[0] % 2 == 0) {
                    mScannerView.startCamera(i);
                } else {
                    mScannerView.startCamera();
                }
                id[0]++;
            }
        });

        mScannerView.setResultHandler(this);// Register ourselves as a handler for scan results.

        mScannerView.startCamera();         // Start camera


    }

    @SuppressLint("NewApi")
    int getFrontCameraId() {
        if (Build.VERSION.SDK_INT < 22) {
            Camera.CameraInfo ci = new Camera.CameraInfo();
            for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
                Camera.getCameraInfo(i, ci);
                if (ci.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) return i;
            }
        } else {
            try {
                CameraManager cManager = (CameraManager) getApplicationContext()
                        .getSystemService(Context.CAMERA_SERVICE);
                String[] cameraId = cManager.getCameraIdList();
                for (int j = 0; j < cameraId.length; j++) {
                    CameraCharacteristics characteristics = cManager.getCameraCharacteristics(cameraId[j]);
                    int cOrientation = characteristics.get(CameraCharacteristics.LENS_FACING);
                    if (cOrientation == CameraCharacteristics.LENS_FACING_FRONT)
                        return Integer.parseInt(cameraId[j]);
                }
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }
        return -1; // No front-facing camera found
    }

    @Override
    public void onPause() {
        super.onPause();
        mScannerView.stopCamera();           // Stop camera on pause
    }

    @Override
    public void handleResult(Result rawResult) {
       // rawResult.getText()
       // handle your result here
       // handle exceptions here
    }
}

Other 可以相应地在片段中使用。

import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.CompoundBarcodeView;


/**
 * Created by Prakhar on 3/8/2016.
 */
public class PayWithQrCodeScannerFragment extends Fragment {

    private static final int PERMISSION_REQUEST_CAMERA = 23;
    public static CompoundBarcodeView barcodeScannerView;
    public static BarcodeCallback callback;



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.paywithqrcodescannerfragment, container, false);

        barcodeScannerView = (CompoundBarcodeView) view.findViewById(R.id.zxing_barcode_scanner);


        callback = new BarcodeCallback() {
            @Override
            public void barcodeResult(BarcodeResult result) {
                    // handle result and exceptions here
            }
        return view;
    }

    /**
     * Check if the device's camera has a Flashlight.
     *
     * @return true if there is Flashlight, otherwise false.
     */
    private boolean hasFlash() {
        return getActivity().getApplicationContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    }


    @Override
    public void onResume() {
        super.onResume();
        if (android.os.Build.VERSION.SDK_INT < 23) {
            barcodeScannerView.resume();
        }
    }


    @Override
    public void onPause() {
        super.onPause();
        if (android.os.Build.VERSION.SDK_INT < 23) {
            barcodeScannerView.pause();
        }
    }

}

使用下面编写的布局 XML 文件来占位扫描仪

<com.journeyapps.barcodescanner.CompoundBarcodeView
            android:id="@+id/zxing_barcode_scanner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:zxing_preview_scaling_strategy="centerCrop"
            app:zxing_use_texture_view="false" />

构建.gradle

compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
compile 'com.google.zxing:core:3.2.1'

【讨论】:

    【解决方案4】:

    我的方法是使用barcodescanner。我使用zxing 扫描条形码和二维码。库的版本1.9 使用zxing v3.2.1。它是zxing 的包装器,因此使用更简单。

    为了做到这一点:

    1. 为 gradle 添加依赖

      compile 'me.dm7.barcodescanner:zxing:1.9'
      
    2. 将相机权限添加到清单

      <uses-permission android:name="android.permission.CAMERA"/>
      
    3. 创建将处理扫描的活动

      清单:

      <activity
          android:name=".view.component.ScannerActivity"
          android:label="@string/app_name"
          android:screenOrientation="portrait"
          android:theme="@style/AppThemeTransparent"/>
      

      styles.xml:

      <style name="AppThemeTransparent" parent="@style/Theme.AppCompat.Light">
          <item name="windowNoTitle">true</item>
          <item name="windowActionBar">false</item>
          <item name="colorPrimary">@color/colorPrimary</item>
          <item name="android:windowFullscreen">true</item>
          <item name="android:windowContentOverlay">@null</item>
      </style>
      

      创建扫描仪活动:

      import android.app.Activity;
      import android.content.Intent;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.WindowManager;
      
      import com.google.zxing.BarcodeFormat;
      import com.google.zxing.Result;
      
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.List;
      
      import me.dm7.barcodescanner.zxing.ZXingScannerView;
      
      public class ScannerActivity extends Activity implements ZXingScannerView.ResultHandler {
      
          public static final String EXCLUDED_FORMAT = "ExcludedFormat";
          private static final String TAG = ScannerActivity.class.getSimpleName();
          private ZXingScannerView mScannerView;
      
          @Override
          public void onCreate(Bundle state) {
              setStatusBarTranslucent(true);
              super.onCreate(state);
              mScannerView = new ZXingScannerView(this);
              setContentView(mScannerView);
          }
      
          protected void setStatusBarTranslucent(boolean makeTranslucent) {
              if (makeTranslucent) {
                  getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
              } else {
                  getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
              }
          }
      
          @Override
          public void onResume() {
              super.onResume();
              mScannerView.setResultHandler(this);
              mScannerView.startCamera();
          }
      
          @Override
          public void onPause() {
              super.onPause();
              mScannerView.stopCamera();
          }
      
          @Override
          public void handleResult(Result rawResult) {
              String result = rawResult.getText();
              BarcodeFormat format = rawResult.getBarcodeFormat();
      
              Log.v(TAG, "Scanned code: " + rawResult.getText());
              Log.v(TAG, "Scanend code type: " + rawResult.getBarcodeFormat().toString());
      
              //Return error
              if (result == null) {
                  setResult(RESULT_CANCELED, returnErrorCode(result, format));
                  finish();
              }
      
              if (result.isEmpty()) {
                  setResult(RESULT_CANCELED, returnErrorCode(result, format));
                  finish();
              }
      
              //Return correct code
              setResult(RESULT_OK, returnCorrectCode(result, format));
              finish();
          }
      
          private Intent returnErrorCode(String result, BarcodeFormat format) {
              Intent returnIntent = new Intent();
              returnIntent.putExtra(ScannerConstants.ERROR_INFO, getResources().getString(R.string.scanner_error_message));
              return returnIntent;
          }
      
          private Intent returnCorrectCode(String result, BarcodeFormat format) {
              Intent returnIntent = new Intent();
              returnIntent.putExtra(ScannerConstants.SCAN_RESULT, result);
      
              if (format.equals(BarcodeFormat.QR_CODE)) {
                  returnIntent.putExtra(ScannerConstants.SCAN_RESULT_TYPE, ScannerConstants.QR_SCAN);
              } else {
                  returnIntent.putExtra(ScannerConstants.SCAN_RESULT_TYPE, ScannerConstants.BAR_SCAN);
              }
      
              return returnIntent;
          }
      
          public void excludeFormats(BarcodeFormat item) {
              Collection<BarcodeFormat> defaultFormats = mScannerView.getFormats();
              List<BarcodeFormat> formats = new ArrayList<>();
              for (BarcodeFormat format : defaultFormats) {
                  if (!format.equals(item)) {
                      formats.add(format);
                  }
              }
              mScannerView.setFormats(formats);
          }
      
          public interface ScannerConstants {
              public static final String SCAN_MODES = "SCAN_MODES";
              public static final String SCAN_RESULT = "SCAN_RESULT";
              public static final String SCAN_RESULT_TYPE = "SCAN_RESULT_TYPE";
              public static final String ERROR_INFO = "ERROR_INFO";
              public static final int BAR_SCAN = 0;
              public static final int QR_SCAN = 1;
          }
      }
      

      请确保,在 API 23+ 设备上,应用程序已授予使用相机的权限。

      打开Activity 就像正常的一样期待结果:

      Intent intent = new Intent(AddEquipmentActivity.this, ScannerActivity.class);
      startActivityForResult(intent, SCAN_SERIAL_REQUEST);
      

    【讨论】:

      【解决方案5】:

      2016 年更新

      目前的建议是使用Android Barcode API,它工作locally(离线),without需要一个服务器往返:

      条形码 API 在设备上以任何方向实时检测条形码。它还可以一次检测多个条码。

      它读取以下条码格式:

      • 一维条码:EAN-13、EAN-8、UPC-A、UPC-E、Code-39、Code-93、Code-128、ITF、Codabar
      • 二维条码:二维码、数据矩阵、PDF-417、AZTEC

      它会自动解析二维码、数据矩阵、PDF-417 和 Aztec 值,支持以下格式:

      • 网址
      • 联系信息(VCARD 等)
      • 日历活动
      • 电子邮件
      • 电话
      • 短信
      • 国际标准书号
      • 无线网络
      • 地理位置(经纬度)
      • AAMVA 驾驶执照/身份证

      查看代码实验室 - Barcode Detection with the Mobile Vision API

      【讨论】:

        【解决方案6】:

        这是扫描二维码的function

        public void scanQR(View v)
        {
            try
            {
                Intent intent = new Intent(ACTION_SCAN);
                intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
                startActivityForResult(intent, 0);
            }
            catch (ActivityNotFoundException anfe)
            {
                showDialog(ActivityUserDetails.this, "No Scanner Found",
                        "Download a scanner code activity?", "Yes", "No").show();
            }
        }
        

        在上面的代码 sn-p 中,我从 catch 块中调用了 showDialog() 方法,这将显示一个 AlertDialog 要求从 Google Play 安装“条形码扫描仪”应用程序。下面给出了showDialog 方法的代码。

        private static AlertDialog showDialog(final Activity act,
                                              CharSequence title, CharSequence message, CharSequence buttonYes,
                                              CharSequence buttonNo)
        {
            AlertDialog.Builder downloadDialog = new AlertDialog.Builder(act);
            downloadDialog.setTitle(title);
            downloadDialog.setMessage(message);
            downloadDialog.setPositiveButton(buttonYes,
                    new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialogInterface, int i)
                        {
                            Uri uri = Uri.parse("market://search?q=pname:"
                                    + "com.google.zxing.client.android");
                            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                            try
                            {
                                act.startActivity(intent);
                            }
                            catch (ActivityNotFoundException anfe)
                            {
        
                            }
                        }
                    });
                    downloadDialog.setNegativeButton(buttonNo,
                    new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialogInterface, int i)
                        {
                        }
                    });
                    return downloadDialog.show();
        }
        

        我在Button点击事件中使用了这个功能。因此Button 的代码如下(xml 文件)。

                            <Button
                            android:id="@+id/button_wr_scan"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:layout_margin="5dp"
                            android:background="@drawable/button_shadow"
                            android:onClick="scanQR"
                            android:paddingRight="4dp"
                            android:paddingTop="4dp"
                            android:text="ScanQR" />
        

        注意:使用此功能的前提是您必须在您的设备中预先安装“条形码扫描仪”应用程序。

        希望对您有所帮助。

        谢谢:)

        【讨论】:

          【解决方案7】:

          在eclipse中逐步设置zxing 3.2.1

          1. 从“https://github.com/zxing/zxing”下载zxing-master.zip
          2. 解压zxing-master.zip,使用eclipse在zxing-master中导入“android”项目
          3. 从“http://repo1.maven.org/maven2/com/google/zxing/core/3.2.1/”下载 core-3.2.1.jar
          4. 在“android”项目中创建“libs”文件夹并将cor-3.2.1.jar粘贴到libs文件夹中
          5. 单击项目:选择“属性”->“Java 编译器”将级别更改为 1.7。然后点击“Android”将“Project build target”改为android 4.4.2+,因为使用1.7需要用Android 4.4编译
          6. 如果“zxing-master/android/app/src/main/java/com/google/zxing/client/android/camera/”中不存在“CameraConfigurationUtils.java”。您可以从“zxing-master/android-core/src/main/java/com/google/zxing/client/android/camera/”复制并粘贴到您的项目中。
          7. 清理并构建项目。如果您的项目显示有关“switch - case”的错误,则应将其更改为“if - else”。
          8. 已完成。清理并构建项目 参考链接:How to use Zxing in android

          【讨论】:

            【解决方案8】:

            模块分级

            dependencies {
                implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
            }
            

            活动.kt

            package com.example.qrcode
            
            import android.content.Intent
            import android.os.Bundle
            import android.widget.Button
            import android.widget.ImageButton
            import android.widget.Toast
            import androidx.appcompat.app.AppCompatActivity
            import androidx.appcompat.app.AppCompatDelegate
            import com.google.android.material.internal.ContextUtils.getActivity
            import com.google.zxing.integration.android.IntentIntegrator
            import com.google.zxing.integration.android.IntentResult
            
            class LicenseCheck : AppCompatActivity() {
            
                override fun onCreate(savedInstanceState: Bundle?) {
            
                    super.onCreate(savedInstanceState)
                    setContentView(R.layout.licensecheck)
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            
                    fun checklicense(license: String){
                        Toast.makeText(this, license, Toast.LENGTH_SHORT).show()
                    }
                    val scanbtn = findViewById(R.id.qrscanner) as ImageButton
                    scanbtn.setOnClickListener {
                        val integrator = IntentIntegrator(this)
                        integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
                        integrator.setPrompt("Focus QRCode from App...")
                        integrator.setCameraId(0)
                        integrator.setBeepEnabled(true)
                        integrator.setBarcodeImageEnabled(false)
                        integrator.initiateScan()
                    }
                    @Override
                    fun onActivityResult(requestCode:Int, resultCode:Int, data: Intent) {
                        var result: IntentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
                        if (result.getContents() == null) {
                            Toast.makeText(this, "Scanning failed!", Toast.LENGTH_LONG).show();
                        } else {
                            checklicense(result.getContents());
                        }
                    }
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-07-20
              • 2019-06-12
              • 2012-11-04
              相关资源
              最近更新 更多