Zxing二维码库是相当丰富。但是我们往往只需要里面的扫码识别以及生成二维码的功能就可以了,所以这次用到了已经抽离出核销代码的框架包
compile ‘com.journeyapps:zxing-android-embedded:3.3.0’,来快速集成开发。比较简单,后面还会有扫面界面的定制,仿微信二维码扫一扫功能。上几个效果图:
扫描中
扫描结果:
接下来我们来实现他。
一、集成二维码的简单扫一扫以及生成二维码的功能(录屏用的是genymotion,录的有点奇怪啊)
1、Zxing二维码的环境。我们只要compile ‘com.journeyapps:zxing-android-embedded:3.3.0’这个后面就不需要再集成了。
2、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" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="打开闪关灯" android:id="@+id/btn_switch" android:layout_alignTop="@+id/btn_hint1" />
<!-- 这个控件就是扫描的窗口了 -->
<com.journeyapps.barcodescanner.DecoratedBarcodeView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/dbv_custom" app:zxing_framing_rect_width="200dp" app:zxing_framing_rect_height="200dp" app:zxing_preview_scaling_strategy="fitXY" app:zxing_use_texture_view="true" >
</com.journeyapps.barcodescanner.DecoratedBarcodeView>
</LinearLayout>
3、CustomScanAct.java
package com.coofond.zxingdemo;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
/** * Created by IBM on 2016/10/13. */
public class CustomScanAct extends Activity implements DecoratedBarcodeView.TorchListener { // 实现相关接口
// 添加一个按钮用来控制闪光灯,同时添加两个按钮表示其他功能,先用Toast表示
Button swichLight;
DecoratedBarcodeView mDBV;
private CaptureManager captureManager;
private boolean isLightOn = false;
@Override
protected void onPause() {
super.onPause();
captureManager.onPause();
}
@Override
protected void onResume() {
super.onResume();
captureManager.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
captureManager.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
captureManager.onSaveInstanceState(outState);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return mDBV.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_customscan);
swichLight = (Button) findViewById(R.id.btn_switch);
mDBV= (DecoratedBarcodeView) findViewById(R.id.dbv_custom);
mDBV.setTorchListener(this);
// 如果没有闪光灯功能,就去掉相关按钮
if (!hasFlash()) {
swichLight.setVisibility(View.GONE);
}
//重要代码,初始化捕获
captureManager = new CaptureManager(this, mDBV);
captureManager.initializeFromIntent(getIntent(), savedInstanceState);
captureManager.decode();
//选择闪关灯
swichLight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isLightOn) {
mDBV.setTorchOff();
} else {
mDBV.setTorchOn();
}
}
});
}
// torch 手电筒
@Override
public void onTorchOn() {
Toast.makeText(this, "torch on", Toast.LENGTH_LONG).show();
isLightOn = true;
}
@Override
public void onTorchOff() {
Toast.makeText(this, "torch off", Toast.LENGTH_LONG).show();
isLightOn = false;
}
// 判断是否有闪光灯功能
private boolean hasFlash() {
return getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
}
4、MainActivity.java
package com.coofond.zxingdemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
public class MainActivity extends Activity {
private Button btnClick;
private TextView tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
private void initView() {
btnClick = (Button) findViewById(R.id.btn_click);
tvResult = (TextView) findViewById(R.id.tv_result);
}
private void initEvent() {
btnClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//假如你要用的是fragment进行界面的跳转
//IntentIntegrator intentIntegrator = IntentIntegrator.forSupportFragment(ShopFragment.this).setCaptureActivity(CustomScanAct.class);
IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
intentIntegrator
.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES)
.setPrompt("将二维码/条码放入框内,即可自动扫描")//写那句提示的话
.setOrientationLocked(false)//扫描方向固定
.setCaptureActivity(CustomScanAct.class) // 设置自定义的activity是CustomActivity
.initiateScan(); // 初始化扫描
}
});
}
//获取扫描的结果
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (intentResult != null) {
if (intentResult.getContents() == null) {
} else {
// ScanResult 为获取到的字符串
String ScanResult = intentResult.getContents();
tvResult.setText(ScanResult);
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
这样就集成了二维码的基本功能了。显示的是一个闪动的激光条。。。
1、主要是这一句 app:zxing_scanner_layout=”@layout/barcode_scanner”指向你自定义的界面
<!-- 这个控件就是扫描的窗口了 -->
<com.journeyapps.barcodescanner.DecoratedBarcodeView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/dbv_custom" app:zxing_framing_rect_width="200dp" app:zxing_framing_rect_height="200dp" app:zxing_preview_scaling_strategy="fitXY" app:zxing_use_texture_view="true" app:zxing_scanner_layout="@layout/barcode_scanner" >
</com.journeyapps.barcodescanner.DecoratedBarcodeView>
2、那么我们看下如何定制这个窗口barcode_scanner.xml看一下
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" >
<com.journeyapps.barcodescanner.BarcodeView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/zxing_barcode_surface" app:zxing_framing_rect_width="250dp" app:zxing_framing_rect_height="250dp">
</com.journeyapps.barcodescanner.BarcodeView>
<com.coofond.zxingdemo.CustomViewfinderView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/zxing_viewfinder_view" app:zxing_possible_result_points="@color/zxing_custom_possible_result_points" app:zxing_result_view="@color/zxing_custom_result_view" app:zxing_viewfinder_laser="#FFFFFF" app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>
<TextView android:id="@+id/zxing_status_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:background="@color/zxing_transparent" android:text="@string/zxing_msg_default_status" android:textColor="@color/zxing_status_text"/>
</merge>
3、主要是要自定义ViewfinderView,重新绘制你的扫描界面。看下CustomViewfinderView.java中的文件
package com.coofond.zxingdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.ViewfinderView;
import java.util.ArrayList;
import java.util.List;
/** * 自定义zxing二维码扫描界面 * Created by IBM on 2016/10/20. */
public class CustomViewfinderView extends ViewfinderView {
public int laserLinePosition=0;
public float[] position=new float[]{0f,0.5f,1f};
public int[] colors=new int[]{0x00ffffff,0xffffffff,0x00ffffff};
public LinearGradient linearGradient ;
public CustomViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/** * 重写draw方法绘制自己的扫描框 * @param canvas */
@Override
public void onDraw(Canvas canvas) {
refreshSizes();
if (framingRect == null || previewFramingRect == null) {
return;
}
Rect frame = framingRect;
Rect previewFrame = previewFramingRect;
int width = canvas.getWidth();
int height = canvas.getHeight();
//绘制4个角
paint.setColor(0xFFFFFFFF);//定义画笔的颜色
canvas.drawRect(frame.left, frame.top, frame.left+70, frame.top+10, paint);
canvas.drawRect(frame.left, frame.top, frame.left + 10, frame.top + 70, paint);
canvas.drawRect(frame.right-70, frame.top, frame.right, frame.top+10, paint);
canvas.drawRect(frame.right-10, frame.top, frame.right, frame.top+70, paint);
canvas.drawRect(frame.left, frame.bottom-10, frame.left+70, frame.bottom, paint);
canvas.drawRect(frame.left, frame.bottom-70, frame.left+10, frame.bottom, paint);
canvas.drawRect(frame.right-70, frame.bottom-10, frame.right, frame.bottom, paint);
canvas.drawRect(frame.right-10, frame.bottom-70, frame.right, frame.bottom, paint);
// Draw the exterior (i.e. outside the framing rect) darkened
paint.setColor(resultBitmap != null ? resultColor : maskColor);
canvas.drawRect(0, 0, width, frame.top, paint);
canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
canvas.drawRect(0, frame.bottom + 1, width, height, paint);
if (resultBitmap != null) {
// Draw the opaque result bitmap over the scanning rectangle
paint.setAlpha(CURRENT_POINT_OPACITY);
canvas.drawBitmap(resultBitmap, null, frame, paint);
} else {
// paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
// scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
int middle = frame.height() / 2 + frame.top;
laserLinePosition=laserLinePosition+5;
if(laserLinePosition>frame.height())
{
laserLinePosition=0;
}
linearGradient= new LinearGradient(frame.left + 1, frame.top+laserLinePosition , frame.right -1 , frame.top +10+laserLinePosition, colors, position, Shader.TileMode.CLAMP);
// Draw a red "laser scanner" line through the middle to show decoding is active
// paint.setColor(laserColor);
paint.setShader(linearGradient);
//绘制扫描线
canvas.drawRect(frame.left + 1, frame.top+laserLinePosition , frame.right -1 , frame.top +10+laserLinePosition, paint);
paint.setShader(null);
float scaleX = frame.width() / (float) previewFrame.width();
float scaleY = frame.height() / (float) previewFrame.height();
List<ResultPoint> currentPossible = possibleResultPoints;
List<ResultPoint> currentLast = lastPossibleResultPoints;
int frameLeft = frame.left;
int frameTop = frame.top;
if (currentPossible.isEmpty()) {
lastPossibleResultPoints = null;
} else {
possibleResultPoints = new ArrayList<>(5);
lastPossibleResultPoints = currentPossible;
paint.setAlpha(CURRENT_POINT_OPACITY);
paint.setColor(resultPointColor);
for (ResultPoint point : currentPossible) {
canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
frameTop + (int) (point.getY() * scaleY),
POINT_SIZE, paint);
}
}
if (currentLast != null) {
paint.setAlpha(CURRENT_POINT_OPACITY / 2);
paint.setColor(resultPointColor);
float radius = POINT_SIZE / 2.0f;
for (ResultPoint point : currentLast) {
canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
frameTop + (int) (point.getY() * scaleY),
radius, paint);
}
}
postInvalidateDelayed(16,
frame.left ,
frame.top ,
frame.right ,
frame.bottom);
// postInvalidate();
}
}
}
那么就完全结束了。是懂非懂的感觉。只是停留在集成和使用的阶段。
最后该demo的下载地址http://download.csdn.net/detail/z_zt_t/9659802