使用 ZXing 库中的 IntentIntegrator 时,我可以通过 Intent 向条码扫描器添加闪光按钮吗? [英] While using the IntentIntegrator from the ZXing library, can I add a flash button to the barcode scanner via the Intent?

查看:18

我正在通过 Intent 使用 ZXing 库Android 应用程序的端口.我在 Gradle 依赖项中添加了以下两行以使用 android-integration 代码而无需修改:

编译'com.journeyapps:zxing-android-embedded:3.2.0@aar'编译'com.google.zxing:core:3.2.1'

我正在使用 IntentIntegrator 在我的活动中扫描 onCreate() 中的条形码,如下所示:

integrator = new IntentIntegrator(this);integrator.setOrientationLocked(false);integrator.setPrompt(getString(R.string.scanner_text));//设置扫描仪的文本integrator.setCameraId(0);//使用设备的特定摄像头integrator.setBeepEnabled(true);//在扫描仪中启用蜂鸣声integrator.setBarcodeImageEnabled(false);//不从相机获取图像integrator.initiateScan();

一切正常,我得到了正确的扫描结果,但我想在扫描仪的右下角有一个像这样的闪光按钮:

在此处输入图片描述

我已经可以使用音量上下键控制闪光灯,因为我覆盖了 CaptureActivity.条码扫描器中是否已经有一个像上面那样的闪光按钮,可以在自动、开和关模式之间切换?如果有,我可以使用IntentIntegrator的addExtra()方法来激活它吗?或者实现这一点的唯一方法是根据我的需要修改整个代码?

解决方案

我忽略了 此页面关于嵌入 BarcodeView这些示例活动 展示了如何根据您的需要自定义条码扫描仪.帮助我的示例活动是 CustomScannerActivity.

IntentIntegrator 类,用于本机实现 flash 按钮.相反,我应该为 Barcode Scanner 制作自定义布局,在自定义活动中使用它并从 IntentIntegrator 调用此活动.

我有两个活动.一种是ScannerActivity,另一种是CallingActivity.一个让我困惑了一段时间的错误是我在 ScannerActivity 的 onCreate() 方法中创建了一个 IntentIntegrator 的实例.它应该在 CallingActivity 中.

在给出的示例中,使用了 Button 并且 Button 的文本根据 flash 进行更改.我创建了一个名为 activity_custom_scanner 的新 Android 布局,其中我将 Button 替换为 ToggleButton,并使用按钮图像来获得我想要的 Flash 开/关按钮.

所以我的 ScannerActivity 看起来像这样:

 公共类 CustomScannerActivity 扩展 Activity 实现CompoundBarcodeView.TorchListener {私有静态最终 int BarCodeScannerViewControllerUserCanceledErrorCode = 99991;private static final String TAG = CustomScannerActivity.class.getSimpleName();私有 CaptureManager 捕获;私人 CompoundBarcodeView 条形码扫描仪视图;私人 ToggleButton 开关手电筒按钮;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_custom_scanner);barcodeScannerView = (CompoundBarcodeView)findViewById(R.id.zxing_barcode_scanner);barcodeScannerView.setTorchListener(this);switchFlashlightButton = (ToggleButton)findViewById(R.id.switch_flashlight);switchFlashlightButton.setText(null);switchFlashlightButton.setTextOn(null);switchFlashlightButton.setTextOff(null);//如果设备的相机中没有手电筒,//然后移除开关手电筒按钮...如果 (!hasFlash()) {switchFlashlightButton.setVisibility(View.GONE);}switchFlashlightButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {@覆盖public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {//在这里保存状态如果(已检查){条形码扫描仪View.setTorchOn();} 别的 {条形码扫描仪View.setTorchOff();}}});capture = new CaptureManager(this,barcodeScannerView);capture.initializeFromIntent(getIntent(), savedInstanceState);捕获.解码();}@覆盖protected void onResume() {super.onResume();捕获.onResume();}@覆盖受保护的无效 onPause() {super.onPause();捕获.onPause();}@覆盖受保护的无效 onDestroy() {super.onDestroy();捕获.onDestroy();}@覆盖protected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);capture.onSaveInstanceState(outState);}@覆盖公共布尔 onKeyDown(int keyCode, KeyEvent 事件) {返回barcodeScannerView.onKeyDown(keyCode, event) ||super.onKeyDown(keyCode, 事件);}/*** 检查设备的相机是否有手电筒.* @return 如果有手电筒为真,否则为假.*/私有布尔 hasFlash() {返回 getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);}@覆盖公共无效 onTorchOn() {//必要的覆盖..}@覆盖公共无效 onTorchOff() {//必要的覆盖..}}

CallingActivity 看起来像这样:

public class CallingActivity extends Activity {private static final String TAG = CallingActivity.class.getSimpleName();私有静态最终 int BarCodeScannerViewControllerUserCanceledErrorCode = 99991;字符串 uuid;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);uuid = getIntent().getStringExtra("uuid");new IntentIntegrator(this).setOrientationLocked(false).setCaptureActivity(CustomScannerActivity.class).initiateScan();}public void onActivityResult(int requestCode, int resultCode, Intent intent) {IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);如果(resultCode == RESULT_OK){如果(扫描结果!= null){//处理扫描结果Log.i(TAG, "来自条码扫描仪的文本:" + scanResult.getContents());getIntent().putExtra("data", scanResult.getContents());getIntent().putExtra("uuid", uuid);}}否则如果(resultCode == RESULT_CANCELED){getIntent().putExtra("error", "用户取消");getIntent().putExtra("error_code", BarCodeScannerViewControllerUserCanceledErrorCode);}别的{getIntent().putExtra("error", getString(R.string.scanner_error));getIntent().putExtra("error_code", BarCodeScannerViewControllerUserCanceledErrorCode);}setResult(resultCode, this.getIntent());this.finish();}}

我不确定这是否是完美的方式,但我就是这样做的.

希望对大家有所帮助!

