Android开发实现模仿360二维码扫描功能实例详解

Android开发实现模仿360二维码扫描功能实例详解,第1张

概述本文实例讲述了Android开发实现模仿360二维码扫描功能的方法。分享给大家供大家参考,具体如下:

本文实例讲述了AndroID开发实现模仿360二维码扫描功能的方法。分享给大家供大家参考,具体如下:

一、效果图:

二、框架搭建

1、首先,下载最新zxing开源项目。 下载地址:http://code.google.com/p/zxing/

或 点击此处本站下载

2、分析项目结构,明确扫描框架需求。在zxing中,有很多其他的功能,项目结构比较复杂;针对二维码QRCode扫描,我们需要几个包:

(1)com.Google.zxing.clIEnt.androID.Camera 基于Camera调用以及参数配置,核心包
(2)DecodeFormatManager、DecodeThread、DecodeHandler 基于解码格式、解码线程、解码结果处理的解码类
(3)VIEwfinderVIEw、VIEwfinderResultPointCallBack 基于取景框视图定义的VIEw类
(4)CaptureActivity、CaptureActivityHandler 基于扫描Activity以及扫描结果处理的Capture类
(5)InactivityTimer、BeepManager、FinishListener 基于休眠、声音、退出的辅助管理类
(6)Intents、IntentSource、PrefrencesActivity 基于常量存储的常量类

3、新建工程,添加如下权限permission:

<uses-permission androID:name="androID.permission.CAMERA"/><uses-permission androID:name="androID.permission.INTERNET" /><uses-permission androID:name="androID.permission.VIBRATE" /><uses-permission androID:name="androID.permission.FLASHliGHT" />

4、 添加core.jar文件,并Buildpath;将上述类或包加入工程后,会报一系列错误,原因有几点:

(1)资源文件缺乏,将zxing下需要的资源文件copy到新工程下
(2)版本兼容问题,zxing下很多技术都是使用4.0版本及以上,集成到低版本之后,须做相应改动,详情参照项目源码
(3)包结构引用问题,需要重新导入包引用

5、最后框架

三、具体实现

1、创建MainActivity用于跳转到扫描页面

/** * 二维码扫描 * @Project  App_ZXing * @Package  com.androID.scan * @author   chenlin * @version  1.0 * @Date    2014年3月6日 */public class MainActivity extends Activity {  private button mBtnScan;  private button mBtnBack;  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    mBtnBack = (button) findVIEwByID(R.ID.btn_back);    mBtnBack.setVisibility(VIEw.GONE);    mBtnScan = (button) findVIEwByID(R.ID.btn_scan);    mBtnScan.setonClickListener(new VIEw.OnClickListener() {      @OverrIDe      public voID onClick(VIEw v) {        startActivity(new Intent(MainActivity.this,ScanActivity.class));      }    });  }}

布局文件

<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  xmlns:tools="http://schemas.androID.com/tools"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent" >  <button    androID:ID="@+ID/btn_scan"    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:layout_centerInParent="true"    androID:textcolor="@color/white"    androID:padding="20dp"    androID:background="@drawable/btn_scan_result"    androID:text="扫一扫" />  <include      androID:layout_wIDth="fill_parent"      androID:layout_height="wrap_content"      androID:layout_alignParenttop="true"      layout="@layout/activity_scan_Title" /></relativeLayout>

2、扫描页面

