Android集成二维码扫描功能

文章转载自  https://github.com/yipianfengye/android-zxingLibrary

在具体介绍该扫描库之前我们先看一下其具体的使用方式,看看是不是几行代码就可以集成二维码扫描的功能。

  • 在module的build.gradle中执行compile操作
compile ‘cn.yipianfengye.android:zxing-library:2.1‘
  • 在demo Application中执行初始化操作
@Override
    public void onCreate() {
        super.onCreate();

        ZXingLibrary.initDisplayOpinion(this);
    }
  • 在代码中执行打开扫描二维码界面操作
/**
         * 打开默认二维码扫描界面
         */
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                startActivityForResult(intent, REQUEST_CODE);
            }
        });

这里的REQUEST_CODE是我们定义的int型常量。

  • 在Activity的onActivityResult方法中接收扫描结果
/**
         * 处理二维码扫描结果
         */
        if (requestCode == REQUEST_CODE) {
            //处理扫描结果(在界面上显示)
            if (null != data) {
                Bundle bundle = data.getExtras();
                if (bundle == null) {
                    return;
                }
                if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                    String result = bundle.getString(CodeUtils.RESULT_STRING);
                    Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                    Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                }
            }
        }

怎么样是不是很简单?下面我们可以来看一下具体的执行效果:

执行效果:

但是这样的话是不是太简单了,如果我想选择图片解析呢?别急,对二维码图片的解析也是支持的

  • 集成对二维码图片的解析功能
  • 调用系统API打开图库
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
  • 在Activity的onActivityResult方法中获取用户选中的图片并调用二维码图片解析API
