如何在竖屏模式下使用Zxing?

32

目前zxing库只支持横屏模式。我的应用需要在竖屏模式下使用。


2
以下是您可以使用zxing 2.1做的事情。https://dev59.com/I2Qo5IYBdhLWcg3wMs4L#16252917 - Roy Lee
1
从Zing 2.2.0开始,您可以设置方向属性,请参考此答案 - Anup
10个回答

40

这是纵向扫描的解决方案。

首先在您的应用级gradle文件中声明以下两行:

implementation 'com.journeyapps:zxing-android-embedded:3.0.1@aar'
implementation 'com.google.zxing:core:3.2.0'
在您的xml文件中定义一个按钮,在MainActivity.java文件的Onclick Listener 中编写以下代码。
IntentIntegrator integrator = new IntentIntegrator(this);
    integrator.setPrompt("Scan a barcode");
    integrator.setCameraId(0);  // Use a specific camera of the device
    integrator.setOrientationLocked(true);
    integrator.setBeepEnabled(true);
    integrator.setCaptureActivity(CaptureActivityPortrait.class);
    integrator.initiateScan();

在 onCreate() 方法之后,将以下代码写入您的 MainActivity Java 文件中

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null) {
    if(result.getContents() == null) {
        Log.d("MainActivity", "Cancelled scan");
        Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
    } else {
        Log.d("MainActivity", "Scanned");
        st_scanned_result = result.getContents();
        Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();

    }
  }

}

然后创建一个名为CaptureActivityPortrait的类,它继承自CaptureActivity。该类如下所示:

  package soAndSo(Your PackageName);

  import com.journeyapps.barcodescanner.CaptureActivity;

  public class CaptureActivityPortrait extends CaptureActivity {
  }

最重要的是像下面这样在清单文件中声明您的CaptureActivityPortrait

<activity android:name=".CaptureActivityPortrait"
        android:screenOrientation="sensorPortrait"
        android:stateNotNeeded="true"
        android:theme="@style/zxing_CaptureTheme"
        android:windowSoftInputMode="stateAlwaysHidden"></activity>

2
这应该是被接受的答案。你救了我的一天。谢谢,伙计。我从Google Vision切换到这个,但找不到如何将默认的横向方向更改为纵向的源代码。 - Simon Dorociak
在更新应用程序gradle为:compile 'com.google.zxing:core:3.2.1'并删除清单声明中的zxing主题后,它也适用于我。非常感谢! - Marcel Hofgesang
1
您,先生,是一位英雄。 - Fadi Obaji
1
工作得像冠军一样,谢谢! - Shailendra Madda
为什么非得这样呢? - undefined

23

我想在竖屏模式下使用条码阅读器。我在本讨论串中找到了解决方案,正如早先发布的评论所提到的那样。我考虑将此作为答案发布,以便于像我一样遇到相同问题的人更容易找到解决方案。

要在竖屏模式下使用扫描仪,您需要在AndroidManifest.xml中添加以下活动。

<activity
    android:name="com.journeyapps.barcodescanner.CaptureActivity"
    android:screenOrientation="portrait"
    tools:replace="screenOrientation" />

就是这样。

请查看链接获取更多详细信息。


3
非常肯定,复制粘贴解决了我的问题...谢谢 - Alp Altunel
1
太好了,很高兴能帮到你! :) - Reaz Murshed
1
完美解决方案 - ARN
这是针对哪个版本的zxing? - gumuruh
哈哈...很高兴听到这个!干杯! - Reaz Murshed

18

只需查看在纵向模式下使用Zxing的问题。


3
这个链接已经过时。 - Dusan Kovacevic
2
该链接指向“QR码不支持Unicode”问题... 请查看 https://github.com/journeyapps/zxing-android-embedded/issues/16 - kristyna
2
如果您正在使用3.x.x版本,请在AndroidManifest.xml中声明方向。更多信息请阅读https://github.com/journeyapps/zxing-android-embedded/blob/master/README.md#changing-the-orientation - kristyna

7
请按照以下方式进行检查(官方文档):

将此活动添加到清单文件中。