  • 原文

I am scanning barcodes and QR codes from an Android app via Intent using the ZXing Library and its port of the Android Application. I added the following two lines in my Gradle dependencies to use the android-integration code without modification:

compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
compile 'com.google.zxing:core:3.2.1'

And I am using IntentIntegrator in my Activity to scan a barcode in the onCreate() like this:

integrator = new IntentIntegrator(this);
integrator.setOrientationLocked(false);
integrator.setPrompt(getString(R.string.scanner_text)); // Set the text of the scanner
integrator.setCameraId(0);  // Use a specific camera of the device
integrator.setBeepEnabled(true); // Enable beep in the scanner
integrator.setBarcodeImageEnabled(false); // Do not fetch image from the camera
integrator.initiateScan();

Everything works and I get correct scanned result, but I want a flash button in the lower right corner of the scanner like this:

enter image description here

I can already control the flash using the volume up and down keys because I override the CaptureActivity. Is a flash button like the one above already there in the barcode scanner which can switch between AUTO, ON and OFF mode? If there is, can I use the addExtra() method of the IntentIntegrator to activate it? Or is the only way to implement this would be to modify the entire code according to my needs?

解决方案

I had overlooked this page on Embedding BarcodeView and these sample activities which show how to customise the Barcode Scanner according to your needs. The example activity that helped me was CustomScannerActivity.

There isn't a option in the IntentIntegrator class to implement a flash button natively. Instead I should make a custom layout for the Barcode Scanner, use it in a custom activity and call this activity from the IntentIntegrator.

I have two activities. One is the ScannerActivity and other one is the CallingActivity. A mistake that confused me for a while was that I created an instance of IntentIntegrator in the onCreate() method of ScannerActivity. It should be in the CallingActivity.

In the example given a Button is used and the text of the Button is changed according to the flash. I created a new Android Layout called activity_custom_scanner where I replaced the Button with a ToggleButton and used images for the button instead to get my desired Flash On/Off Button.

So my ScannerActivity looks like this:

public class CustomScannerActivity extends Activity implements
        CompoundBarcodeView.TorchListener {

    private static final int BarCodeScannerViewControllerUserCanceledErrorCode = 99991;

    private static final String TAG = CustomScannerActivity.class.getSimpleName();

    private CaptureManager capture;
    private CompoundBarcodeView barcodeScannerView;
    private ToggleButton switchFlashlightButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_scanner);

        barcodeScannerView = (CompoundBarcodeView)findViewById(R.id.zxing_barcode_scanner);
        barcodeScannerView.setTorchListener(this);

        switchFlashlightButton = (ToggleButton)findViewById(R.id.switch_flashlight);

        switchFlashlightButton.setText(null);
        switchFlashlightButton.setTextOn(null);
        switchFlashlightButton.setTextOff(null);

        // if the device does not have flashlight in its camera,
        // then remove the switch flashlight button...
        if (!hasFlash()) {
            switchFlashlightButton.setVisibility(View.GONE);
        }

        switchFlashlightButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // Save the state here
                if (isChecked) {
                    barcodeScannerView.setTorchOn();
                } else {
                    barcodeScannerView.setTorchOff();
                }
            }
        });

        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();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        capture.onSaveInstanceState(outState);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
    }

    /**
     * Check if the device's camera has a Flashlight.
     * @return true if there is Flashlight, otherwise false.
     */
    private boolean hasFlash() {
        return getApplicationContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    }

    @Override
    public void onTorchOn() {
        // necessary override..
    }


    @Override
    public void onTorchOff() {
        // necessary override..
    }

}

And the CallingActivity looks like this:

public class CallingActivity extends Activity {

    private static final String TAG = CallingActivity.class.getSimpleName();

    private static final int BarCodeScannerViewControllerUserCanceledErrorCode = 99991;

    String uuid;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        uuid = getIntent().getStringExtra("uuid");
        new IntentIntegrator(this).setOrientationLocked(false).setCaptureActivity(CustomScannerActivity.class).initiateScan();
    }



    public void onActivityResult(int requestCode, int resultCode, Intent intent) {

        IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);

        if (resultCode == RESULT_OK) {
            if (scanResult != null) {

                // handle scan result
                Log.i(TAG, "Text from Barcode Scanner: " + scanResult.getContents());
                getIntent().putExtra("data", scanResult.getContents());
                getIntent().putExtra("uuid", uuid);
            }
        }
        else if (resultCode == RESULT_CANCELED) {
            getIntent().putExtra("error", "User canceled");
            getIntent().putExtra("error_code", BarCodeScannerViewControllerUserCanceledErrorCode);
        }
        else
        {
            getIntent().putExtra("error", getString(R.string.scanner_error));
            getIntent().putExtra("error_code", BarCodeScannerViewControllerUserCanceledErrorCode);
        }

        setResult(resultCode, this.getIntent());

        this.finish();
    }

}

I am not sure if it's the perfect way, but that's how I did it.

Hope it helps someone!