使用zxing实现二维码的扫描功能

来源:互联网 发布:烟花特效软件 编辑:程序博客网 时间:2024/05/01 23:11

转载请注明出处,http://blog.csdn.net/bule_zst/article/details/74387281


首先,下载zxing的项目包 下载地址

解压后如下图所示

这里写图片描述

新建一个android项目,并进行以下操作

  1. 将zxing android目录下的src中的com文件夹拷贝到项目的
    QRcodeScanner\app\src\main\java目录下(QRcodeScanner为项目名)

  2. 将zxing android-core\src\main\java\com\google\zxing\client\android\camera目录下的CameraConfigurationUtils.Java类拷贝到项目中的
    QRcodeScanner\app\src\main\java\com\google\zxing\client\android\camera目录下

  3. 将zxing android目录下的res资源文件拷贝到项目中相应的位置,它会提示是否覆盖,选择overwrite all

  4. 将core文件夹打包导入
    下载地址,下载内容为zxing的jar包,包含core和javase两个文件夹

之后,替换AndroidManifest.xml中内容

<?xml version="1.0" encoding="utf-8"?>  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.ricky.qrcodesanner"      android:versionCode="1"      android:versionName="1.0" >       <uses-permission android:name="android.permission.CAMERA" />        <uses-permission android:name="android.permission.INTERNET" />        <uses-permission android:name="android.permission.VIBRATE" />        <uses-permission android:name="android.permission.FLASHLIGHT" />        <uses-permission android:name="android.permission.READ_CONTACTS" />        <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />        <uses-sdk          android:minSdkVersion="14"          android:targetSdkVersion="19" />      <uses-feature            android:name="android.hardware.camera"            android:required="false" />        <uses-feature            android:name="android.hardware.camera.front"            android:required="false" />        <uses-feature            android:name="android.hardware.camera.autofocus"            android:required="false" />        <uses-feature            android:name="android.hardware.camera.flash"            android:required="false" />        <uses-feature android:name="android.hardware.screen.landscape" />        <uses-feature            android:name="android.hardware.wifi"            android:required="false" />        <uses-feature android:name="android.hardware.touchscreen" />        <supports-screens            android:anyDensity="true"            android:largeScreens="true"            android:normalScreens="true"            android:smallScreens="true"            android:xlargeScreens="true" />      <application          android:allowBackup="true"          android:icon="@drawable/launcher_icon"        android:label="@string/app_name"          android:theme="@style/AppTheme" >          <activity              android:name=".MainActivity"              android:label="@string/app_name" >              <intent-filter>                  <action android:name="android.intent.action.MAIN" />                  <category android:name="android.intent.category.LAUNCHER" />              </intent-filter>          </activity>           <activity                android:name="com.google.zxing.client.android.CaptureActivity"                android:clearTaskOnLaunch="true"                android:configChanges="orientation|keyboardHidden"                android:screenOrientation="landscape"                android:stateNotNeeded="true"                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"                android:windowSoftInputMode="stateAlwaysHidden" >                <intent-filter>                    <action android:name="com.google.zxing.client.android.SCAN" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>                <intent-filter>                    <action android:name="android.intent.action.VIEW" />                    <category android:name="android.intent.category.DEFAULT" />                    <category android:name="android.intent.category.BROWSABLE" />                    <data                        android:host="zxing.appspot.com"                        android:path="/scan"                        android:scheme="http" />                </intent-filter>                <intent-filter>                    <action android:name="android.intent.action.VIEW" />                    <category android:name="android.intent.category.DEFAULT" />                    <category android:name="android.intent.category.BROWSABLE" />                    <data                        android:host="www.google.com"                        android:path="/m/products/scan"                        android:scheme="http" />                </intent-filter>                <intent-filter>                    <action android:name="android.intent.action.VIEW" />                    <category android:name="android.intent.category.DEFAULT" />                    <category android:name="android.intent.category.BROWSABLE" />                    <data                        android:host="www.google.co.uk"                        android:path="/m/products/scan"                        android:scheme="http" />                </intent-filter>                <intent-filter>                    <action android:name="android.intent.action.VIEW" />                    <category android:name="android.intent.category.DEFAULT" />                    <category android:name="android.intent.category.BROWSABLE" />                    <data                        android:host="scan"                        android:path="/"                        android:scheme="zxing" />                </intent-filter>            </activity>            <activity                android:name="com.google.zxing.client.android.PreferencesActivity"                android:label="@string/preferences_name"                android:stateNotNeeded="true" >            </activity>            <activity                android:name="com.google.zxing.client.android.encode.EncodeActivity"                android:stateNotNeeded="true" >                <intent-filter>                    <action android:name="com.google.zxing.client.android.ENCODE" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>                <intent-filter>                    <action android:name="android.intent.action.SEND" />                    <category android:name="android.intent.category.DEFAULT" />                    <data android:mimeType="text/x-vcard" />                </intent-filter>                <intent-filter>                    <action android:name="android.intent.action.SEND" />                    <category android:name="android.intent.category.DEFAULT" />                    <data android:mimeType="text/plain" />                </intent-filter>            </activity>            <activity                android:name="com.google.zxing.client.android.book.SearchBookContentsActivity"                android:configChanges="orientation|keyboardHidden"                android:label="@string/sbc_name"                android:screenOrientation="landscape"                android:stateNotNeeded="true" >                <intent-filter>                    <action android:name="com.google.zxing.client.android.SEARCH_BOOK_CONTENTS" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>            </activity>            <activity                android:name="com.google.zxing.client.android.share.ShareActivity"                android:screenOrientation="user"                android:stateNotNeeded="true"                android:theme="@android:style/Theme.Light" >                <intent-filter>                    <action android:name="com.google.zxing.client.android.SHARE" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>            </activity>            <activity                android:name="com.google.zxing.client.android.history.HistoryActivity"                android:label="@string/history_title"                android:stateNotNeeded="true" >                <intent-filter>                    <action android:name="android.intent.action.VIEW" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>            </activity>            <activity                android:name="com.google.zxing.client.android.share.BookmarkPickerActivity"                android:label="@string/bookmark_picker_name"                android:stateNotNeeded="true" >                <intent-filter>                    <action android:name="android.intent.action.PICK" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>            </activity>            <activity                android:name="com.google.zxing.client.android.share.AppPickerActivity"                android:configChanges="orientation"                android:label="@string/app_picker_name"                android:stateNotNeeded="true" >                <intent-filter>                    <action android:name="android.intent.action.PICK" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>            </activity>            <activity                android:name="com.google.zxing.client.android.HelpActivity"                android:screenOrientation="user" >                <intent-filter>                    <action android:name="android.intent.action.VIEW" />                    <category android:name="android.intent.category.DEFAULT" />                </intent-filter>            </activity>        </application>  </manifest>

