移动开发 \ Android \ ZXing实现二维码扫描

ZXing实现二维码扫描

总点击1179
简介:  二维码现在越来越火爆,使用的越发广泛,对于二维码二维码的生成与解析,有多种途径,这里我选择用google老大的ZXing。

   二维码现在越来越火爆,使用的越发广泛,对于二维码二维码的生成与解析,有多种途径,这里我选择用google老大的ZXing。

   其中刘超大神使用ZXing写了一个快速集成二维码扫描的工具类,实现其核心的实现扫描的功能。使用时通过调用二维码工具类,几行代码就可以实现二维码扫描的功能。


   参考资料:  

     二维码工具类下载地址:  https://github.com/yipianfengye/android-zxingLibrary

使用说明

可打开默认二维码扫描页面

支持对图片Bitmap的扫描功能

支持对UI的定制化操作

支持对条形码的扫描功能

支持生成二维码操作

支持控制闪光灯开关

通过一个扫描二维码、自定义二维码扫描界面以及生成二维码的例子,来了解ZXing二维码工具类的强大。

生成二维码效果图:

    

ZXing实现二维码扫描


一、实现对二维码的扫描


使用步骤:

1.在module的build.gradle中dependencies添加

compile 'cn.yipianfengye.android:zxing-library:2.1'

2.在Application中执行初始化操作

提示:在清单文件中注册Application


public class MyApplication extends Application{

@Override

public void onCreate() {

super.onCreate();

//初始化二维码工具类

ZXingLibrary.initDisplayOpinion(this);

}

}3.在清单文件配置权限(安卓6.0以上的手机还要额外的权限配置)。

<uses-permission android:name="android.permission.CAMERA" />

<uses-permission android:name="android.permission.FLASHLIGHT" />

<uses-feature android:name="android.hardware.camera" />

<uses-feature android:name="android.hardware.camera.autofocus" />

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.INTERNET" />

4.在代码中执行打开扫描二维码界面操作

 Intent intent = new Intent(MainActivity.this,CaptureActivity.class);

startActivityForResult(intent,REQUEST_CODE);

这里的REQUEST_CODE是我们定义的int型常量,这里设置为5,为了方便接受onActivityResult分别进行处理。

5.在Activity的onActivityResult方法中接收扫描结果(下面有完整代码)

protected void onActivityResult(int requestCode,int resultCode,Intent data) {

if (requestCode == 5) {

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();

}

}

}}

实现效果:(由于模拟器没有摄像头不能扫描二维码,手机录屏需要root,所以就截取了效果图)

第一张是进行二维码扫描,第二张是当扫描结束,显示信息。

只用区区几行代码,就可以实现二维码的快速扫描。


二、定制化显示扫描UI

1.在values的colors文件下添加颜色,决定了二维码四个边框的颜色

<color name="scan_corner_color">#0effc2</color>2.2.在drawable文件下添加一个scan_image.png的图片,就是二维码扫描的那条横线

3.创建一个新的Activity(demo里叫 SecondActivity )集成FragmentActivity,在清单文件里进行配置。

4. 修改新的Activity布局文件,是二维码的背景布局

<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:layout_gravity="bottom|center_horizontal"

android:layout_marginBottom="10dp"

android:layout_marginLeft="20dp"

android:layout_marginRight="20dp"

android:layout_marginTop="20dp"

android:text="取消二维码扫描" />

<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效果等。

5. 创建my_camera.xml布局文件,这个就是扫描二维码的界面

要自定义二维码扫描页面,就在这个布局里进行修改,这里我加了一个ToolBar,一个Button按钮

用来退出扫描。

<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" />

<android.support.v7.widget.Toolbar

android:background="#FF0000"

android:layout_width="match_parent"

android:layout_height="100dp">

</android.support.v7.widget.Toolbar>

<com.uuzuche.lib_zxing.view.ViewfinderView

android:id="@+id/viewfinder_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

app:inner_corner_color="@color/scan_corner_color"

app:inner_corner_length="30dp"

app:inner_corner_width="5dp"

app:inner_height="200dp"

app:inner_margintop="150dp"

app:inner_scan_bitmap="@drawable/scan_image"

app:inner_scan_iscircle="false"

app:inner_scan_speed="10"

app:inner_width="200dp" />

</FrameLayout>

6. 二维码解析回调函数,代码放到SecondActivity

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();

}

};

7.在Activity中执行Fragment的初始化操作


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_second);

initView();

//在Activity中执行Fragment的初始化操作

//执行扫面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();

}

8.使用Activity里定义的Button按钮,完成用户通过点击,退出二维码扫描界面的操作

//点击退出按钮就退出扫描二维码的界面

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.second_button1:

finish();

break;

}

}

效果图:

ZXing实现二维码扫描

