跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Android 使用 ZXing 库实现二维码扫描与生成

Android 项目集成 ZXing 库可实现二维码扫描与生成功能。步骤包括在 Gradle 中添加 zxing-lite 依赖,在 Manifest 中声明 Camera 权限及注册 CaptureActivity,设计包含输入框、按钮和图片视图的布局 XML,并在 MainActivity 中编写点击事件监听与 onActivityResult 回调逻辑以处理扫描结果和生成二维码位图。开发过程中需注意 Android 6.0+ 的动态权限申请、ProGuard 混淆规则配置以及内存管理问题,确保功能稳定运行。

禅心发布于 2025/2/6更新于 2026/10/2399 浏览
Android 使用 ZXing 库实现二维码扫描与生成

Android 使用 ZXing 库实现二维码扫描与生成

在 Android 开发中,二维码功能(扫描与生成)是应用集成中的常见需求。ZXing (Zebra Crossing) 是一个开源的条码/二维码处理库。本文将详细介绍如何在 Android 项目中集成 zxing-lite 库,并实现扫描二维码和生成二维码的功能。

1. 引入第三方依赖

首先,需要在项目的 build.gradle (Module: app) 文件中添加 zxing-lite 的依赖。推荐使用 AndroidX 版本以确保兼容性。

// build.gradle (Module: app)
dependencies {
    implementation 'com.king.zxing:zxing-lite:1.1.7-androidx'
}

添加完成后,点击 "Sync Now" 同步项目依赖。

2. 配置 AndroidManifest.xml

为了能够调用摄像头进行扫描,必须在清单文件中声明权限以及扫描 Activity。

2.1 声明权限

在 <manifest> 标签下添加以下权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 如果需要保存图片或读取相册 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2.2 注册 CaptureActivity

ZXing-lite 提供了现成的扫描界面 Activity,需要在 Manifest 中注册它,并设置合适的主题和屏幕方向。

<activity
    android:name="com.king.zxing.CaptureActivity"
    android:screenOrientation="fullSensor"
    android:theme="@style/CaptureTheme" />

注意:在 Android 6.0 (API 23) 及以上版本,动态运行时权限是必须的。建议在代码中处理权限申请逻辑。

3. 布局文件设计 (activity_main.xml)

主界面需要包含输入框、按钮和图片展示区域。以下是推荐的布局结构:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <!-- 显示扫描结果 -->
    <EditText
        android:id="@+id/edt_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="扫描结果将显示在这里"
        android:inputType="textMultiLine" />

    <!-- 操作按钮组 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="16dp">

        <Button
            android:id="@+id/btn_scan"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="扫码" />

        <Button
            android:id="@+id/btn_create"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="生成" />
    </LinearLayout>

    <!-- 输入内容用于生成 -->
    <EditText
        android:id="@+id/edt_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:hint="请输入要生成的文字内容" />

    <!-- 二维码图片展示 -->
    <ImageView
        android:id="@+id/iv_qr"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_marginTop="16dp"
        android:scaleType="fitCenter"
        android:src="@android:drawable/ic_menu_gallery" />

</LinearLayout>

4. 核心代码实现 (MainActivity.java)

在主活动中,我们需要初始化视图,处理按钮点击事件,并接收扫描回调。

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

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

import com.king.zxing.CaptureActivity;
import com.king.zxing.util.CodeUtils;

