如何在Weex App中集成QR阅读器?

时间:2017-07-18 07:12:50

标签: qr-code weex

React.Native有像react-native-qrcode-scanner这样的插件。 我怎么能在Weex上做到这一点?

1 个答案:

答案 0 :(得分:0)

这是一个名为EMAS的解决方案。像weex-market一样,有很多组件和模块。其中一个是符合您要求的扫描组件。

但门户网站website现在只有中文版。

这是一个使用ZXing做qrcode的Android演示。复制此文件并注册为scan组件。看看这个Demo

public class WXQRCodeScannerComponent extends WXComponent<ZXingScannerView> implements ZXingScannerView.ResultHandler{

    private static final String VF_WIDTH = "vfWidth";
    private static final String VF_HEIGHT = "vfHeight";
    private static final String VF_TOP_MARGIN = "vfTopMargin";
    private static final String AUTO_STOP = "autoStop";

    private static final String ON_SCAN = "scan";

    private static final String TAG = "scan";
    private boolean isAutoStop = false;

    private boolean hasScanned = false;

    private Handler mHandler = new Handler(Looper.getMainLooper());

    private static final int CAMERA_PERMISSION_REQUEST_CODE = 0x1001;

    private OnRequestPermissionCallback mPermissionCallback = new OnRequestPermissionCallback() {
        @Override
        public void onPermissionGranted() {
            ZXingScannerView hostView = getHostView();
            if(hostView != null) {
                hostView.startCamera();
            }
        }

        @Override
        public void onPermissionDenied() {
            // nope
        }
    };


    public WXQRCodeScannerComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {
        super(instance, dom, parent);
    }

