安卓二维码功能集成

安卓二维码功能集成

本次使用的第三方库为 https://github.com/journeyapps/zxing-android-embedded

这个库直接对zxing进行了封装抽取,用起来也比较方便。自定义界面实现也非常容易。以下看代码。

build.gradle下面复制粘贴以下内容
    repositories {
    jcenter()
}

dependencies {
    compile 'com.journeyapps:zxing-android-embedded:3.3.0@aar'
    compile 'com.google.zxing:core:3.2.1'
    compile 'com.android.support:appcompat-v7:23.1.0'   // Version 23+ is required
}

android {
    buildToolsVersion '23.0.2' // Older versions may give compile errors
}
/**
     * 跳转到扫描二维码页面
     */

    @Override
    public void jumpToScanCode() {
        iv_jump_to_scan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IntentIntegrator integrator = IntentIntegrator.forSupportFragment(ConnectWifiFragment.this).setCaptureActivity(CustomCaptureAvtivity.class);
                integrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES);
                integrator.setPrompt("开始扫描二维码");
                integrator.setCameraId(0);  // Use a specific camera of the device
                integrator.setBeepEnabled(false);
                integrator.setBarcodeImageEnabled(true);
                integrator.setOrientationLocked(false);
                integrator.initiateScan();

            }
        });
    }

这里我在fragment的一个按钮里面打开一个新的avtivity窗口扫描二维码,扫描二维码的窗口这里采用的是自定义的CustomCaptureAvtivity。如果你用这个库提供的扫描窗口,可以不加这个setCaptureActivity(CustomCaptureAvtivity.class)方法。因为我要自定义扫描框的形状大小这里自定义了一个CustomCaptureAvtivity。

 @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if(result != null) {
            if(result.getContents() == null) {
            } else {
                Intent intent = new Intent(getActivity(), QRCodeActivity.class);
                intent.putExtra(Constant.ScanFinishJumpToUrl,result.getContents());
                startActivity(intent);
            }

            // At this point we may or may not have a reference to the activity
          //  displayToast();
        }
    }

在onActivityResult里面可以接受到扫描回来的结果,这里我收到扫描结果后跳转了一个activity用来打开二维码扫描结果返回的网站.如果你用默认的扫描界面到这里你已经成功了.

public class CustomCaptureAvtivity extends Activity implements DecoratedBarcodeView.TorchListener ,View.OnClickListener {

    private CaptureManager capture;
    private DecoratedBarcodeView barcodeScannerView;
    private Button switchFlashlightButton;
    private ImageView iv_back;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_capture_avtivity);

        barcodeScannerView = (DecoratedBarcodeView)findViewById(R.id.zxing_barcode_scanner);
        iv_back = (ImageView)findViewById(R.id.iv_scan_back);
        barcodeScannerView.setTorchListener(this);
        iv_back.setOnClickListener(this);
        // if the device does not have flashlight in its camera,
        // then remove the switch flashlight button...
        if (!hasFlash()) {
            switchFlashlightButton.setVisibility(View.GONE);
        }

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

    public void switchFlashlight(View view) {

    }

    @Override
    public void onTorchOn() {
       // switchFlashlightButton.setText(R.string.turn_off_flashlight);
    }

    @Override
    public void onTorchOff() {
      //  switchFlashlightButton.setText(R.string.turn_on_flashlight);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.iv_scan_back:
                CustomCaptureAvtivity.this.finish();
                break;
        }

        }

}

这个是demo里面的自定义扫描界面的activity,原封不动的抄过来改了一些东西。主要是初始化了扫描界面不多说下面看关键的扫描界面的类是:

