[置顶] Android移动开发-在Android项目里集成开源框架ZXing实现扫描二维码的功能
2017-11-23 15:49
976 查看
二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。
那么在Android项目里集成Google开源框架ZXing实现扫描二维码的功能呢?
在集成二维码之前,我们先看一下国内比较主流用到的二维码的手机应用的二维码界面(以下截图分别是支付宝、微信、摩拜单车、ofo单车)
首先下载或直接引入zxing开源项目,项目的github地址:https://github.com/zxing/zxing/tree/zxing-3.2.1
导入开发资源的jar包并引入
在AndroidManifest.xml文件里配置Manifest里的权限声明
在AndroidManifest.xml文件里面添加声明:
把ZXing相应的项目文件导入
在res目录下新建raw目录,并把扫描识别时的震动声音文件beep.ogg导入
-开始扫描时的界面, layout/layout/activity_find_scan.xml界面布局代码如下:
开始扫描时FindScanActivity.java逻辑代码如下:
扫描识别结果返回的界面, layout/layout/activity_scan_result.xml界面布局代码如下:
扫描识别结果返回的ScanResultActivity.java逻辑代码如下:
Demo程序运行效果界面截图如下:
Demo程序源码下载地址一(GitHub)
Demo程序源码下载地址二(Gitee)
二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。
那么在Android项目里集成Google开源框架ZXing实现扫描二维码的功能呢?
在集成二维码之前,我们先看一下国内比较主流用到的二维码的手机应用的二维码界面(以下截图分别是支付宝、微信、摩拜单车、ofo单车)
首先下载或直接引入zxing开源项目,项目的github地址:https://github.com/zxing/zxing/tree/zxing-3.2.1
导入开发资源的jar包并引入
在AndroidManifest.xml文件里配置Manifest里的权限声明
<!-- 拍照 --> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 震动 --> <uses-permission android:name="android.permission.VIBRATE" />
在AndroidManifest.xml文件里面添加声明:
<activity android:name=".FindScanActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ScanResultActivity"/> </application>
把ZXing相应的项目文件导入
在res目录下新建raw目录,并把扫描识别时的震动声音文件beep.ogg导入
-开始扫描时的界面, layout/layout/activity_find_scan.xml界面布局代码如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/sv_scan" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" /> <com.fukaimei.scanqrcodetest.zxing.view.ViewfinderView android:id="@+id/vv_finder" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="@drawable/bg_alpha" android:gravity="center" android:text="扫描二维码/条形码" android:textColor="#ffffffff" android:textSize="20sp" /> </RelativeLayout>
开始扫描时FindScanActivity.java逻辑代码如下:
package com.fukaimei.scanqrcodetest; import java.io.IOException; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Bundle; import android.os.Handler; import android.os.Vibrator; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Window; import android.widget.Toast; import com.fukaimei.scanqrcodetest.zxing.camera.CameraManager; import com.fukaimei.scanqrcodetest.zxing.decoding.CaptureActivityHandler; import com.fukaimei.scanqrcodetest.zxing.decoding.InactivityTimer; import com.fukaimei.scanqrcodetest.zxing.view.ViewfinderView; import com.google.zxing.Result; public class FindScanActivity extends Activity implements SurfaceHolder.Callback { private final static String TAG = "FindScanActivity"; private CaptureActivityHandler mHandler; private ViewfinderView vv_finder; private boolean hasSurface = false; private InactivityTimer mTimer; private MediaPlayer mPlayer; private boolean bBeep; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_find_scan); // 获取相机的动态权限 cameraPermissions(); CameraManager.init(getApplication(), CameraManager.QR_CODE); vv_finder = (ViewfinderView) findViewById(R.id.vv_finder); mTimer = new InactivityTimer(this); } // 定义获取相机的动态权限 private void cameraPermissions() { if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{ android.Manifest.permission.CAMERA}, 1); } } /** * 重写onRequestPermissionsResult方法 * 获取动态权限请求的结果,再开启相机扫码 */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { CameraManager.init(getApplication(), CameraManager.QR_CODE); } else { Toast.makeText(this, "用户拒绝了权限", Toast.LENGTH_SHORT).show(); } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } @Override protected void onResume() { super.onResume(); SurfaceView sv_scan = (SurfaceView) findViewById(R.id.sv_scan); SurfaceHolder surfaceHolder = sv_scan.getHolder(); if (hasSurface) { initCamera(surfaceHolder); } else { surfaceHolder.addCallback(this); } bBeep = true; AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE); if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) { bBeep = false; } initBeepSound(); } @Override protected void onPause() { super.onPause(); if (mHandler != null) { mHandler.quitSynchronously(); mHandler = null; } CameraManager.get().closeDriver(); } @Override protected void onDestroy() { mTimer.shutdown(); super.onDestroy(); } public void handleDecode(Result result, Bitmap barcode) { mTimer.onActivity(); beepAndVibrate(); String resultString = result.getText(); if (resultString == null || resultString.length() <= 0) { Toast.makeText(this, "Scan failed or result is null", Toast.LENGTH_SHORT).show(); } else { String desc = String.format("barcode width=%d,height=%d", barcode.getWidth(), barcode.getHeight()); // Toast.makeText(this, desc, Toast.LENGTH_SHORT).show(); Intent intent = new Intent(this, ScanResultActivity.class); intent.putExtra("result", resultString); startActivity(intent); } } private void initCamera(SurfaceHolder surfaceHolder) { try { CameraManager.get().openDriver(surfaceHolder); if (mHandler == null) { mHandler = new CaptureActivityHandler(this, null, null); } } catch (Exception e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { if (!hasSurface) { hasSurface = true; initCamera(holder); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { hasSurface = false; } public ViewfinderView getViewfinderView() { return vv_ afb3 finder; } public Handler getHandler() { return mHandler; } public void drawViewfinder() { vv_finder.drawViewfinder(); } private void initBeepSound() { if (bBeep && mPlayer == null) { setVolumeControlStream(AudioManager.STREAM_MUSIC); mPlayer = new MediaPlayer(); mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mPlayer.setOnCompletionListener(beepListener); AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.beep); try { mPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength()); file.close(); mPlayer.setVolume(0.1f, 0.1f); mPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); mPlayer = null; } } } private static final long VIBRATE_DURATION = 200L; private void beepAndVibrate() { if (bBeep && mPlayer != null) { mPlayer.start(); } Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); vibrator.vibrate(VIBRATE_DURATION); } private final OnCompletionListener beepListener = new OnCompletionListener() { public void onCompletion(MediaPlayer mPlayer) { mPlayer.seekTo(0); } }; }
扫描识别结果返回的界面, layout/layout/activity_scan_result.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="10dp"> <TextView android:id="@+id/tv_result" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
扫描识别结果返回的ScanResultActivity.java逻辑代码如下:
package com.fukaimei.scanqrcodetest; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.TextView; public class ScanResultActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan_result); TextView tv_result = (TextView) findViewById(R.id.tv_result); String result = getIntent().getStringExtra("result"); tv_result.setText("扫码结果为:" + result); } }
Demo程序运行效果界面截图如下:
Demo程序源码下载地址一(GitHub)
Demo程序源码下载地址二(Gitee)
相关文章推荐
- [置顶] android开发之集成zxing,二维码,以及扫描二维码的功能实现。带源代码下载
- android开发之集成zxing,二维码,以及扫描二维码的功能实现。带源代码下载
- android开发(17) 扫描二维码 - 调用第三方APK来实现二维码扫描,参考自 开源项目zxing
- android开发(17) 扫描二维码 - 调用第三方APK来实现二维码扫描,参考自 开源项目zxing
- [置顶] Android移动开发-在Android项目里集成调用微信支付开发的实现
- [置顶] Android移动开发-在Android项目里集成讯飞语音识别与合成的实现
- android中Zxing实现二维码功能的快速集成以及扫描界面的定制
- [置顶] Android移动开发-在Android项目里集成face++人脸识别的实现
- Android二维码功能实现,在程序内嵌入ZXing项目
- Android二维码功能实现,在程序内嵌入ZXing项目
- Android二维码功能实现,在程序内嵌入ZXing项目
- Android开源库之使用ZXing开源库实现二维码功能
- Android二维码功能实现,在程序内嵌入ZXing项目
- Android二维码功能实现,在程序内嵌入ZXing项目
- [置顶] Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能。
- Android 二维码功能实现,在程序内嵌入ZXing项目
- Android二维码功能实现,在程序内嵌入ZXing项目
- Android二维码功能实现,在程序内嵌入ZXing项目
- Android二维码功能实现,在程序内嵌入ZXing项目
- Android开发实现模仿360二维码扫描功能实例详解