<activity
        android:name="com.journeyapps.barcodescanner.CaptureActivity"
        android:screenOrientation="fullSensor"
        tools:replace="screenOrientation" />

将积分器的OrientationLocked属性设置为false

IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setOrientationLocked(false);
integrator.initiateScan();

希望这可以帮到您。

6

setDisplayOrientation(int)不会影响传递给PreviewCallback.onPreviewFrame的字节数组的顺序。(有关详细信息,请参阅JavaDoc)

这意味着您需要在预览回调返回的数据上进行旋转,但这是yuv数据,您需要将其转换为rgb数据,然后对其进行旋转。虽然可能可以在竖屏模式下扫描条形码,但由于需要将数据从yuv转换为rgb并旋转rgb数据,因此处理时间会更长。

所以问题在于,如何从预览回调中获取竖屏模式下的yuv数据?当我们为相机参数设置setPreviewSize时,如果不支持预览大小,它将引发异常。这就是此问题的关键。如果相机驱动程序不支持横屏模式(高度>宽度)的预览大小,则无法在竖屏模式下获取yuv数据。其余的取决于您,您可以在竖屏模式下扫描条形码,但它会花费更长的时间,或者您可以更改屏幕方向为横屏以更快地获得结果。


4
只需在您的项目的 AndroidManifest.xml 文件中添加以下代码。
<activity android:name="com.journeyapps.barcodescanner.CaptureActivity"
        android:screenOrientation="sensorPortrait"
        android:stateNotNeeded="true"
        android:theme="@style/zxing_CaptureTheme"
        android:windowSoftInputMode="stateAlwaysHidden"
        tools:replace="android:screenOrientation" />

4
  1. In order to make screen work in portrait, set portrait orientation for the activity (e.g. in manifest) and then config the camera: Use camera.setDisplayOrientation(90) in CameraConfigurationManager.setDesiredCameraParameters(Camera camera). But be aware that:

    • setDisplayOrientation(int) requires Android 2.2
    • setDisplayOrientation(int) does not affect the order of byte array passed in PreviewCallback.onPreviewFrame. (Refer to JavaDoc for additional info)
  2. Because preview frames are always in "landscape", we need to rotate them. I used clockwise rotation offered by comment #11. Do not forget to swap width and height parameters after rotation. DecodeHandler.java, rotate data before buildLuminanceSource in decode(byte[] data, int width, int height)

    rotatedData = new byte[data.length];
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++)
            rotatedData[x * height + height - y - 1] = data[x + y * width];
    }
    int tmp = width; // Here we are swapping, that's the difference to #11
    width = height;
    height = tmp;
    
  3. I also modified CameraManager.java, getFramingRectInPreview(), as recommended by #c11:

    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;
    
  4. I did not modify getCameraResolution(). That's the second difference to #c11.

因此,我已经成功地将UPC和其他1D码扫描工作设置为纵向模式。
附注:您还可以调整FramingRect的大小(这是在扫描过程中屏幕上可见的矩形),FramingRectInPreview会自动调整。

1

1
@Drew 我认为这是个不错的答案...原帖想要一个支持纵向模式的ZXing版本,而这个答案恰好提供了此功能。它也帮助了我满足同样的需求。 - dodgy_coder
我相信它确实发生了。多年前,这个网站上的资源请求是可以接受的。但是现在的指南已经改变了。当新的答案只提供链接时,你经常会得到我给你的那些评论。 - Drew

0
将 android:screenOrientation="sensorPortrait" 添加到您的清单中。
<activity android:name=".CaptureActivity"
              android:screenOrientation="sensorPortrait"
              android:clearTaskOnLaunch="true"
              android:stateNotNeeded="true"
              android:theme="@style/CaptureTheme"
              android:windowSoftInputMode="stateAlwaysHidden"
tools:replace="android:theme"/>

0
将以下代码添加到AndroidManifest.xml文件中的application标签内,这样一定会起作用。
<activity
        android:name="com.journeyapps.barcodescanner.CaptureActivity"
        android:screenOrientation="fullSensor"
        tools:replace="screenOrientation" />

添加此内容可能会导致清单合并问题。您能否提供不引起清单合并问题的解决方案? - Prasanna Anbazhagan
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接