如何在一个原有的工程中实现二维码扫码功能呢?那么Zxing这个库你就必须得用上了,大部分二维码扫码都是使用的Zxing这个库,所以,我在自己的原有工程的基础上,使用Zxing来实现二维码扫码功能。

ZXing (“Zebra Crossing”) 是Java和Android的二维码扫码库。可以支持多种扫码图片(1D/2D)。Github地址为:Zxing的Github地址

下面主要来讲下如何来在自己的原有项目中去集成Zxing库。

1. 下载zxing源代码

下载地址为:Zxing源代码下载。选择其中一个压缩格式下载即可。这里我选择的是zip格式的(tar.gz一般都是Linux系统使用的,不过Windows下系统有些压缩软件也是可以解压的)。

然后对下载下来的源代码压缩包Zxing3.4.0进行解压,解压后的文件如下图所示。

这里主要关注的是与android有关的。

2. 加入zxing依赖

打开Module:appbuild.gralde文件,然后添加zxing依赖implementation 'com.google.zxing:core:3.4.0'。如下图所示。

3. 复制Zxing的android到工程目录中

打开zxing源代码,然后一直打开到\zxing-zxing-3.4.0\android\src\com目录,然后右键复制,如下图所示。

打开自己的工程目录直到java/目录下,然后将复制的com/目录下的代码添加到这个目录下,如下图所示。

复制后,可以查看Android Studio的工程名目录如下图。

4. 向AndroidManifest.xml添加代码

打开zxing源文件代码目录\zxing-zxing-3.4.0\android,然后打开AndroidManifest.xml文件。

4.1. 添加权限

复制AndroidManifest.xml中的权限代码到自己的工程的AndroidManifest.xml中,复制的权限代码如下:

    <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"/>
    <!-- unavailable in API 23 -->
    <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-feature android:name="android.hardware.camera.any"/>
    <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"/>

复制后的自己工程中的AndroidManifest.xml文件如下图所示:

4.2. 添加activity等代码到AndroidManifest中

添加如下代码到AndroidManifest.xml文件中的<application>节点里面。

 <activity android:name="com.google.zxing.client.android.CaptureActivity"
            android:screenOrientation="sensorLandscape"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:theme="@style/CaptureTheme"
            android:windowSoftInputMode="stateAlwaysHidden">

            <intent-filter>
                <action android:name="com.google.zxing.client.android.SCAN"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
            <!-- Allow web apps to launch Barcode Scanner by linking to http://zxing.appspot.com/scan. -->
            <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:scheme="http" android:host="zxing.appspot.com" android:path="/scan"/>
            </intent-filter>
            <!-- We also support a Google Product Search URL. -->
            <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:scheme="http" android:host="www.google.com" android:path="/m/products/scan"/>
            </intent-filter>
            <!-- And the UK version. -->
            <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:scheme="http" android:host="www.google.co.uk" android:path="/m/products/scan"/>
            </intent-filter>
            <!-- Support zxing://scan/?... like iPhone app -->
            <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:scheme="zxing" android:host="scan" android:path="/"/>
            </intent-filter>
        </activity>
        <activity android:name="com.google.zxing.client.android.PreferencesActivity"
            android:label="@string/preferences_name"
            android:stateNotNeeded="true"/>
        <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>
            <!-- This allows us to handle the Share button in Contacts. -->
            <intent-filter>
                <action android:name="android.intent.action.SEND"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:mimeType="text/x-vcard"/>
            </intent-filter>
            <!-- This allows us to handle sharing any plain text . -->
            <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:label="@string/sbc_name"
            android:stateNotNeeded="true"
            android:screenOrientation="sensorLandscape">
            <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:stateNotNeeded="true"
            android:screenOrientation="user">
            <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"/>
        <activity android:name="com.google.zxing.client.android.share.BookmarkPickerActivity"
            android:label="@string/bookmark_picker_name"
            android:stateNotNeeded="true"/>
        <activity android:name="com.google.zxing.client.android.share.AppPickerActivity"
            android:label="@string/app_picker_name"
            android:stateNotNeeded="true"/>
        <activity android:name="com.google.zxing.client.android.HelpActivity"
            android:label="@string/menu_help"
            android:screenOrientation="user"
            android:stateNotNeeded="true"/>

5. 复制asset文件到工程下

将zxing库中的\zxing-zxing-3.4.0\android目录复制到自己工程目录下。具体如下图所示。

其实这里面就是一些资源文件。

复制到自己工程<自己的Android工程名>\app\src\main目录下。复制后的工程结构如下图所示。

6. 复制res/目录下的文件到自己工程里面

这里把zxing目录下的res/目录下的资源复原都复制到自己的工程res/目录下面,其中可以看到有很多values-xx文件夹,其实就是以不同国家来进行区分的,这里我们可以先不用管values-xx文件夹。可以参考下面的这幅图片,可以把高亮的文件夹复制到自己的工程目录下。

复制完后,我的工程res/目录结构如下图所示:

7. 添加需要跳转到扫码的Activity

上面基本上把Zxing库中的一些文件都复制过来了,接下来就是要在自己的代码中,添加需要跳转到扫码功能的Activity。zxing扫码的Activity就是CaptureActivity。注意,开启相机是需要申请权限的,这里

// 开启扫码Activity
Intent qrIntent = new Intent(getContext(), CaptureActivity.class);
startActivityForResult(qrIntent, Constant.REQUSET_QR);

权限相关代码


    /**
     * 请求相机权限,去调用这个方法去申请权限
     */
    private void requestCameraPermission() {
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.CAMERA}, Constant.REQUEST_CAMER_PERMISSION);
        } else {
            startCameraActivityForResult();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case Constant.REQUEST_CAMER_PERMISSION:
                Log.i(TAG, "相机请求");
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.i(TAG, "相机权限请求成功!");
                    startCameraActivityForResult();
                } else {
                    Toast.makeText(getContext(), "权限授予失败", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

8. 运行结果

Demo地址:Demo

可以看到虽然实现了扫码功能,但是实际上只能横屏去进行扫码,竖屏是不识别二维码的,所以想要实现竖屏扫码,后面的blog是继续去讲解如何实现zxing的竖屏扫码。