/** * 条形码扫描 * * @Project App_ZXing * @Package com.androID.scan * @author chenlin * @version 1.0 * @Date 2014年3月6日 */public class ScanActivity extends Activity implements Callback {  private static final float BEEP_VolUME = 0.10f;  protected static final String RESulT_TEXT = "result";  protected static final String RESulT_BITMAP = "bitmap";  /** 扫描界面 */  private SurfaceVIEw mSurfaceVIEw;  /** 自定义的VIEw,就是我们看见的拍摄时中间的框框了 */  private VIEwfinderVIEw mFindVIEw;  /** 解码处理类,负责调用另外的线程进行解码。 */  private CaptureActivityHandler mHandler;  /** 判断是否创建了SurfaceVIEw */  private boolean hasSurface;  /** decodeFormats 条形码,二维码等的集合 */  private Vector<barcodeFormat> mDecodeFormats;  /** 字符编码 */  private String characterSet;  /** 定时器 */  private InactivityTimer inactivityTimer;  /** 媒体播放器 */  private MediaPlayer mediaPlayer;  /** 是否播放声音 */  private boolean playBeep;  /** 是否震动 */  private boolean vibrate;  @OverrIDe  public voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_scan);    init();  }  /**   * 初始化   */  private voID init() {    mSurfaceVIEw = (SurfaceVIEw) findVIEwByID(R.ID.prevIEw_vIEw);    mFindVIEw = (VIEwfinderVIEw) findVIEwByID(R.ID.vIEwfinder_vIEw);    CameraManager.init(getApplication());    hasSurface = false;    inactivityTimer = new InactivityTimer(this);  }  /**   * 暂停后恢复时处理内容   */  @SuppressWarnings("all")  @OverrIDe  protected voID onResume() {    super.onResume();    // 先重新获得holder    SurfaceHolder surfaceHolder = mSurfaceVIEw.getHolder();    if (hasSurface) {      initCamera(surfaceHolder);    } else {      surfaceHolder.addCallback(this);      surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }    mDecodeFormats = null;    characterSet = null;    playBeep = true;    AudioManager audioService = (AudioManager) getSystemService(AUdio_SERVICE);    // 如果当前是铃音模式,则继续准备下面的 蜂鸣提示音 *** 作,如果是静音或者震动模式。就不要继续了。因为用户选择了无声的模式,我们就也不要出声了。    if (audioService.getRingerMode() != AudioManager.RINGER_MODE_norMAL) {      playBeep = false;    }    // 初始化播放声音    initBeepSound();    //播放    vibrate = true;  }  @OverrIDe  protected voID onPause() {    super.onPause();    if (mHandler != null) {      mHandler.quitSynchronously();      mHandler = null;    }    // 关闭摄像头信息    CameraManager.get().closeDriver();  }  @OverrIDe  protected voID onDestroy() {    // 关闭定时器    inactivityTimer.shutdown();    super.onDestroy();  }  /**   * 处理扫描结果   *   * @param result   * @param barcode   */  public voID handleDecode(Result result,Bitmap barcode) {    // 添加定时器    inactivityTimer.onActivity();    // 响铃和震动    playBeepSoundAndVibrate();    String resultString = result.getText();    if (TextUtils.isEmpty(resultString)) {      ToastUtil.show(this,"扫描失败");      ScanActivity.this.finish();    } else {      //扫描完成后传递结果      Intent resultIntent = new Intent();      resultIntent.setClass(ScanActivity.this,ScanResultActivity.class);      resultIntent.putExtra(RESulT_TEXT,resultString);      ByteArrayOutputStream baos = new ByteArrayOutputStream();      barcode.compress(Bitmap.CompressFormat.PNG,100,baos);      byte[] bitmapByte = baos.toByteArray();      resultIntent.putExtra(RESulT_BITMAP,bitmapByte);      startActivity(resultIntent);      overrIDePendingTransition(R.anim.activity_in_from_rigth,R.anim.activity_out_to_scale);      ScanActivity.this.finish();    }  }  private voID initCamera(SurfaceHolder surfaceHolder) {    try {      CameraManager.get().openDriver(surfaceHolder);    } catch (IOException ioe) {      return;    } catch (RuntimeException e) {      return;    }    if (mHandler == null) {      mHandler = new CaptureActivityHandler(this,mDecodeFormats,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 mFindVIEw;  }  public Handler getHandler() {    return mHandler;  }  public voID drawVIEwfinder() {    mFindVIEw.drawVIEwfinder();  }  /**   * 初始化声音资源   */  private voID initBeepSound() {    // 如果要播放声音并且没有播放器时    if (playBeep && mediaPlayer == null) {      // 设置声道流格式为音乐      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);      // 第一个参数,指代一个震动的频率数组。每两个为一组,每组的第一个为等待时间,第二个为震动时间。      // 比如 [2000,500,400],会先等待2000毫秒,震动500,再等待100,震动400      // 第二个参数,repest指代从 第几个索引(第一个数组参数) 的位置开始循环震动。      // 会一直保持循环,我们需要用 vibrator.cancel()主动终止      // vibrator.vibrate(new long[]{300,500},0);    }  }  /**   * 注册事件。当播放完毕一次后,重新指向流文件的开头,以准备下次播放。   */  private final MediaPlayer.OnCompletionListener beepListener = new MediaPlayer.OnCompletionListener() {    public voID onCompletion(MediaPlayer mediaPlayer) {      mediaPlayer.seekTo(0);    }  };}

布局文件

<?xml version="1.0" enCoding="utf-8"?><FrameLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent" >  <relativeLayout    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent" >    <SurfaceVIEw      androID:ID="@+ID/prevIEw_vIEw"      androID:layout_wIDth="fill_parent"      androID:layout_height="fill_parent"      androID:layout_gravity="center" />    <com.androID.scan.vIEw.VIEwfinderVIEw      androID:ID="@+ID/vIEwfinder_vIEw"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content" />    <include      androID:layout_wIDth="fill_parent"      androID:layout_height="wrap_content"      androID:layout_alignParenttop="true"      layout="@layout/activity_scan_Title" />  </relativeLayout></FrameLayout>

3、结果页面

/** * * @Project App_ZXing * @Package com.androID.scan * @author chenlin * @version 1.0 * @Date 2014年3月6日 * @Note Todo */public class ScanResultActivity extends Activity {  private EditText mEtScan;  private button mBtnBack;  private button mBtncopy;  private ImageVIEw mImageVIEw;  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_scan_result);    initVIEws();    init();  }  private voID init() {    final String result = getIntent().getStringExtra(ScanActivity.RESulT_TEXT);    mEtScan.setText(result);    final ClipboardManager cm = (ClipboardManager) getSystemService(CliPBOARD_SERVICE);    mBtnBack.setonClickListener(new VIEw.OnClickListener() {      @OverrIDe      public voID onClick(VIEw v) {        ScanResultActivity.this.finish();      }    });    mBtncopy.setonClickListener(new OnClickListener() {      @OverrIDe      public voID onClick(VIEw v) {        if (result!=null) {          ClipData myClip = ClipData.newPlainText("text",result);          cm.setPrimaryClip(myClip);        }      }    });    //设置图片信息    byte[] imgByte = getIntent().getByteArrayExtra(ScanActivity.RESulT_BITMAP);    if (imgByte != null) {      Drawable drawable = BitmapUtil.byte2Drawable(imgByte);      if (drawable != null) {        mImageVIEw.setimageDrawable(drawable);      }    }  }  // public voID paste(VIEw vIEw){  // ClipData abc = myClipboard.getPrimaryClip();  // ClipData.Item item = abc.getItemAt(0);  // String text = item.getText().toString();  // pasteFIEld.setText(text);  // Toast.makeText(getApplicationContext(),"Text Pasted",// Toast.LENGTH_SHORT).show();  // }  private voID initVIEws() {    mEtScan = (EditText) findVIEwByID(R.ID.et_scan_result);    mBtnBack = (button) findVIEwByID(R.ID.btn_back);    mBtncopy = (button) findVIEwByID(R.ID.btn_copy);  }}

四、代码下载

完整实例代码点击此处本站下载

PS:这里再为大家推荐一款二维码在线生成工具供大家参考使用:

在线生成二维码工具(加强版)
http://tools.jb51.net/transcoding/jb51qrcode

更多关于AndroID相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android数据库 *** 作技巧总结》、《Android编程之activity *** 作技巧总结》、《Android文件 *** 作技巧汇总》、《Android资源 *** 作技巧汇总》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家AndroID程序设计有所帮助。

总结

以上是内存溢出为你收集整理的Android开发实现模仿360二维码扫描功能实例详解全部内容,希望文章能够帮你解决Android开发实现模仿360二维码扫描功能实例详解所遇到的程序开发问题。

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

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

原文地址: http://outofmemory.cn/web/1144119.html

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

发表评论

登录后才能评论

评论列表(0条)

保存