使用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"
也完全不影响。具体原理并不清楚,大概是使用原生布局,可以转换为竖屏吧。