在上一篇博文中(一个工程导入Zxing库实现二维码扫码功能)讲解了如何将zxing库加入到自己的工程里面,但是最后只能横屏扫描二维码,竖屏扫描二维码竟然不识别。这一点都不符合用户的习惯,所以现在来看看如何实现基于zxing的竖屏扫描二维码。

1. 修改AndroidManifest.xml

修改AndroidManifest.xmlCaptureActivity中的属性为:

android:screenOrientation="portrait"

让这个CaptureActivity显示为竖屏。下面的代码就是activity节点的代码。

<activity android:name="com.google.zxing.client.android.CaptureActivity"
            android:screenOrientation="portrait"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:theme="@style/CaptureTheme"
            android:windowSoftInputMode="stateAlwaysHidden">

2. 修改CameraManager中的代码

CameraManager.java文件中找到getFramingRectInPreview()这个方法,然后将原来的代码修改为:

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;

为了方便参考,下面把getFramingRectInPreview()这个方法的整个代码都贴出来:

  public synchronized Rect getFramingRectInPreview() {
    if (framingRectInPreview == null) {
      Rect framingRect = getFramingRect();
      if (framingRect == null) {
        return null;
      }
      Rect rect = new Rect(framingRect);
      Point cameraResolution = configManager.getCameraResolution();
      Point screenResolution = configManager.getScreenResolution();
      if (cameraResolution == null || screenResolution == null) {
        // Called early, before init even finished
        return null;
      }
//      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;
  }

3. 修改CameraConfigurationManager中的代码

找到CameraConfigurationManager.java文件中的setDesiredCameraParameters(OpenCamera camera, boolean safeMode)方法,然后添加一行代码:

// 这里设置成90度
    theCamera.setDisplayOrientation(90);

为了方便参考,这里贴出setDesiredCameraParameters(OpenCamera camera, boolean safeMode)方法的代码:

void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) {
    Camera theCamera = camera.getCamera();
    // 这里设置成90度
    theCamera.setDisplayOrientation(90);

    Camera.Parameters parameters = theCamera.getParameters();
    .....
    }
  }

4. 修改CameraConfigurationUtils中的代码

找到CameraConfigurationUtils.java中的findBestPreviewSizeValue()方法,然后在这个方法里面找到double screenAspectRatio = screenResolution.x / (double) screenResolution.y;这行代码,然后将这行代码注释掉,添加如下代码:

    // 添加横竖屏代码
    double screenAspectRatio;
    if (screenResolution.x < screenResolution.y) { // 竖屏
      screenAspectRatio = (double) screenResolution.y / (double) screenResolution.x;
    } else {
      screenAspectRatio = (double) screenResolution.x / (double) screenResolution.y;
    }

为了方便参考,将findBestPreviewSizeValue()方法中的结构展示出来:

  public static Point findBestPreviewSizeValue(Camera.Parameters parameters, Point screenResolution) {

    List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();

   ......

    // double screenAspectRatio = screenResolution.x / (double) screenResolution.y;

    // 添加横竖屏代码
    double screenAspectRatio;
    if (screenResolution.x < screenResolution.y) { // 竖屏
      screenAspectRatio = (double) screenResolution.y / (double) screenResolution.x;
    } else {
      screenAspectRatio = (double) screenResolution.x / (double) screenResolution.y;
    }

    ......

    Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
    Log.i(TAG, "No suitable preview sizes, using default: " + defaultSize);
    return defaultSize;
  }

5. 扫描结果

大功告成,编译运行,看看实际效果这么样吧。

可以看到基本上还是可以实现竖屏扫码的哦!继续加油!