SB程序媛学习笔记--Android(安卓)zxing实现二维码开发
博主有话说:写这个博客只是为了记录学习android过程中的问题,这篇文章只是参考了很多其他博主写的文章和资料总结出的笔记,并非完全原创。如果你运气不咋地看到这篇文章而且又觉得似曾相识,请勿喷我,我会在文章最后贴出参考博客地址。
关于zxing库,有以下几个方面:
(1)下载zxing库(下载精简过的android库)
(2)配置zxing库到项目中
(3)生成二维码
(4)扫描二维码
(5)扫描框UI
(1)下载zxing库
尊重原作者:https://github.com/zxing/zxing
但是因为原作者实在是太厉害,库实在太大,所以请下载精简过的zxing库,以下是精简库的结构:
(2)配置zxing库到项目中
①将下载的zxing库import进eclipse中
②选中该项目右键——properties——Android——选中isLibrary(因为这个项目作为库被其他项目使用)——OK
③新建一个项目(这个项目是你需要导入这个功能的项目)
④选中该项目右键——properties——Android——Add加入zxing库——OK
(3)生成二维码
①创建EditText et1接受输入内容
String str =et1.getText().toString();
②创建Bitmap存储二维码图片,而生成二维码是用到库里面的EncodingHandler类中的createQRCode方法
Bitmap qrcode = EncodingHandler.createQRCode(et1.getText().toString(), 400);
参数:
1.生成二维码的内容
2.生成二维码横向纵向长度(由于是一个正方形,所以只有一个值)
完整代码:
String str =et1.getText().toString();if(str.equals("")){Toast.makeText(MainActivity.this, "请输入文本", Toast.LENGTH_SHORT).show();}else{try {//第一个参数是要生成二维码的内容,第二个参数是生成二维码横向纵向长度Bitmap qrcode = EncodingHandler.createQRCode(et1.getText().toString(), 400);iv.setImageBitmap(qrcode);} catch (WriterException e) {e.printStackTrace();}}
(4)扫描二维码
①二维码扫描的页面实际是库里面的一个Activity,项目里面通过跳转到库里面CaptureActivity来使用二维码扫描功能,所以要定义一个intent来跳转。
Intent startScan = new Intent(MainActivity.this, CaptureActivity.class);
②实现跳转功能需要在你的项目AndroidManifest.xml中定义Activity,可以直接把zxing库中AndroidManifest.xml的以下内容复制到你的项目AndroidManifest.xml中
③调用startActivity(startScan);跳转到二维码扫描页面,扫描页面如下(这是改变过的UI)
完整代码:
Intent startScan = new Intent(MainActivity.this, CaptureActivity.class);startActivity(startScan);
但是调用startActivity(startScan);只能打开扫描Activity,但是不能解码,由于库的CaptureActivity中的handleDecode方法会将解码内容回调,如下:
public void handleDecode(Result result, Bitmap barcode) {inactivityTimer.onActivity();playBeepSoundAndVibrate();String resultString = result.getText();if (resultString.equals("")) {Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();}else {Intent resultIntent = new Intent();Bundle bundle = new Bundle();bundle.putString("result", resultString);resultIntent.putExtras(bundle);this.setResult(RESULT_OK, resultIntent);}CaptureActivity.this.finish();}
所以在你的项目的MainActivity需要调用startActivityForResult(startScan, 0);来跳转页面且使用onActivityResult方法接收回调的内容,用TextView tv1显示出来,如下:
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode ==RESULT_OK){ String str =data.getExtras().getString("result"); tv1.setText(str); }}
完整代码:
public class MainActivity extends Activity {private Button bt1,bt2;private TextView tv1;private EditText et1;private ImageView iv;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bt1 =(Button)findViewById(R.id.bt1);bt2 =(Button)findViewById(R.id.bt2);tv1 =(TextView)findViewById(R.id.tv1);et1 =(EditText)findViewById(R.id.et1);iv =(ImageView)findViewById(R.id.iv1);bt1.setOnClickListener(new OnClickListener() {public void onClick(View v) {Toast.makeText(MainActivity.this, "你写可以扫描条形码或者二维码", Toast.LENGTH_SHORT).show();Intent startScan = new Intent(MainActivity.this, CaptureActivity.class);//startActivity(startScan);startActivityForResult(startScan, 0);}});bt2.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String str =et1.getText().toString();if(str.equals("")){Toast.makeText(MainActivity.this, "请输入文本", Toast.LENGTH_SHORT).show();}else{try {//第一个参数是要生成二维码的内容,第二个参数是生成二维码横向纵向长度Bitmap qrcode = EncodingHandler.createQRCode(et1.getText().toString(), 400);iv.setImageBitmap(qrcode);} catch (WriterException e) {e.printStackTrace();}}}});} protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode ==RESULT_OK){ String str =data.getExtras().getString("result"); tv1.setText(str); } }}
由于扫描功能用到照相机,和震动,需要加入permission:
演示:
①在EditText输入需要转换内容,点击生成二维码生成。
②点击打开扫描二维码按钮,扫描,显示输入的内容
(5)扫描框UI
由于库中自带的扫描框是横屏的,解决横屏和其他详见问题参考:
http://www.cnblogs.com/dolphin0520/p/3355728.html
扫描框其实是通过View画出来的,在zxing库中的包com.zxing.view的ViewfinderView类就是扫描框的UI,由于对View不怎么熟悉,只能凭我自己理解。
1.包 com.zxing.camera的CameraManager类中以下两个参数是可以控制框的大小
//控制框的最大宽度 private static final int MAX_FRAME_WIDTH = 480; //控制框的最大高度 private static final int MAX_FRAME_HEIGHT = 480;
2.包com.zxing.view的ViewfinderView类中以下代码获取到这个框
Rect frame = CameraManager.get().getFramingRect(); if (frame == null) { return;}
3在ondraw方法中对获得的框进行装饰
①绘制扫描框以外的阴影部分
// 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);
② 画出扫描框的四个角
paint.setColor(getResources().getColor(R.color.blues)); //左上角 canvas.drawRect(frame.left,frame.top, frame.left + ScreenRate,frame.top+ 10,paint); canvas.drawRect(frame.left,frame.top, frame.left + 10,frame.top+ ScreenRate,paint); //右上角 canvas.drawRect(frame.right- ScreenRate,frame.top, frame.right,frame.top + 10,paint); canvas.drawRect(frame.right- 10,frame.top, frame.right,frame.top + ScreenRate,paint); //左下角 canvas.drawRect(frame.left,frame.bottom - 10,frame.left + ScreenRate,frame.bottom,paint); canvas.drawRect(frame.left,frame.bottom - ScreenRate,frame.left + 10,frame.bottom,paint); //右下角 canvas.drawRect(frame.right- ScreenRate,frame.bottom - 10,frame.right,frame.bottom, paint);canvas.drawRect(frame.right- 10,frame.bottom - ScreenRate,frame.right,frame.bottom, paint);
③绘制框中移动的线(可以用图片实现)
//初始化中间线滑动的最上边和最下边 if(!isFirst){ isFirst = true; slideTop = frame.top; slideBottom = frame.bottom; } //绘制中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTANCE slideTop += SPEEN_DISTANCE; if(slideTop >= frame.bottom){ slideTop = frame.top; } canvas.drawRect(frame.left + MIDDLE_LINE_PADDING, slideTop - MIDDLE_LINE_WIDTH/2, frame.right - MIDDLE_LINE_PADDING,slideTop + MIDDLE_LINE_WIDTH/2, paint);
④画扫描框的边框
// Draw a two pixel solid black border inside the framing rect paint.setColor(frameColor); canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint); canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint); canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint); canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint);
⑤画扫描框下面的字
paint.setColor(Color.BLACK); paint.setTextSize(TEXT_SIZE * density); paint.setAlpha(0x40); paint.setTypeface(Typeface.create("System", Typeface.BOLD)); canvas.drawText(getResources().getString(R.string.scan_text), frame.left, (float) (frame.bottom + (float)TEXT_PADDING_TOP *density), paint);
⑥在扫描的时候,框里面会出现一些黄色点,将以下代码注释掉就不会有了
for (ResultPoint point : currentPossible) { canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint); }
问题(这是为了提醒博主以后深入研究的问题)
①手机离二维码很近的时候反而不能扫描出二维码,在一定距离后才能正常扫描出二维码(可能与内部算法有关)。
②扫描框下字体颜色很暗,即使用了WITHE,(可能是因为在绘制阴影部分的时候,掩盖了字体的颜色,需要去看看View详解),所以在这里直接用TextView 在camera.xml写出来。缺点是当扫描框大小改变的时候,TextView位置不改变。
③中间移动的线在扫描时候不平滑
④...
参考网址与博客:
http://www.cnblogs.com/dolphin0520/p/3355728.html
http://blog.csdn.net/xiaanming/article/details/10163203?D2kdVYKfPI_-8QXCzICABQ&ved=0CBkQFjABOIwB&usg=AFQjCNF2ULtaIMPd5bndaol7tFI3AO61Xw
http://blog.csdn.net/xinchen200/article/details/18036695
http://www.jikexueyuan.com/course/134_3.html?ss=1
更多相关文章
- Android(安卓)Studio插件-自动根据布局生成Activity等代码(插件
- 分享开发 Android(安卓)手机应用的开发经验——QR生成器
- Android的签名文件生成两种方法
- Android(安卓)USB 扫码枪获取扫描内容
- Android: NDK编程
- 与ios相比,android为什么越用越卡
- 纪念一下坑爹的蓝牙扫描枪连接(Android外接输入设备)
- Android(安卓)app中加载jar插件
- Android新技术------Android(安卓)App Bundle之bundletool的使用