Android基于google Zxing实现二维码的生成

Android基于google Zxing实现二维码的生成,第1张

概述最近项目用到了二维码生成与识别,之前没有接触这块,然后就上网搜了搜,发现有好多这方面的资源,特别是googleZxing对二维码的封装,实现的已经不错了,可以直接拿过来引用,下载了他们的源码后,只做了少少的改动

最近项目用到了二维码的生成与识别,之前没有接触这块,然后就上网搜了搜,发现有好多这方面的资源,特别是Google Zxing对二维码的封装,实现的已经不错了,可以直接拿过来引用,下载了他们的源码后,只做了少少的改动,就是在Demo中增加了长按识别的功能,网上虽然也有长按识别的Demo,但好多下载下来却无法运行,然后总结了一下,加在了下面的Demo中。  
下面来介绍这个Demo的主类

public class barCodeTestActivity extends Activity {   private TextVIEw resultTextVIEw; private EditText qrStrEditText; private ImageVIEw qrimgImageVIEw; private String time;  private file file = null;  @OverrIDe  public voID onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentVIEw(R.layout.main);     resultTextVIEw = (TextVIEw) this.findVIEwByID(R.ID.tv_scan_result);   qrStrEditText = (EditText) this.findVIEwByID(R.ID.et_qr_string);   qrimgImageVIEw = (ImageVIEw) this.findVIEwByID(R.ID.iv_qr_image);      button scanbarCodebutton = (button) this.findVIEwByID(R.ID.btn_scan_barcode);   scanbarCodebutton.setonClickListener(new OnClickListener() {  @OverrIDe public voID onClick(VIEw v) { //打开扫描界面扫描条形码或二维码 Intent openCameraIntent = new Intent(barCodeTestActivity.this,CaptureActivity.class); startActivityForResult(openCameraIntent,0); } }); qrimgImageVIEw.setonLongClickListener(new OnLongClickListener() {  @OverrIDe public boolean onLongClick(VIEw v) { // 长按识别二维码   saveCurrentimage(); return true; } });     button generateQRCodebutton = (button) this.findVIEwByID(R.ID.btn_add_qrcode);   generateQRCodebutton.setonClickListener(new OnClickListener() {  @OverrIDe public voID onClick(VIEw v) { try { String contentString = qrStrEditText.getText().toString(); if (!contentString.equals("")) { //根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350) Bitmap qrCodeBitmap = EnCodingHandler.createQRCode(contentString,350); qrimgImageVIEw.setimageBitmap(qrCodeBitmap); }else { //提示文本不能是空的 Toast.makeText(barCodeTestActivity.this,"Text can not be empty",Toast.LENGTH_SHORT).show(); }  } catch (WriterException e) { // Todo auto-generated catch block e.printstacktrace(); } } });  }   //这种方法状态栏是空白,显示不了状态栏的信息  private voID saveCurrentimage()  {   //获取当前屏幕的大小   int wIDth = getwindow().getDecorVIEw().getRootVIEw().getWIDth();   int height = getwindow().getDecorVIEw().getRootVIEw().getHeight();   //生成相同大小的图片   Bitmap temBitmap = Bitmap.createBitmap( wIDth,height,Bitmap.Config.ARGB_8888 );   //找到当前页面的根布局   VIEw vIEw = getwindow().getDecorVIEw().getRootVIEw();   //设置缓存   vIEw.setDrawingCacheEnabled(true);   vIEw.buildDrawingCache();   //从缓存中获取当前屏幕的图片,创建一个DrawingCache的拷贝,因为DrawingCache得到的位图在禁用后会被回收   temBitmap = vIEw.getDrawingCache();   SimpleDateFormat df = new SimpleDateFormat("yyyymmddhhmmss");   time = df.format(new Date());   if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){    file = new file(Environment.getExternalStorageDirectory().getabsolutePath() + "/screen",time + ".png");    if(!file.exists()){     file.getParentfile().mkdirs();     try {      file.createNewfile();     } catch (IOException e) {      // Todo auto-generated catch block      e.printstacktrace();     }    }    fileOutputStream fos = null;    try {     fos = new fileOutputStream(file);     temBitmap.compress(Bitmap.CompressFormat.PNG,100,fos);     fos.flush();     fos.close();    } catch (fileNotFoundException e) {     e.printstacktrace();    } catch (IOException e) {     // Todo auto-generated catch block     e.printstacktrace();    }    new Thread(new Runnable() {     @OverrIDe     public voID run() {      String path = Environment.getExternalStorageDirectory().getabsolutePath() + "/screen/" + time + ".png";      final Result result = parseQRcodeBitmap(path);      runOnUiThread(new Runnable() {       public voID run() {       if(null!=result){       resultTextVIEw.setText(result.toString());       }else{        Toast.makeText(barCodeTestActivity.this,"无法识别",Toast.LENGTH_LONG).show();       }       }      });     }    }).start();    //禁用DrawingCahce否则会影响性能,而且不禁止会导致每次截图到保存的是缓存的位图    vIEw.setDrawingCacheEnabled(false);   }  }    //解析二维码图片,返回结果封装在Result对象中  private com.Google.zxing.Result parseQRcodeBitmap(String bitmapPath){   //解析转换类型UTF-8   Hashtable<DecodeHintType,String> hints = new Hashtable<DecodeHintType,String>();   hints.put(DecodeHintType.CHaraCTER_SET,"utf-8");   //获取到待解析的图片   BitmapFactory.Options options = new BitmapFactory.Options();    //如果我们把inJustDecodeBounds设为true,那么BitmapFactory.decodefile(String path,Options opt)   //并不会真的返回一个Bitmap给你,它仅仅会把它的宽,高取回来给你   options.inJustDecodeBounds = true;   //此时的bitmap是null,这段代码之后,options.outWIDth 和 options.outHeight就是我们想要的宽和高了   Bitmap bitmap = BitmapFactory.decodefile(bitmapPath,options);   //我们现在想取出来的图片的边长(二维码图片是正方形的)设置为400像素   /**    options.outHeight = 400;    options.outWIDth = 400;    options.inJustDecodeBounds = false;    bitmap = BitmapFactory.decodefile(bitmapPath,options);   */   //以上这种做法,虽然把bitmap限定到了我们要的大小,但是并没有节约内存,如果要节约内存,我们还需要使用inSimpleSize这个属性   options.inSampleSize = options.outHeight / 400;   if(options.inSampleSize <= 0){    options.inSampleSize = 1; //防止其值小于或等于0   }   /**    * 辅助节约内存设置    *    * options.inPreferredConfig = Bitmap.Config.ARGB_4444; // 默认是Bitmap.Config.ARGB_8888    * options.inPurgeable = true;    * options.ininputShareable = true;    */   options.inJustDecodeBounds = false;   bitmap = BitmapFactory.decodefile(bitmapPath,options);    //新建一个RGBluminanceSource对象,将bitmap图片传给此对象   RGBluminanceSource rgbluminanceSource = new RGBluminanceSource(bitmap);   //将图片转换成二进制图片   BinaryBitmap binaryBitmap = new BinaryBitmap(new HybrIDBinarizer(rgbluminanceSource));   //初始化解析对象   QRCodeReader reader = new QRCodeReader();   //开始解析   Result result = null;   try {    result = reader.decode(binaryBitmap,hints);   } catch (Exception e) {    // Todo: handle exception   }      return result;  }  @OverrIDe protected voID onActivityResult(int requestCode,int resultCode,Intent data) { super.onActivityResult(requestCode,resultCode,data); //处理扫描结果(在界面上显示) if (resultCode == RESulT_OK) { Bundle bundle = data.getExtras(); String scanResult = bundle.getString("result"); resultTextVIEw.setText(scanResult); } } } 

然后长按识别二维码调用了RGBluminanceSource这个类

public class RGBluminanceSource extends luminanceSource { private byte bitmapPixels[];  protected RGBluminanceSource(Bitmap bitmap) { super(bitmap.getWIDth(),bitmap.getHeight());  // 首先,要取得该图片的像素数组内容 int[] data = new int[bitmap.getWIDth() * bitmap.getHeight()]; this.bitmapPixels = new byte[bitmap.getWIDth() * bitmap.getHeight()]; bitmap.getPixels(data,getWIDth(),getHeight());  // 将int数组转换为byte数组,也就是取像素值中蓝色值部分作为辨析内容 for (int i = 0; i < data.length; i++) { this.bitmapPixels[i] = (byte) data[i]; } }  @OverrIDe public byte[] getMatrix() { // 返回我们生成好的像素数据 return bitmapPixels; }   @OverrIDe public byte[] getRow(int y,byte[] row) { // 这里要得到指定行的像素数据 System.arraycopy(bitmapPixels,y * getWIDth(),row,getWIDth()); return row; } } 

相机识别二维码调用了CaptureActivity这个类 

public class CaptureActivity extends Activity implements Callback {  private CaptureActivityHandler handler; private VIEwfinderVIEw vIEwfinderVIEw; private boolean hasSurface; private Vector<barcodeFormat> decodeFormats; private String characterSet; private InactivityTimer inactivityTimer; private MediaPlayer mediaPlayer; private boolean playBeep; private static final float BEEP_VolUME = 0.10f; private boolean vibrate; private button cancelScanbutton;  /** Called when the activity is first created. */ @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.camera);  CameraManager.init(getApplication()); vIEwfinderVIEw = (VIEwfinderVIEw) findVIEwByID(R.ID.vIEwfinder_vIEw); cancelScanbutton = (button) this.findVIEwByID(R.ID.btn_cancel_scan); hasSurface = false; inactivityTimer = new InactivityTimer(this); }  @OverrIDe protected voID onResume() { super.onResume(); SurfaceVIEw surfaceVIEw = (SurfaceVIEw) findVIEwByID(R.ID.prevIEw_vIEw); SurfaceHolder surfaceHolder = surfaceVIEw.getHolder(); if (hasSurface) { initCamera(surfaceHolder); } else { surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } decodeFormats = null; characterSet = null;   playBeep = true; AudioManager audioService = (AudioManager) getSystemService(AUdio_SERVICE); if (audioService.getRingerMode() != AudioManager.RINGER_MODE_norMAL) { playBeep = false; } initBeepSound(); vibrate = true;  //quit the scan vIEw cancelScanbutton.setonClickListener(new OnClickListener() {  @OverrIDe public voID onClick(VIEw v) { CaptureActivity.this.finish(); } }); }  @OverrIDe protected voID onPause() { super.onPause(); if (handler != null) { handler.quitSynchronously(); handler = null; } CameraManager.get().closeDriver(); }  @OverrIDe protected voID onDestroy() { inactivityTimer.shutdown(); super.onDestroy(); }  /** * Handler scan result * @param result * @param barcode */ public voID handleDecode(Result result,Bitmap barcode) { inactivityTimer.onActivity(); playBeepSoundAndVibrate(); String resultString = result.getText(); //FIXME if (resultString.equals("")) { //扫描失败 Toast.makeText(CaptureActivity.this,"Scan Failed!",Toast.LENGTH_SHORT).show(); }else { // System.out.println("Result:"+resultString); Intent resultIntent = new Intent(); Bundle bundle = new Bundle(); bundle.putString("result",resultString); resultIntent.putExtras(bundle); this.setResult(RESulT_OK,resultIntent); } CaptureActivity.this.finish(); }  private voID initCamera(SurfaceHolder surfaceHolder) { try { CameraManager.get().openDriver(surfaceHolder); } catch (IOException ioe) { return; } catch (RuntimeException e) { return; } if (handler == null) { handler = new CaptureActivityHandler(this,decodeFormats,characterSet); } }  @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 vIEwfinderVIEw; }  public Handler getHandler() { return handler; }  public voID drawVIEwfinder() { vIEwfinderVIEw.drawVIEwfinder(); } private voID initBeepSound() { if (playBeep && mediaPlayer == null) { // The volume on STREAM_SYstem is not adjustable,and users found it // too loud,// so we Now play on the music stream. setVolumeControlStream(AudioManager.STREAM_MUSIC); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setonCompletionListener(beepListener);  AssetfileDescriptor file = getResources().openRawResourceFd( R.raw.beep); try { mediaPlayer.setDataSource(file.getfileDescriptor(),file.getStartOffset(),file.getLength()); file.close(); mediaPlayer.setVolume(BEEP_VolUME,BEEP_VolUME); mediaPlayer.prepare(); } catch (IOException e) { mediaPlayer = null; } } }  private static final long VIBRATE_DURATION = 200L;  private voID playBeepSoundAndVibrate() { if (playBeep && mediaPlayer != null) { mediaPlayer.start(); } if (vibrate) { Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); vibrator.vibrate(VIBRATE_DURATION); } }  /** * When the beep has finished playing,rewind to queue up another one. */ private final OnCompletionListener beepListener = new OnCompletionListener() { public voID onCompletion(MediaPlayer mediaPlayer) { mediaPlayer.seekTo(0); } };   } 

下面是主布局mian文件

<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:layout_wIDth="fill_parent"  androID:layout_height="fill_parent"  androID:background="@androID:color/white"  androID:orIEntation="vertical" >    <button   androID:ID="@+ID/btn_scan_barcode"   androID:layout_wIDth="fill_parent"   androID:layout_height="wrap_content"   androID:layout_margintop="30dp"   androID:text="Open camera" />    <linearLayout   androID:orIEntation="horizontal"   androID:layout_margintop="10dp"   androID:layout_wIDth="fill_parent"   androID:layout_height="wrap_content">      <TextVIEw   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content"   androID:textcolor="@androID:color/black"   androID:textSize="18sp"   androID:text="Scan result:" />      <TextVIEw   androID:ID="@+ID/tv_scan_result"   androID:layout_wIDth="fill_parent"   androID:textSize="18sp"   androID:textcolor="@androID:color/black"   androID:layout_height="wrap_content" />  </linearLayout>    <EditText   androID:ID="@+ID/et_qr_string"   androID:layout_wIDth="fill_parent"   androID:layout_height="wrap_content"   androID:layout_margintop="30dp"   androID:hint="input the text"/>    <button   androID:ID="@+ID/btn_add_qrcode"   androID:layout_wIDth="fill_parent"   androID:layout_height="wrap_content"   androID:text="Generate QRcode" />    <ImageVIEw   androID:ID="@+ID/iv_qr_image"   androID:layout_wIDth="250dp"   androID:layout_height="250dp"   androID:scaleType="fitXY"   androID:layout_margintop="10dp"   androID:layout_gravity="center"/>   </linearLayout>

 详细了解的请下载demo自己看,Demo中解决了在竖拍解码时二维码被拉伸的现象。
不过我遇到了一个问题是 二维码的扫描框调大后,扫描的灵敏度降低了,希望知道的朋友给指导下
有兴趣的可以下载Demo看一看:google Zxing实现二维码的生成

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android基于google Zxing实现二维码的生成全部内容,希望文章能够帮你解决Android基于google Zxing实现二维码的生成所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1149186.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存