public class CustomViewfinderView extends ViewfinderView {
    public int laserLinePosition=0;
    public float[] position=new float[]{0f,0.5f,1f};
    public int[] colors=new int[]{0x00ffffff,0xffffffff,0x00ffffff};
    public  LinearGradient linearGradient ;
    public CustomViewfinderView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    /**
     * 重写draw方法绘制自己的扫描框
     * @param canvas
     */
    @Override
    public void onDraw(Canvas canvas) {
        refreshSizes();
        if (framingRect == null || previewFramingRect == null) {
            return;
        }

        Rect frame = framingRect;
        Rect previewFrame = previewFramingRect;

        int width = canvas.getWidth();
        int height = canvas.getHeight();
        //绘制4个角

        paint.setColor(0xFFFFFFFF);
        canvas.drawRect(frame.left, frame.top, frame.left+70, frame.top+10, paint);
        canvas.drawRect(frame.left, frame.top, frame.left + 10, frame.top + 70, paint);

        canvas.drawRect(frame.right-70, frame.top, frame.right, frame.top+10, paint);
        canvas.drawRect(frame.right-10, frame.top, frame.right, frame.top+70, paint);

        canvas.drawRect(frame.left, frame.bottom-10, frame.left+70, frame.bottom, paint);
        canvas.drawRect(frame.left, frame.bottom-70, frame.left+10, frame.bottom, paint);

        canvas.drawRect(frame.right-70, frame.bottom-10, frame.right, frame.bottom, paint);
        canvas.drawRect(frame.right-10, frame.bottom-70, frame.right, frame.bottom, paint);
        // Draw the exterior (i.e. outside the framing rect) darkened
        paint.setColor(resultBitmap != null ? resultColor : maskColor);
        canvas.drawRect(0, 0, width, frame.top, paint);
        canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
        canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
        canvas.drawRect(0, frame.bottom + 1, width, height, paint);

        if (resultBitmap != null) {
            // Draw the opaque result bitmap over the scanning rectangle
            paint.setAlpha(CURRENT_POINT_OPACITY);
            canvas.drawBitmap(resultBitmap, null, frame, paint);
        } else {


          //  paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
          //  scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
            int middle = frame.height() / 2 + frame.top;
            laserLinePosition=laserLinePosition+5;
            if(laserLinePosition>frame.height())
            {
                laserLinePosition=0;
            }
            linearGradient= new LinearGradient(frame.left + 1, frame.top+laserLinePosition , frame.right -1 , frame.top +10+laserLinePosition, colors, position, Shader.TileMode.CLAMP);
            // Draw a red "laser scanner" line through the middle to show decoding is active

            //  paint.setColor(laserColor);
            paint.setShader(linearGradient);
            //绘制扫描线
            canvas.drawRect(frame.left + 1, frame.top+laserLinePosition , frame.right -1 , frame.top +10+laserLinePosition, paint);
            paint.setShader(null);
            float scaleX = frame.width() / (float) previewFrame.width();
            float scaleY = frame.height() / (float) previewFrame.height();

            List<ResultPoint> currentPossible = possibleResultPoints;
            List<ResultPoint> currentLast = lastPossibleResultPoints;
            int frameLeft = frame.left;
            int frameTop = frame.top;
            if (currentPossible.isEmpty()) {
                lastPossibleResultPoints = null;
            } else {
                possibleResultPoints = new ArrayList<>(5);
                lastPossibleResultPoints = currentPossible;
                paint.setAlpha(CURRENT_POINT_OPACITY);
                paint.setColor(resultPointColor);
                for (ResultPoint point : currentPossible) {
                    canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
                            frameTop + (int) (point.getY() * scaleY),
                            POINT_SIZE, paint);
                }
            }
            if (currentLast != null) {
                paint.setAlpha(CURRENT_POINT_OPACITY / 2);
                paint.setColor(resultPointColor);
                float radius = POINT_SIZE / 2.0f;
                for (ResultPoint point : currentLast) {
                    canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
                            frameTop + (int) (point.getY() * scaleY),
                            radius, paint);
                }
            }

            postInvalidateDelayed(16,
                    frame.left ,
                    frame.top ,
                    frame.right ,
                    frame.bottom);
           // postInvalidate();

        }
    }
}

里面的这个ViewfinderView 类是用来扫描二维码的,决定了二维码扫描界面整个扫描框的外形我这里不需要改动他的其他逻辑,只需要重绘扫描界面,这里我选择自定义一个类去继承ViewfinderView ,重写他的ondraw方法绘制自己的扫描框。当然不要忘了在布局文件中修改一下布局文件内容

//CustomCaptureAvtivity 的布局
<FrameLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="example.zxing.CustomScannerActivity">

    <com.journeyapps.barcodescanner.DecoratedBarcodeView
        android:id="@+id/zxing_barcode_scanner"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:zxing_scanner_layout="@layout/custom_barcode_scanner">
    </com.journeyapps.barcodescanner.DecoratedBarcodeView>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:padding="10dp"
        android:background="#cc333333"
        >
        <ImageView
            android:id="@+id/iv_scan_back"
            android:layout_centerVertical="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/home_btn_back"
            />
    </RelativeLayout>

</FrameLayout>
//CustomCaptureAvtivity 的布局引用的一个布局,这里的
<com.e7wifi.colourmedia.view.CustomViewfinderView>为自定义的CustomViewfinderView

<?xml version="1.0" encoding="utf-8"?>
<merge 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">

    <com.journeyapps.barcodescanner.BarcodeView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/zxing_barcode_surface"
        app:zxing_framing_rect_width="250dp"
        app:zxing_framing_rect_height="250dp">
    </com.journeyapps.barcodescanner.BarcodeView>

    <com.e7wifi.colourmedia.view.CustomViewfinderView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/zxing_viewfinder_view"
        app:zxing_possible_result_points="@color/zxing_custom_possible_result_points"
        app:zxing_result_view="@color/zxing_custom_result_view"
        app:zxing_viewfinder_laser="#FFFFFF"
        app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>

    <TextView
        android:id="@+id/zxing_status_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:background="@color/zxing_transparent"
        android:text="@string/zxing_msg_default_status"
        android:textColor="@color/zxing_status_text"/>

</merge>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值