目前zxing库只支持横屏模式。我的应用需要在竖屏模式下使用。
目前zxing库只支持横屏模式。我的应用需要在竖屏模式下使用。
这是纵向扫描的解决方案。
首先在您的应用级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>
我想在竖屏模式下使用条码阅读器。我在本讨论串中找到了解决方案,正如早先发布的评论所提到的那样。我考虑将此作为答案发布,以便于像我一样遇到相同问题的人更容易找到解决方案。
要在竖屏模式下使用扫描仪,您需要在AndroidManifest.xml
中添加以下活动。
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="portrait"
tools:replace="screenOrientation" />
就是这样。
请查看链接获取更多详细信息。
只需查看在纵向模式下使用Zxing的问题。
将此活动添加到清单文件中。
<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();
setDisplayOrientation(int)
不会影响传递给PreviewCallback.onPreviewFrame
的字节数组的顺序。(有关详细信息,请参阅JavaDoc)
这意味着您需要在预览回调返回的数据上进行旋转,但这是yuv数据,您需要将其转换为rgb数据,然后对其进行旋转。虽然可能可以在竖屏模式下扫描条形码,但由于需要将数据从yuv转换为rgb并旋转rgb数据,因此处理时间会更长。
所以问题在于,如何从预览回调中获取竖屏模式下的yuv数据?当我们为相机参数设置setPreviewSize时,如果不支持预览大小,它将引发异常。这就是此问题的关键。如果相机驱动程序不支持横屏模式(高度>宽度)的预览大小,则无法在竖屏模式下获取yuv数据。其余的取决于您,您可以在竖屏模式下扫描条形码,但它会花费更长的时间,或者您可以更改屏幕方向为横屏以更快地获得结果。
<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" />
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:
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;
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;
I did not modify getCameraResolution(). That's the second difference to #c11.
<activity android:name=".CaptureActivity"
android:screenOrientation="sensorPortrait"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:theme="@style/CaptureTheme"
android:windowSoftInputMode="stateAlwaysHidden"
tools:replace="android:theme"/>
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="fullSensor"
tools:replace="screenOrientation" />