if (requestCode == REQUEST_IMAGE) {
            if (data != null) {
                Uri uri = data.getData();
                ContentResolver cr = getContentResolver();
                try {
                    Bitmap mBitmap = MediaStore.Images.Media.getBitmap(cr, uri);//显得到bitmap图片

                    CodeUtils.analyzeBitmap(mBitmap, new CodeUtils.AnalyzeCallback() {
                        @Override
                        public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
                            Toast.makeText(MainActivity.this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                        }

                        @Override
                        public void onAnalyzeFailed() {
                            Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                        }
                    });

                    if (mBitmap != null) {
                        mBitmap.recycle();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

执行效果

有了默认的二维码扫描界面,也有了对二维码图片的解析,可能有的同学会说如果我想定制化显示UI怎么办呢?没关系也支持滴。

  • 定制化显示扫描UI

由于我们的扫描组件是通过Fragment实现的,所以能够很轻松的实现扫描UI的定制化。

  • 在新的Activity中定义Layout布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_second"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/second_button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="取消"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="10dp"
        android:layout_gravity="bottom|center_horizontal"
        />

    <FrameLayout
        android:id="@+id/fl_my_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        ></FrameLayout>

</FrameLayout>

启动id为fl_my_container的FrameLayout就是我们需要替换的扫描组件,也就是说我们会将我们定义的扫描Fragment替换到id为fl_my_container的FrameLayout的位置。而上面的button是我们添加的一个额外的控件,在这里你可以添加任意的控件,各种UI效果等。具体可以看下面在Activity的初始化过程。

  • 在Activity中执行Fragment的初始化操作
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        /**
         * 执行扫面Fragment的初始化操作
         */
        CaptureFragment captureFragment = new CaptureFragment();
        // 为二维码扫描界面设置定制化界面
        CodeUtils.setFragmentArgs(captureFragment, R.layout.my_camera);

        captureFragment.setAnalyzeCallback(analyzeCallback);
        /**
         * 替换我们的扫描控件
         */ getSupportFragmentManager().beginTransaction().replace(R.id.fl_my_container, captureFragment).commit();
    }

其中analyzeCallback是我们定义的扫描回调函数,其具体的定义:

/**
     * 二维码解析回调函数
     */
    CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() {
        @Override
        public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
            bundle.putString(CodeUtils.RESULT_STRING, result);
            resultIntent.putExtras(bundle);
            SecondActivity.this.setResult(RESULT_OK, resultIntent);
            SecondActivity.this.finish();
        }

        @Override
        public void onAnalyzeFailed() {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
            bundle.putString(CodeUtils.RESULT_STRING, "");
            resultIntent.putExtras(bundle);
            SecondActivity.this.setResult(RESULT_OK, resultIntent);
            SecondActivity.this.finish();
        }
    };

仔细看的话,你会发现我们调用了CondeUtils.setFragmentArgs方法,该方法主要用于修改扫描界面扫描框与透明框相对位置的,与若不调用的话,其会显示默认的组件效果,而如果调用该方法的话,可以修改扫描框与透明框的相对位置等UI效果,我们可以看一下my_camera布局文件的实现。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <SurfaceView
        android:id="@+id/preview_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <com.uuzuche.lib_zxing.view.ViewfinderView
        android:id="@+id/viewfinder_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:inner_width="200dp"
        app:inner_height="200dp"
        app:inner_margintop="150dp"
        app:inner_corner_color="@color/scan_corner_color"
        app:inner_corner_length="30dp"
        app:inner_corner_width="5dp"
        app:inner_scan_bitmap="@drawable/scan_image"
        app:inner_scan_speed="10"
        app:inner_scan_iscircle="false"
        />

</FrameLayout>

上面我们自定义的扫描控件的布局文件,下面我们看一下默认的扫描控件的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <SurfaceView
        android:id="@+id/preview_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <com.uuzuche.lib_zxing.view.ViewfinderView
        android:id="@+id/viewfinder_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</FrameLayout>

可以发现其主要的区别就是在自定义的扫描控件中多了几个自定义的扫描框属性:

<declare-styleable name="innerrect">
        <attr name="inner_width" format="dimension"/><!-- 控制扫描框的宽度 -->
        <attr name="inner_height" format="dimension"/><!-- 控制扫描框的高度 -->
        <attr name="inner_margintop" format="dimension" /><!-- 控制扫描框距离顶部的距离 -->
        <attr name="inner_corner_color" format="color" /><!-- 控制扫描框四角的颜色 -->
        <attr name="inner_corner_length" format="dimension" /><!-- 控制扫描框四角的长度 -->
        <attr name="inner_corner_width" format="dimension" /><!-- 控制扫描框四角的宽度 -->
        <attr name="inner_scan_bitmap" format="reference" /><!-- 控制扫描图 -->
        <attr name="inner_scan_speed" format="integer" /><!-- 控制扫描速度 -->
        <attr name="inner_scan_iscircle" format="boolean" /><!-- 控制小圆点是否展示 -->
    </declare-styleable>

通过以上几个属性我们就可以定制化的显示我们的扫描UI了,比如定制化微信扫描UI:

执行效果

当然了如果以上的以上,你还是对定制化UI方面不太满意,可以直接下载我的项目,然后引入lib-zxing module作为你的module,直接修改其代码。

  • 生成二维码图片
  • 生成带Logo的二维码图片:
/**
         * 生成二维码图片
         */
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String textContent = editText.getText().toString();
                if (TextUtils.isEmpty(textContent)) {
                    Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                editText.setText("");
                mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
                imageView.setImageBitmap(mBitmap);
            }
        });
  • 生成不带logo的二维码图片
/**
         * 生成不带logo的二维码图片
         */
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String textContent = editText.getText().toString();
                if (TextUtils.isEmpty(textContent)) {
                    Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                editText.setText("");
                mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
                imageView.setImageBitmap(mBitmap);
            }
        });
  • 执行效果

  • 支持控制闪光灯
/**
 * 打开闪光灯
 */
CodeUtils.isLightEnable(true);

/**
 * 关闭闪光灯
 */
 CodeUtils.isLightEnable(false);
时间: 2024-12-20 23:28:44

Android集成二维码扫描功能的相关文章