    public WXQRCodeScannerComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, int type) {
        super(instance, dom, parent, type);
    }

    @Override
    protected ZXingScannerView initComponentHostView(@NonNull Context context) {
        requestPermissionIfNeeded();
        ZXingScannerView qrCodeView = new ZXingScannerView(context);
        qrCodeView.setSquareViewFinder(true);
        qrCodeView.setResultHandler(this); // Register ourselves as a handler for scan results.
        return qrCodeView;
    }

    private void requestPermissionIfNeeded() {
        Context c = getContext();
        if(c != null && c instanceof Activity) {
            if(ContextCompat.checkSelfPermission(c, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) c, Manifest.permission.CAMERA)) {
                    Toast.makeText(c, "请授予相机权限以用于扫码", Toast.LENGTH_LONG).show();
                }
                LocalBroadcastManager.getInstance(c)
                        .registerReceiver(new InnerReceiver(mPermissionCallback), new IntentFilter(WXModule.ACTION_REQUEST_PERMISSIONS_RESULT));

                ActivityCompat.requestPermissions((Activity) c,
                        new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
            } else {
                //Nope
            }

        }
    }


    static class InnerReceiver extends BroadcastReceiver{
        private OnRequestPermissionCallback mCallback;
        InnerReceiver(OnRequestPermissionCallback callback) {
            this.mCallback = callback;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            int code = intent.getIntExtra(WXModule.REQUEST_CODE, 0);
            int[] grantResults = intent.getIntArrayExtra(WXModule.GRANT_RESULTS);
            String[] permissions = intent.getStringArrayExtra(WXModule.PERMISSIONS);
            if(code == CAMERA_PERMISSION_REQUEST_CODE) {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 权限申请成功
                    if(mCallback != null) {
                        mCallback.onPermissionGranted();
                    }
                } else {
                    Toast.makeText(context, "相机权限申请失败!将无法使用扫码功能!", Toast.LENGTH_SHORT).show();
                    if(mCallback != null) {
                        mCallback.onPermissionDenied();
                    }
                }
            }
            LocalBroadcastManager.getInstance(context).unregisterReceiver(this);
        }
    }

    interface OnRequestPermissionCallback {
        void onPermissionGranted();
        void onPermissionDenied();
    }

    @Override
    protected boolean setProperty(String key, Object param) {
        switch (key) {
            case VF_WIDTH:
                Float width = WXUtils.getFloat(param,null);
                if(width != null) {
                    setVfWidth(width);
                }
                return true;
            case VF_HEIGHT:
                Float height = WXUtils.getFloat(param,null);
                if(height != null) {
                    setVfHeight(height);
                }
                return true;
            case VF_TOP_MARGIN:
                Float topMargin = WXUtils.getFloat(param,null);
                if(topMargin != null) {
                    setVfTopMargin(topMargin);
                }
                return true;
            case AUTO_STOP:
                Boolean autoStop = WXUtils.getBoolean(param, false);
                if(autoStop != null) {
                    setAutoStop(autoStop);
                }
                return true;
        }
        return super.setProperty(key, param);
    }


    @Override
    protected void onHostViewInitialized(ZXingScannerView host) {
        super.onHostViewInitialized(host);
        ZXingScannerView hostView = getHostView();
        if(hostView != null) {
            hostView.startCamera();
        }

    }

    @WXComponentProp(name = VF_WIDTH)
    public void setVfWidth(float width) {
        float finalWidth = WXViewUtils.getRealSubPxByWidth(width,getInstance().getInstanceViewPortWidth());
        if(getHostView() != null) {
//            ScanBoxView scanBoxView = getHostView().getScanBox();
//            if(scanBoxView != null) {
//                scanBoxView.setRectWidth((int) finalWidth);
//            }
        }
    }

    @WXComponentProp(name = VF_HEIGHT)
    public void setVfHeight(float height) {
        float finalHeight = WXViewUtils.getRealSubPxByWidth(height,getInstance().getInstanceViewPortWidth());
        if(getHostView() != null) {
//            ScanBoxView scanBoxView = getHostView().getScanBox();
//            if(scanBoxView != null) {
//                scanBoxView.setRectHeight((int) finalHeight);
//            }
        }
    }

    @WXComponentProp(name = VF_TOP_MARGIN)
    public void setVfTopMargin(float topMargin) {
        float finalTopMargin = WXViewUtils.getRealSubPxByWidth(topMargin,getInstance().getInstanceViewPortWidth());
        if(getHostView() != null) {
//            ScanBoxView scanBoxView = getHostView().getScanBox();
//            if(scanBoxView != null) {
//                scanBoxView.setTopOffset((int) finalTopMargin);
//            }
        }
    }

    @WXComponentProp(name = AUTO_STOP)
    public void setAutoStop(boolean autoStop) {
        this.isAutoStop = autoStop;
    }

    @Override
    public void onActivityResume() {
        super.onActivityResume();
        ZXingScannerView hostView = getHostView();
        if(hostView != null) {
            hostView.startCamera();
        }
    }

    @Override
    public void onActivityPause() {
        super.onActivityPause();
        ZXingScannerView hostView = getHostView();
        if(hostView != null) {
            hostView.stopCamera();           // Stop camera on pause
        }
    }

    @Override
    public void onActivityDestroy() {
        if(mHandler != null) {
            ZXingScannerView hostView = getHostView();
            if(hostView != null) {
                hostView.stopCamera();
            }
            mHandler.removeCallbacksAndMessages(null);
        }
    }

    @Override
    public void handleResult(Result result) {
        if(isAutoStop && hasScanned) {
            resumeCameraPreviewDelayed();
            return;
        }

        fireEventByResult(result);
        resumeCameraPreviewDelayed();
        hasScanned = true;
    }

    private void fireEventByResult(Result result) {
        if(result == null || TextUtils.isEmpty(result.getText())) {
            Map<String,Object> callback = new HashMap<>(4);
            callback.put("result","failed");
            fireEvent(ON_SCAN,callback);
            if(WXEnvironment.isApkDebugable()) {
                WXLogUtils.d(TAG, "scan failed");
            }
        } else {
            Map<String,String> data = new HashMap<>(4);
            data.put("timestamp", System.currentTimeMillis()+"");
            data.put("code", result.getText());

            Map<String,Object> callback = new HashMap<>(4);
            callback.put("result","success");
            callback.put("data", data);
            fireEvent(ON_SCAN,callback);
            if(WXEnvironment.isApkDebugable()) {
                WXLogUtils.d(TAG, "scan success: " + result.getText());
            }
        }
    }

    private void resumeCameraPreviewDelayed() {
        if(mHandler == null) {
            return;
        }
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                ZXingScannerView hostView = getHostView();
                if(hostView != null) {
                    hostView.resumeCameraPreview(WXQRCodeScannerComponent.this);
                }
            }
        }, 1000);
    }
}