然后,替换MainActivity中的代码

PS: onActivityResult方法中的内容仅供参考,读者可修改成任何满足自己需求的代码

package com.example.thinkpad.qrcodescanner;import android.app.Activity;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;import com.google.zxing.client.android.CaptureActivity;import com.ricky.qrcodesanner.R;public class MainActivity extends Activity {    public static final int SCAN_CODE = 1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button = (Button) findViewById(R.id.scan_button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);                startActivityForResult(intent, SCAN_CODE);            }        });    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        switch (requestCode) {            case SCAN_CODE:                TextView scanResult = (TextView) findViewById(R.id.scan_result);                if (resultCode == RESULT_OK) {                    String result = data.getStringExtra("scan_result");                    scanResult.setText(result);                } else if (resultCode == RESULT_CANCELED) {                    scanResult.setText("没有扫描出结果");                }                break;            default:                break;        }    }}

接着,修改activity_main.xml布局文件,加入id分别为scan_button、scan_result的Button和TextView,代码略

按Ctrl+F9运行一下,会发现有一些报错

  • 修改value/style.xml文件,在resources标签之间添加代码
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">    <!-- Customize your theme here. -->    <item name="colorPrimary">@color/colorPrimary</item>    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>    <item name="colorAccent">@color/colorAccent</item>  </style> 
  • 修改value/color.xml文件,在resources标签之间添加代码
<color name="colorPrimary">#3F51B5</color>  <color name="colorPrimaryDark">#303F9F</color>  <color name="colorAccent">#FF4081</color>
  • 打开AndroidManifest.xml文件,按F2找到错误地方
    这里写图片描述
    在.MainActivity前面添加它的包名
    小技巧:将name双引号里面的内容清空,然后输入Main就会自动提示,选中即可
    这里写图片描述

之后,按Ctrl+F9会显示一大堆R包找不到的报错信息,目前我也没找到比较好的方法,只能一个文件一个文件的修改,将文件首部的import com.google.zxing.client.android.R;删掉,改成项目相应的R包

这里写图片描述

这里推荐一个热键工具Autohotkey,在得知R包的位置后,就可以自己写脚本,一键替换R包位置。

复制正确的R包位置,然后只需要按一次Ctrl+F9,之后反复地按回车即可完成全部替换。

$Enter::send, ^ysend, +{Enter}send, ^vsend, ^{F9}return

之后,替换CaptureActivity中的handleDecode方法,CaptureActivity的位置在
com.google.zxing.client.android

public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {  //  playBeep();      inactivityTimer.onActivity();      lastResult = rawResult;      if(rawResult!=null&&!rawResult.getText().equalsIgnoreCase("")){          Intent intent =new Intent();          intent.putExtra("scan_result", rawResult.getText());          setResult(RESULT_OK, intent);      }else{          setResult(RESULT_CANCELED);      }      CaptureActivity.this.finish();  }  

最后,在MainActivity中动态申请权限(Android6.0之后的要求)

在onCreate中添加

if(ContextCompat.checkSelfPermission( this, "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED ) {            ActivityCompat.requestPermissions( this, new String[]{"android.permission.CAMERA"}, 1);        }        if( ContextCompat.checkSelfPermission( this, "android.permission.WRITE_EXTERNAL_STORAGE" ) != PackageManager.PERMISSION_GRANTED ) {            ActivityCompat.requestPermissions( this, new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"}, 1 );        }

大功告成!

可能在扫描完成后没有显示出结果,那是因为你的TextView没有设置textColor。在这个项目中,默认字体颜色是白色,所以看不到,修改字体颜色为黑色即可。

参考文章,http://blog.csdn.net/rickyfm/article/details/48632911