使用zxing进行QR code扫描,默认是横屏扫描。如何才能做到竖屏呢。
具体可以参考:http://blog.whomeninja.in/android-barcode-scanner-vertical-orientation-and-camera-flash/
方法是使用上面的方法,这里简单总结一下:
1.首先参考的网址的竖屏方法并没有用,而是下载了它的github源码(https://github.com/rajdeol/android-barcode-scanner-bulk-scan-with-flash),发现使用的是另外一个方法。
2.先放上代码:
package in.whomeninja.android_barcode_scanner_bulk_scan_with_flash; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.view.KeyEvent; import android.view.View; import com.journeyapps.barcodescanner.CaptureManager; import com.journeyapps.barcodescanner.DecoratedBarcodeView; /** * Created by RajinderPal on 1/29/2017. */ public class TorchOnCaptureActivity extends Activity { private CaptureManager capture; private DecoratedBarcodeView barcodeScannerView; private View turnflashOn, turnflashOff; private boolean cameraFlashOn = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); barcodeScannerView = initializeContent(); TorchEventListener torchEventListener = new TorchEventListener(this); barcodeScannerView.setTorchListener(torchEventListener); turnflashOn = findViewById(R.id.switch_flashlight_on); turnflashOff = findViewById(R.id.switch_flashlight_off); // turn the flash on if set via intent Intent scanIntent = getIntent(); if(scanIntent.hasExtra(appConstants.CAMERA_FLASH_ON)){ if(scanIntent.getBooleanExtra(appConstants.CAMERA_FLASH_ON,false)){ barcodeScannerView.setTorchOn(); updateView(); } } capture = new CaptureManager(this, barcodeScannerView); capture.initializeFromIntent(getIntent(), savedInstanceState); capture.decode(); } /** * Override to use a different layout. * * @return the DecoratedBarcodeView */ protected DecoratedBarcodeView initializeContent() { setContentView(R.layout.capture_flash); //setContentView(com.google.zxing.client.android.R.layout.zxing_capture); return (DecoratedBarcodeView)findViewById(com.google.zxing.client.android.R.id.zxing_barcode_scanner); } @Override protected void onResume() { super.onResume(); capture.onResume(); } @Override protected void onPause() { super.onPause(); capture.onPause(); } @Override protected void onDestroy() { super.onDestroy(); capture.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); capture.onSaveInstanceState(outState); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { capture.onRequestPermissionsResult(requestCode, permissions, grantResults); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event); } public void toggleFlash(View view){ if(cameraFlashOn){ barcodeScannerView.setTorchOff(); }else{ barcodeScannerView.setTorchOn(); } } public void updateView(){ if(cameraFlashOn){ turnflashOn.setVisibility(View.GONE); turnflashOff.setVisibility(View.VISIBLE); }else{ turnflashOn.setVisibility(View.VISIBLE); turnflashOff.setVisibility(View.GONE); } } class TorchEventListener implements DecoratedBarcodeView.TorchListener{ private TorchOnCaptureActivity activity; TorchEventListener(TorchOnCaptureActivity activity){ this.activity = activity; } @Override public void onTorchOn() { this.activity.cameraFlashOn = true; this.activity.updateView(); } @Override public void onTorchOff() { this.activity.cameraFlashOn = false; this.activity.updateView(); } } }
<?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/switch_flashlight_on" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/turn_on_flashlight" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:visibility="visible" android:onClick="toggleFlash"/> <Button android:id="@+id/switch_flashlight_off" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/turn_off_flashlight" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:visibility="gone" android:onClick="toggleFlash"/> <com.journeyapps.barcodescanner.DecoratedBarcodeView android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="50dp" android:layout_marginRight="50dp" android:layout_marginTop="150dp" android:layout_marginBottom="150dp" android:id="@+id/zxing_barcode_scanner" app:zxing_use_texture_view="false" app:zxing_preview_scaling_strategy="fitXY"/> </RelativeLayout>
3.竖屏分析:直接调用zxing的代码,默认只有全屏横屏的样式。经过多次试验,发现核心就是直接引用它的布局:
protected DecoratedBarcodeView initializeContent() { setContentView(R.layout.capture_flash); //setContentView(com.google.zxing.client.android.R.layout.zxing_capture); return (DecoratedBarcodeView)findViewById(com.google.zxing.client.android. R.id.zxing_barcode_scanner); }
这里findViewById用的实际是zxing自己的布局,同时xml布局文件里面,<com.journeyapps.barcodescanner.DecoratedBarcodeView>这个控件的id也要和zxing包的一样,即
android:id="@+id/zxing_barcode_scanner"
如此这般,就不会直接调用默认的横屏布局了,但是仅仅这样并不够,因为build app后发现不没有打开摄像头。这就需要下面这些关键语句:
private CaptureManager capture; private DecoratedBarcodeView barcodeScannerView; barcodeScannerView = initializeContent(); capture = new CaptureManager(this, barcodeScannerView); capture.initializeFromIntent(getIntent(), savedInstanceState); capture.decode(); @Override protected void onResume() { super.onResume(); capture.onResume(); } @Override protected void onPause() { super.onPause(); capture.onPause(); } @Override protected void onDestroy() { super.onDestroy(); capture.onDestroy(); }
这些都是初始化
CaptureManager、DecoratedBarcodeView
的语句,加上后就可以调用摄像头,正常使用了,而且是竖屏样式。
只需要以上操作,即使不添加
android:screenOrientation="fullSensor"
也完全不影响。具体原理并不清楚,大概是使用原生布局,可以转换为竖屏吧。