完整代码(布局只有两个Button): MainActivity:/*使用二维码工具类步骤:

* 1. 在module的build.gradle中dependencies添加:compile 'cn.yipianfengye.android:zxing-library:2.1'

* 2. 在Application中执行二维码工具类的初始化操作 ZXingLibrary.initDisplayOpinion(this);

* 3. 在清单文件配置权限和自定义的APPlication,安卓6.0的手机还要做额外的权限配置,方有效.

* 3. 更加点击事件调用开启扫描二维码界面操作

* 4. 在自动接收跳转页面传过来的数据onActivityResult里接收扫描结果,并对结果进行处理

* */

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button ZXing;

private Button ZXingOK;

private Button ZXingOK2;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

}

private void initView() {

ZXing = (Button) findViewById(R.id.ZXing);

ZXingOK = (Button) findViewById(R.id.ZXingOK);

ZXing.setOnClickListener(this);

ZXingOK.setOnClickListener(this);

ZXingOK2 = (Button) findViewById(R.id.ZXingOK2);

ZXingOK2.setOnClickListener(this);

}

//根据点击事件开启二维码扫描,这里的5是为了方便接受onActivityResult分别进行处理

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.ZXing:

Intent intent = new Intent(MainActivity.this,CaptureActivity.class);

startActivityForResult(intent,5);

break;

case R.id.ZXingOK:

Intent intent1 = new Intent(MainActivity.this,SecondActivity.class);

startActivityForResult(intent1,7);

break;

case R.id.ZXingOK2:

Intent intent2 = new Intent(MainActivity.this,Main2Activity.class);

startActivity(intent2);

break;

}

}

//在自动接收跳转页面传过来的数据OnActivityResult里接收扫描结果,并对结果进行处理

@Override

protected void onActivityResult(int requestCode,Intent data) {

//处理二维码扫描的结果,5就是对在startActivityForResult里设置的标识进行判断,执行对应的逻辑

if (requestCode == 5) {

//处理扫描结果(在界面上显示)

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,Toast.LENGTH_LONG).show();

}

}

}

if (requestCode == 7) {

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,Toast.LENGTH_LONG).show();

}

}

}

}

}


SecondActivity:


/* 定制化显示扫描界面

* 1.在values的colors文件下添加颜色,决定了二维码四个边框的颜色

* 2.在drawable文件下添加一个scan_image.png的图片,决定了二维码扫描的那条横线的颜色

* 3.创建一个新的Activity(demo里叫 SecondActivity )集成FragmentActivity,在清单文件里进行配置.

* 4.修改新的Activity布局文件,是二维码的背景布局

* 5.创建my_camera.xml布局文件,这个就是扫描二维码的界面

* 6.二维码解析回调函数,代码放到这个Activity即可(SecondActivity就在这个Activity名字)

* 7.在Activity中执行Fragment的初始化操作

* 8.使用Activity里定义的Button按钮,退出二维码扫描界面的操作.

* 9.使用这个我们自定义的二维码扫描界面和使用默认的界面类似,只需替换CaptureActivity即可

*/

public class SecondActivity extends AppCompatActivity implements View.OnClickListener {

private Button second_button1;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_second);

initView();

//在Activity中执行Fragment的初始化操作

//执行扫面Fragment的初始化操作

CaptureFragment captureFragment = new CaptureFragment();

// 为二维码扫描界面设置定制化界面

CodeUtils.setFragmentArgs(captureFragment,captureFragment).commit();

}

private void initView() {

second_button1 = (Button) findViewById(R.id.second_button1);

second_button1.setOnClickListener(this);

}

//点击退出按钮就退出扫描二维码的界面

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.second_button1:

finish();

break;

}

}

//二维码解析回调函数,代码放到这个Activity即可(SecondActivity就在这个Activity名字)

CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() {

@Override

public void onAnalyzeSuccess(Bitmap mBitmap,resultIntent);

SecondActivity.this.finish();

}

};

}


三、生成二维码


只需要在点击事件中加入相应执行代码,即可完成效果:


@Override

public void onClick(View v) {

switch (v.getId()) {

//生成不带logo的二维码图片

case R.id.btnStart:

String textContent = edShow.getText().toString();

if (TextUtils.isEmpty(textContent)) {

Toast.makeText(Main2Activity.this,"您的输入为空!",Toast.LENGTH_SHORT).show();

return;

}

edShow.setText("");

Bitmap image = CodeUtils.createImage(textContent,400,null);

imgShow.setImageBitmap(image);

break;

//生成带logo的二维码图片

case R.id.btnStart2:

String textContent1 = edShow.getText().toString();

if (TextUtils.isEmpty(textContent1)) {

Toast.makeText(Main2Activity.this,Toast.LENGTH_SHORT).show();

return;

}

edShow.setText("");

Bitmap image1 = CodeUtils.createImage(textContent1,BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));

imgShow.setImageBitmap(image1);

break;

}

}


意见反馈 常见问题 官方微信 返回顶部