Android—ZXing二维码扫描遇到的问题

最近工作中需要开发带有二维码扫描功能的软件(基于开源项目ZXing),遇到的问题记录一下,也希望给大家带来帮助. 1.首先因为扫描要开摄像机所以加权限是一定的,不然后面什么都不能进行 <uses-permission android:name="android.permission.CAMERA" /> 2.设置扫描框的大小: 在com.zxing.camera包中查找 private static final int MIN_FRAME_WIDTH = 240;  pri

简化至只剩条码和二维码扫描功能的ZXing

基于这位的源码修改的. http://blog.csdn.net/ryantang03/article/details/7831826 去除了他加入的生成二维码图片的功能,节约了一个包. 去掉了扫描成功后的音效,节约了一个音效文件. 去掉了闪光灯功能,晚上扫什么码赶紧睡觉.节约了一个类. 去掉了扫描超时,节约了两个类. 去掉了扫描界面的标题栏,节约了一个图片文件. 一切以易用为目的,zxing这玩意太麻烦了. 修改后的代码最后发. 要用的话,首先当然是复制文件. 1. libs文件夹里的jar包

Android &quot;QR二维码扫描&quot;

没什么说的,上图上源码 git: http://git.oschina.net/892642257/QRCode csdn(0分): http://download.csdn.net/detail/onlyonecoder/7713589 Android "QR二维码扫描"

有关iOS系统中调用相机设备实现二维码扫描功能的注意点(3/3)

今天我们接着聊聊iOS系统实现二维码扫描的其他注意点. 大家还记得前面我们用到的输出数据的类对象吗?AVCaptureMetadataOutput,就是它!如果我们需要实现目前主流APP扫描二维码的功能,即只有当二维码进入视图中心的方框中时才进行扫描识别功能,这样做的目的主要是为了提高用户的使用体验,需要用到这个类里面的一个属性:rectOfInterest,这个属性是一个CGRect结构体类型.但和我们平时经常使用的CGRect有点不一样.以下截取了官网文档对这个属性的表述: /*! @pro

Android实现二维码扫描登录网页

之前写过一个二维码扫描demo,用的Zxing的框架,点击下载,后续扫描二维码中出现一些问题,比如解决压缩图片,调整扫描窗口大小等等.后续单位要求做扫描登录实现,发现难点就是怎么知道你扫描的是这台电脑,后台必须获取到(后台技术的问题)然后把这个参数给我,再传递到后台,后台判断登录即可.这样自己扫描后直接传递个参数就可以实现登录了.效果如下: 大概代码实现:扫描跳转: //扫描登录a case R.id.tv_more_qr: if (PventQuickClick.isFastDoubleCli

苹果原生二维码扫描功能——可限制扫描区域

使用原生的好处就是扫描特别快效率特别高,使用  AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(默认的是全屏扫描) 首先是要用到的几个类 @property ( strong , nonatomic ) AVCaptureDevice * device; @property ( strong , nonatomic ) AVCaptureDeviceInput * input; @property ( strong , nonatomic ) AVCaptureMe

Android二维码扫描功能的集成开发

二维码开发主要依赖ZXing开源项目 项目地址:https://github.com/zxing/zxing 这个开源项目可以扫描一维,和二维码, 一维码指的是书后面的条形码 首先配置ZXing库和Android工程 项目本身非常大,我们只需使用精简版的库 导入之后 TestQRcode 项目作为库被其他项目使用. BarCodeTestActivity package com.ericssonlabs; import com.google.zxing.WriterException; impo

使用ionic2开发一个二维码扫描功能

界面添加一个按钮: <button ion-button block color="secondary" class="Scan-button" (click)="scanQR()" [disabled]="loading">点我扫描</button> ts具体代码: import { Component } from '@angular/core'; import { NavController }

IOS7自带的二维码扫描功能

#pragma mark AVCaptureMetadataOutputObjectsDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {          NSString *stringValue;