、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

Android二维码扫描我们可以调用Zing.jar包,用人家写好的代码,我们只需要根据自己的需要修改布局即可.下面我简单介绍一下Android我们怎么来用和修改人家的代码.

1、下载Zing.jar包http://download.csdn.net/detail/u013132758/9361939

2、解压导入项目可以用了。

效图如下:


详细介绍一下如何根据自己的需求来修改代码:

首先在AndroidMainfest。xml中添加权限

  

 

   
   

    
   
   

1、项目结构如下所示


2、若修改扫描框的大小可在CameraManager里面修改参数width,height该项目中我设置为0.7倍的屏幕宽度。

CameraManager.java

package com.zm.app.zxing.camera;/* * Copyright (C) 2008 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */import java.io.IOException;import java.util.List;import android.content.Context;import android.graphics.PixelFormat;import android.graphics.Point;import android.graphics.Rect;import android.hardware.Camera;import android.os.Build;import android.os.Handler;import android.util.DisplayMetrics;import android.util.Log;import android.view.SurfaceHolder;import com.zm.app.zxing.camera.PlanarYUVLuminanceSource;/** * This object wraps the Camera service object and expects to be the only one talking to it. The * implementation encapsulates the steps needed to take preview-sized images, which are used for * both preview and decoding. * */public final class CameraManager {  private static final String TAG = CameraManager.class.getSimpleName();  private static CameraManager cameraManager;  static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT  static {    int sdkInt;    try {      sdkInt = Integer.parseInt(Build.VERSION.SDK);    } catch (NumberFormatException nfe) {      // Just to be safe      sdkInt = 10000;    }    SDK_INT = sdkInt;  }  private final Context context;  private final CameraConfigurationManager configManager;  private Camera camera;  private Rect framingRect;  private Rect framingRectInPreview;  private boolean initialized;  private boolean previewing;  private final boolean useOneShotPreviewCallback;  /**   * Preview frames are delivered here, which we pass on to the registered handler. Make sure to   * clear the handler so it will only receive one message.   */  private final PreviewCallback previewCallback;  /** Autofocus callbacks arrive here, and are dispatched to the Handler which requested them. */  private final AutoFocusCallback autoFocusCallback;  /**   * Initializes this static object with the Context of the calling Activity.   *   * @param context The Activity which wants to use the camera.   */  public static void init(Context context) {    if (cameraManager == null) {      cameraManager = new CameraManager(context);    }  }  /**   * Gets the CameraManager singleton instance.   *   * @return A reference to the CameraManager singleton.   */  public static CameraManager get() {    return cameraManager;  }  private CameraManager(Context context) {    this.context = context;    this.configManager = new CameraConfigurationManager(context);    // Camera.setOneShotPreviewCallback() has a race condition in Cupcake, so we use the older    // Camera.setPreviewCallback() on 1.5 and earlier. For Donut and later, we need to use    // the more efficient one shot callback, as the older one can swamp the system and cause it    // to run out of memory. We can't use SDK_INT because it was introduced in the Donut SDK.    //useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.CUPCAKE;    useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 3; // 3 = Cupcake    previewCallback = new PreviewCallback(configManager, useOneShotPreviewCallback);    autoFocusCallback = new AutoFocusCallback();  }  /**   * Opens the camera driver and initializes the hardware parameters.   *   * @param holder The surface object which the camera will draw preview frames into.   * @throws IOException Indicates the camera driver failed to open.   */  public void openDriver(SurfaceHolder holder) throws IOException {    if (camera == null) {      camera = Camera.open();      if (camera == null) {        throw new IOException();      }      camera.setPreviewDisplay(holder);      if (!initialized) {        initialized = true;        configManager.initFromCameraParameters(camera);      }      configManager.setDesiredCameraParameters(camera);      //FIXME      //     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);      //�Ƿ�ʹ��ǰ��//      if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false)) {//        FlashlightManager.enableFlashlight();//      }      FlashlightManager.enableFlashlight();    }  }  public void openLight(){    if (camera != null) {      Camera.Parameters parameter;      parameter = camera.getParameters();      parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);      camera.setParameters(parameter);    }  }  public void offLight(){    if (camera != null) {      Camera.Parameters parameter;      parameter = camera.getParameters();      parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);      camera.setParameters(parameter);    }  }  /**   * Closes the camera driver if still in use.   */  public void closeDriver() {    if (camera != null) {      FlashlightManager.disableFlashlight();      camera.release();      camera = null;    }  }  /**   * Asks the camera hardware to begin drawing preview frames to the screen.   */  public void startPreview() {    if (camera != null && !previewing) {      camera.startPreview();      previewing = true;    }  }  /**   * Tells the camera to stop drawing preview frames.   */  public void stopPreview() {    if (camera != null && previewing) {      if (!useOneShotPreviewCallback) {        camera.setPreviewCallback(null);      }      camera.stopPreview();      previewCallback.setHandler(null, 0);      autoFocusCallback.setHandler(null, 0);      previewing = false;    }  }  /**   * A single preview frame will be returned to the handler supplied. The data will arrive as byte[]   * in the message.obj field, with width and height encoded as message.arg1 and message.arg2,   * respectively.   *   * @param handler The handler to send the message to.   * @param message The what field of the message to be sent.   */  public void requestPreviewFrame(Handler handler, int message) {    if (camera != null && previewing) {      previewCallback.setHandler(handler, message);      if (useOneShotPreviewCallback) {        camera.setOneShotPreviewCallback(previewCallback);      } else {        camera.setPreviewCallback(previewCallback);      }    }  }  /**   * Asks the camera hardware to perform an autofocus.   *   * @param handler The Handler to notify when the autofocus completes.   * @param message The message to deliver.   */  public void requestAutoFocus(Handler handler, int message) {    if (camera != null && previewing) {      autoFocusCallback.setHandler(handler, message);      //Log.d(TAG, "Requesting auto-focus callback");      camera.autoFocus(autoFocusCallback);    }  }  /**   * Calculates the framing rect which the UI should draw to show the user where to place the   * barcode. This target helps with alignment as well as forces the user to hold the device   * far enough away to ensure the image will be in focus.   *   * @return The rectangle to draw on screen in window coordinates.   */  public Rect getFramingRect() {    Point screenResolution = configManager.getScreenResolution();    if (framingRect == null) {      if (camera == null) {        return null;      }      DisplayMetrics metrics = context.getResources().getDisplayMetrics();      //定义扫描矿的宽和高分别为0.7倍的屏幕宽度和高度      int width = (int)(metrics.widthPixels*0.7);      int height = width;      int leftOffset = (screenResolution.x - width) / 2;      int topOffset = (screenResolution.y - height) / 2;      framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);      Log.d(TAG, "Calculated framing rect: " + framingRect);    }    return framingRect;  }  /**   * Like {@link #getFramingRect} but coordinates are in terms of the preview frame,   * not UI / screen.   */  public Rect getFramingRectInPreview() {    if (framingRectInPreview == null) {      Rect rect = new Rect(getFramingRect());      Point cameraResolution = configManager.getCameraResolution();      Point screenResolution = configManager.getScreenResolution();      //modify here//      rect.left = rect.left * cameraResolution.x / screenResolution.x;//      rect.right = rect.right * cameraResolution.x / screenResolution.x;//      rect.top = rect.top * cameraResolution.y / screenResolution.y;//      rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;      rect.left = rect.left * cameraResolution.y / screenResolution.x;      rect.right = rect.right * cameraResolution.y / screenResolution.x;      rect.top = rect.top * cameraResolution.x / screenResolution.y;      rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;      framingRectInPreview = rect;    }    return framingRectInPreview;  }  /**   * 通过设置Camera打开闪光灯   */  public void turnLightOn()  {    Log.e(TAG,"闪光灯相机=======没开");    if (camera == null)    {      Log.e(TAG,"闪光灯相机没开");      return;    }    Log.e(TAG,"闪光灯相机====%%%%%%%===没开");    Camera.Parameters parameters = camera.getParameters();    if (parameters == null)    {      return;    }    List flashModes = parameters.getSupportedFlashModes();    if (flashModes == null)    {      return;    }    String flashMode = parameters.getFlashMode();//    Log.i(TAG, Flash mode:  + flashMode);//    Log.i(TAG, Flash modes:  + flashModes);//    // 闪光灯关闭状态    if (!Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode))    {      // Turn on the flash      if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH))      {        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);        camera.setParameters(parameters);        camera.startPreview();      }      else      {      }    }  }  /**   * 通过设置Camera关闭闪光灯   *   */  public void turnLightOff()  {    if (camera == null)    {      Log.e(TAG,"闪光灯相机没开");      return;    }    Camera.Parameters parameters = camera.getParameters();    if (parameters == null)    {      return;    }    List flashModes = parameters.getSupportedFlashModes();    String flashMode = parameters.getFlashMode();    // Check if camera flash exists    if (flashModes == null)    {      return;    }    // 闪光灯打开状态    if (!Camera.Parameters.FLASH_MODE_OFF.equals(flashMode))    {      // Turn off the flash      if (flashModes.contains(Camera.Parameters.FLASH_MODE_OFF))      {        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);        camera.setParameters(parameters);      }      else      {        Log.e(TAG, "FLASH_MODE_OFF not supported");      }    }  }  /**   * Converts the result points from still resolution coordinates to screen coordinates.   *   * @param points The points returned by the Reader subclass through Result.getResultPoints().   * @return An array of Points scaled to the size of the framing rect and offset appropriately   *         so they can be drawn in screen coordinates.   */  /*  public Point[] convertResultPoints(ResultPoint[] points) {    Rect frame = getFramingRectInPreview();    int count = points.length;    Point[] output = new Point[count];    for (int x = 0; x < count; x++) {      output[x] = new Point();      output[x].x = frame.left + (int) (points[x].getX() + 0.5f);      output[x].y = frame.top + (int) (points[x].getY() + 0.5f);    }    return output;  }   */  /**   * A factory method to build the appropriate LuminanceSource object based on the format   * of the preview buffers, as described by Camera.Parameters.   *   * @param data A preview frame.   * @param width The width of the image.   * @param height The height of the image.   * @return A PlanarYUVLuminanceSource instance.   */  public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {    Rect rect = getFramingRectInPreview();    int previewFormat = configManager.getPreviewFormat();    String previewFormatString = configManager.getPreviewFormatString();    switch (previewFormat) {      // This is the standard Android format which all devices are REQUIRED to support.      // In theory, it's the only one we should ever care about.      case PixelFormat.YCbCr_420_SP:        // This format has never been seen in the wild, but is compatible as we only care        // about the Y channel, so allow it.      case PixelFormat.YCbCr_422_SP:        return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,                rect.width(), rect.height());      default:        // The Samsung Moment incorrectly uses this variant instead of the 'sp' version.        // Fortunately, it too has all the Y data up front, so we can read it.        if ("yuv420p".equals(previewFormatString)) {          return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,                  rect.width(), rect.height());        }    }    throw new IllegalArgumentException("Unsupported picture format: " +            previewFormat + '/' + previewFormatString);  }  public Context getContext() {    return context;  }}
3、要修改扫描界面,自己画界面可在ViewfinderView中修改

ViewfinderView.java

package com.zm.app.zxing.view;import android.content.Context;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.Typeface;import android.util.AttributeSet;import android.view.View;import com.example.qr_codescan.R;import com.google.zxing.ResultPoint;import java.util.Collection;import java.util.HashSet;/** * Created by leiqi on 15-12-9. */public class ViewfinderView extends View {private static final String TAG = "log";/** * 刷新界面的时间 */private static final long ANIMATION_DELAY = 10L;private static final int OPAQUE = 0xFF;/** * 四个绿色边角对应的长度 */private int ScreenRate;/** * 四个绿色边角对应的宽度 */private static final int CORNER_WIDTH = 5;/** * 扫描框中的中间线的宽度 */private static final int MIDDLE_LINE_WIDTH = 5;/** * 扫描框中的中间线的与扫描框左右的间隙 */private static final int MIDDLE_LINE_PADDING = 5;/** * 中间那条线每次刷新移动的距离 */private static final int SPEEN_DISTANCE = 5;/** * 手机的屏幕密度 */private static float density;/** * 字体大小 */private static final int TEXT_SIZE = 18;private static final int TEXT_SIZE1 = 22;/** * 字体距离扫描框下面的距离 */private static final int TEXT_PADDING_TOP = 30;/** * 画笔对象的引用 */private Paint paint;/** * 中间滑动线的最顶端位置 */private int slideTop;/** * 中间滑动线的最底端位置 */private int slideBottom;/** * 将扫描的二维码拍下来,这里没有这个功能,暂时不考虑 */private Bitmap resultBitmap;private final int maskColor;private final int resultColor;private final int resultPointColor;private Collection possibleResultPoints;private Collection lastPossibleResultPoints;boolean isFirst;public ViewfinderView(Context context, AttributeSet attrs) {super(context, attrs);density = context.getResources().getDisplayMetrics().density;//将像素转换成dpScreenRate = (int) (20 * density);paint = new Paint();Resources resources = getResources();maskColor = resources.getColor(R.color.viewfinder_mask);resultColor = resources.getColor(R.color.result_view);resultPointColor = resources.getColor(R.color.possible_result_points);possibleResultPoints = new HashSet(5);}@Overridepublic void onDraw(Canvas canvas) {//中间的扫描框,你要修改扫描框的大小,去CameraManager里面修改Rect frame = com.zm.app.zxing.camera.CameraManager.get().getFramingRect();if (frame == null) {return;}//初始化中间线滑动的最上边和最下边if (!isFirst) {isFirst = true;slideTop = frame.top;slideBottom = frame.bottom;}//获取屏幕的宽和高int width = canvas.getWidth();int height = canvas.getHeight();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 rectanglepaint.setAlpha(OPAQUE);canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);} else {////画扫描框上面的字//paint.setColor(Color.rgb(255,255,255));//paint.setTextSize(TEXT_SIZE1 * density);//paint.setAlpha(0x40);//paint.setTypeface(Typeface.create("System", Typeface.BOLD));//canvas.drawText(getResources().getString(R.string.Return_car), frame.left, (float) (frame.top - (float) TEXT_PADDING_TOP * density), paint);//画扫描框边上的角,总共8个部分paint.setColor(Color.rgb(33,134,116));canvas.drawRect(frame.left, frame.top, frame.left + ScreenRate,frame.top + CORNER_WIDTH, paint);canvas.drawRect(frame.left, frame.top, frame.left + CORNER_WIDTH, frame.top+ ScreenRate, paint);canvas.drawRect(frame.right - ScreenRate, frame.top, frame.right,frame.top + CORNER_WIDTH, paint);canvas.drawRect(frame.right - CORNER_WIDTH, frame.top, frame.right, frame.top+ ScreenRate, paint);canvas.drawRect(frame.left, frame.bottom - CORNER_WIDTH, frame.left+ ScreenRate, frame.bottom, paint);canvas.drawRect(frame.left, frame.bottom - ScreenRate,frame.left + CORNER_WIDTH, frame.bottom, paint);canvas.drawRect(frame.right - ScreenRate, frame.bottom - CORNER_WIDTH,frame.right, frame.bottom, paint);canvas.drawRect(frame.right - CORNER_WIDTH, frame.bottom - ScreenRate,frame.right, frame.bottom, paint);//绘制中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTANCEslideTop += 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);//画扫描框下面的字paint.setColor(Color.WHITE);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);Collection currentPossible = possibleResultPoints;Collection currentLast = lastPossibleResultPoints;if (currentPossible.isEmpty()) {lastPossibleResultPoints = null;} else {possibleResultPoints = new HashSet(5);lastPossibleResultPoints = currentPossible;paint.setAlpha(OPAQUE);paint.setColor(resultPointColor);for (ResultPoint point : currentPossible) {canvas.drawCircle(frame.left + point.getX(), frame.top+ point.getY(), 6.0f, paint);}}if (currentLast != null) {paint.setAlpha(OPAQUE / 2);paint.setColor(resultPointColor);for (ResultPoint point : currentLast) {canvas.drawCircle(frame.left + point.getX(), frame.top+ point.getY(), 3.0f, paint);}}//只刷新扫描框的内容,其他地方不刷新postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top,frame.right, frame.bottom);}}public void drawViewfinder() {resultBitmap = null;invalidate();}/** * Draw a bitmap with the result points highlighted instead of the live * scanning display. * * @param barcode An image of the decoded barcode. */public void drawResultBitmap(Bitmap barcode) {resultBitmap = barcode;invalidate();}public void addPossibleResultPoint(ResultPoint point) {possibleResultPoints.add(point);}}


4、打开关闭闪光灯

打开关闭闪光灯直接调用

CameraManager.get().openLight();

CameraManager.get().offLight();

public void openLight(){    if (camera != null) {      Camera.Parameters parameter;      parameter = camera.getParameters();      parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);      camera.setParameters(parameter);    }  }  public void offLight(){    if (camera != null) {      Camera.Parameters parameter;      parameter = camera.getParameters();      parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);      camera.setParameters(parameter);    }  }



更多相关文章

  1. 创建 cocos2d-x+lua for android 步骤
  2. Android下修改SeekBar样式
  3. Android实现透明式状态栏
  4. Android初学习 - android:sharedUserId="android.uid.system" 应
  5. Android(安卓)UI开发第三十三篇——Navigation Drawer For Andro
  6. android 扫描SD卡与系统文件(转)
  7. 如何修改应用兼容Android(安卓)3.0系统
  8. 修复 XE8 for Android(安卓)方向传感器 headingX,Y,Z 不会动的问
  9. 修改EditText的光标颜色

随机推荐

  1. Android系列学习:handler,HandlerThread
  2. Android实现OCR扫描识别数字图片之图片扫
  3. android:gravity和android:layout_gravit
  4. Android(安卓)USB下的Accessory模式
  5. Android(安卓)UI学习组件概述
  6. 为什么老妈放弃了 Android(安卓)手机,买了
  7. Android(安卓)Framework学习——view的创
  8. Android(安卓)设置合理的定时器隔一段时
  9. Android(安卓)下的java.security和window
  10. Dojo Mobile:iPhone/Android的Web应用开发