import static com.king.zxing.CaptureFragment.KEY_RESULT;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    protected EditText edtResult;
    protected Button btnScan;
    protected Button btnCreate;
    protected EditText edtData;
    protected ImageView ivQr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 修复:直接调用 setContentView,而非 super.setContentView
        setContentView(R.layout.activity_main);
        
        // 初始化权限工具类(需自行实现或使用 PermissionX 等库)
        // PermissionUtils.applyPermission(this); 
        initView();
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.btn_scan) {
            // 跳转到扫描界面
            Intent intent = new Intent(this, CaptureActivity.class);
            startActivityForResult(intent, 1);
        } else if (view.getId() == R.id.btn_create) {
            String data = edtData.getText().toString().trim();
            if (TextUtils.isEmpty(data)) {
                Toast.makeText(this, "请输入文字", Toast.LENGTH_SHORT).show();
            } else {
                // 生成二维码
                Bitmap qrCode = CodeUtils.createQRCode(data, 600, null);
                ivQr.setImageBitmap(qrCode);
            }
        }
    }

    /**
     * 在该方法中拿到扫描的数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == 1) {
                String result = data.getStringExtra(KEY_RESULT);
                Log.e("ZXing", "scan result-->" + result);
                // 展示到页面上
                if (edtResult != null) {
                    edtResult.setText(result);
                }
            }
        } else if (resultCode == RESULT_CANCELED) {
            // 用户取消扫描
            Log.d("ZXing", "Scan canceled");
        }
    }

    private void initView() {
        edtResult = findViewById(R.id.edt_result);
        btnScan = findViewById(R.id.btn_scan);
        btnScan.setOnClickListener(this);
        btnCreate = findViewById(R.id.btn_create);
        btnCreate.setOnClickListener(this);
        edtData = findViewById(R.id.edt_data);
        ivQr = findViewById(R.id.iv_qr);
    }
}

5. 常见问题与注意事项

5.1 运行时权限

在 Android 6.0 及以上版本,即使 Manifest 中声明了 CAMERA 权限,也需要在代码中动态请求用户授权。如果未获取权限,扫描界面可能会闪退或无法启动相机。

建议封装一个权限检查工具类,或者使用如 PermissionX 这样的库来简化流程。

5.2 内存溢出问题

生成高分辨率二维码时,Bitmap 会占用较多内存。如果频繁生成且未回收,可能导致 OOM。建议在生成后及时复用 Bitmap 对象,或在低内存设备上降低生成尺寸。

5.3 ProGuard 混淆

如果开启了代码混淆,请确保保留 ZXing 相关的类。在 proguard-rules.pro 中添加以下规则:

-keep class com.king.zxing.** { *; }
-dontwarn com.king.zxing.**

5.4 主题适配

CaptureTheme 默认样式可能在不同机型上表现不一致。如果发现扫描界面背景色异常,可以在 styles.xml 中自定义该主题颜色。

6. 总结

通过集成 zxing-lite 库,开发者可以快速在 Android 应用中实现二维码的扫描与生成功能。本文涵盖了从依赖引入、权限配置、UI 布局到核心逻辑实现的完整流程。在实际开发中,还需结合具体业务场景处理权限交互、错误提示及用户体验优化。

目录

  1. Android 使用 ZXing 库实现二维码扫描与生成
  2. 1. 引入第三方依赖
  3. 2. 配置 AndroidManifest.xml
  4. 2.1 声明权限
  5. 2.2 注册 CaptureActivity
  6. 3. 布局文件设计 (activity_main.xml)
  7. 4. 核心代码实现 (MainActivity.java)
  8. 5. 常见问题与注意事项
  9. 5.1 运行时权限
  10. 5.2 内存溢出问题
  11. 5.3 ProGuard 混淆
  12. 5.4 主题适配
  13. 6. 总结

更多推荐文章

查看全部
  • OpenAI 指控 DeepSeek 非法蒸馏,字节发布 Seedance 2.0,Java 26 预览版上线
  • 百川 2-13B-Chat WebUI v1.0 故障排查手册:6 大常见问题解决
  • C++ string 类模拟实现
  • Lit 与 Alpine.js:轻量级前端开发的两种路径
  • 时序数据库选型指南:工程视角下的 Apache IoTDB
  • AI 大模型入门指南:从零部署与开发实战
  • Unity 性能优化:降低 Animator 调用次数与内存泄漏排查
  • Python 垂直爬虫系统实现方法详解
  • ZeroClaw:基于 Rust 的轻量级 AI Agent,内存占用仅 5MB
  • C++原子操作:从底层原理到实战应用
  • 从零入门大模型:推荐 5 本核心学习书籍
  • Java LeetCode 热门算法精讲
  • Counterfeit-V3.0 AI 绘画模型技术与应用指南
  • Python 屏幕截图翻译工具实战
  • 本地离线部署 Whisper 模型进行语音转写
  • VSCode 搭建 Java+Maven 开发环境指南
  • Anaconda 与 Python 环境安装配置指南
  • 飞算 JavaAI 驱动电商系统核心模块高效开发实战
  • SDL3 跨平台开发简明教程:基于 C++ 与 CMake 构建应用
  • FPGA 比特流(Bitstream)核心原理与生成流程

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online