欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

集成华为HMS Scankit 扫码SDK实现自定义扫码页面,扫一扫二维码

程序员文章站 2022-11-03 08:22:18
1:应用场景: Android开发实现扫一扫功能,比ZXing效果好,集成简单。2:官方Demo: 官网Demo体验地址:华为Demo,示例代码下来就可以运行。3:开发: 1:在项目级gradle里添加华为maven仓// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript { ......

1:应用场景:

        Android开发实现扫一扫功能,比ZXing效果好,集成简单。

2:官方Demo:

       官网Demo体验地址:华为Demo,示例代码下来就可以运行。

3:开发:

    1:在项目级gradle里添加华为maven仓

集成华为HMS Scankit 扫码SDK实现自定义扫码页面,扫一扫二维码

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
        maven {url 'http://developer.huawei.com/repo/'}
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.3'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'http://developer.huawei.com/repo/'}
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

2:在应用级的build.gradle里面加上SDK依赖

集成华为HMS Scankit 扫码SDK实现自定义扫码页面,扫一扫二维码

// 华为二维码扫描
implementation 'com.huawei.hms:scan:1.1.3.301'

3:Manifest申请静态权限和扫码页面:

<!--相机权限-->
<uses-permission android:name="android.permission.CAMERA" />
<!--读文件权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--使用特性-->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<!--震动权限-->
<uses-permission android:name="android.permission.VIBRATE" />
<!--        自定义扫码界面-->
        <activity
            android:screenOrientation="portrait"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar"
            android:windowSoftInputMode="adjustPan|stateHidden"
            android:name=".ScanQrActivity"/>

4:在启动扫码Activity的地方添加动态权限申请:

public class MainActivity extends AppCompatActivity {
    TextView textView;
    public static int REQUEST_CODE = 0x11;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.bt);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //申请权限
                ActivityCompat.requestPermissions(
                        MainActivity.this,
                        new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_CODE);
            }
        });
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (permissions == null || grantResults == null) {
            return;
        }
        if (grantResults.length < 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (requestCode == REQUEST_CODE) {
            //权限申请成功,跳转到自定义扫码页面
            Intent intent = new Intent(MainActivity.this, ScanQrActivity.class);

            startActivityForResult(intent, REQUEST_CODE);
        }
    }

//     处理扫码结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            //处理扫描结果 
            if (null != data) {
                Bundle bundle = data.getExtras();
                if (bundle == null) {
                    return;
                }
                if (bundle.getInt("result_type") == 1) {
                    String result = bundle.getString("result_string");
                    Log.e("扫描结果" , "result:"+result);

                } else if (bundle.getInt("result_type") == 2) {
                    Log.e("扫描结果" , "扫描失败:");
                }
            }
        }
    }
}

5:自定义扫码页面

/**
 *   二维码扫描
 */
public class ScanQrActivity extends AppCompatActivity {


    private RemoteView remoteView;
    int mSceenWidth;
    int mSceenHeight;
    View line;

    FrameLayout frameLayout;

    ImageView flushBtn;
    /**
     *   手电筒图片
     */
    private int[] img = {R.mipmap.flashlight_on, R.mipmap.flashlight_off};
    final int SCAN_FRAME_SIZE = 340;
    private TranslateAnimation animation;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_scanqr);
        line = findViewById(R.id.scan_qr_line);
        frameLayout = findViewById(R.id.scan_qr_rim);
        flushBtn = findViewById(R.id.flush_btn);


        //1.设置扫码识别区域,您可以按照需求调整参数
        DisplayMetrics dm = getResources().getDisplayMetrics();
        float density = dm.density;
        //2.获取屏幕尺寸
        mSceenWidth = getResources().getDisplayMetrics().widthPixels;
        mSceenHeight = getResources().getDisplayMetrics().heightPixels;

        int scanFrameSize = (int) (SCAN_FRAME_SIZE * density);

        //3.声明 viewfinder'的 矩形,在布局中间
        //设置扫描区域(可选,矩形可以为空,如果不配置,默认是中心的布局)
        Rect rect = new Rect();
        rect.left = mSceenWidth / 2 - scanFrameSize / 2;
        rect.right = mSceenWidth / 2 + scanFrameSize / 2;
        rect.top = mSceenHeight / 2 - scanFrameSize / 2;
        rect.bottom = mSceenHeight / 2 + scanFrameSize / 2;


        //初始化RemoteView,并通过如下方法设置参数:
        // setContext()(必选)传入context、setBoundingBox()设置扫描区域、
        // setFormat()设置识别码制式,设置完毕调用build()方法完成创建
        remoteView = new RemoteView.Builder().setContext(this).setBoundingBox(rect).setFormat(HmsScan.ALL_SCAN_TYPE).build();
        //将自定义view加载到activity
        remoteView.onCreate(savedInstanceState);

        remoteView.setOnLightVisibleCallback(new OnLightVisibleCallBack() {
            @Override
            public void onVisibleChanged(boolean visible) {
                if(visible){
                    flushBtn.setVisibility(View.VISIBLE);
                }
            }
        });

        remoteView.setOnResultCallback(new OnResultCallback() {
            @Override
            public void onResult(HmsScan[] result) {
                //获取到扫码结果HmsScan,判断结果是否有效
                if (result != null && result.length > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) {
                    //成功
                    setVibrator();
                    Intent resultIntent = new Intent();
                    Bundle bundle = new Bundle();
                    bundle.putInt("result_type",1);
                    bundle.putString("result_string", result[0].originalValue);
                    resultIntent.putExtras(bundle);
                    ScanQrActivity.this.setResult(RESULT_OK, resultIntent);
                    ScanQrActivity.this.finish();

                } else {
                    //失败
                    setVibrator();
                    Intent resultIntent = new Intent();
                    Bundle bundle = new Bundle();
                    bundle.putInt("result_type", 2);
                    bundle.putString("result_string", "");
                    resultIntent.putExtras(bundle);
                    ScanQrActivity.this.setResult(RESULT_OK, resultIntent);
                    ScanQrActivity.this.finish();


                }
            }
        });
        remoteView.onCreate(savedInstanceState);
        //添加 remoteView 到Framelayout布局中
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        //绑定相机预览布局

        frameLayout.addView(remoteView, params);

        setFlashOperation();
    }
    /**
     *  震动
     */
    private void setVibrator() {

        Vibrator vibrator = (Vibrator)this.getSystemService(this.VIBRATOR_SERVICE);
        vibrator.vibrate(300);
    }

    /**
     *  开启闪光灯
     */
    private void setFlashOperation() {
        flushBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (remoteView.getLightStatus()) {
                    remoteView.switchLight();
                    flushBtn.setImageResource(img[1]);
                } else {
                    remoteView.switchLight();
                    flushBtn.setImageResource(img[0]);
                }
            }
        });
    }
    @Override
    protected void onResume() {

        super.onResume();

        if (remoteView!= null){

            remoteView.onResume();
        }

        if (animation == null){
            animation = new TranslateAnimation(0, 0, 0, 720);
        }

        line.setVisibility(View.VISIBLE);

        animation.setDuration(2000);

        animation.setRepeatCount(-1);

        line.startAnimation(animation);

        animation.start();
 
    }
    //管理 remoteView 生命周期
    @Override
    protected void onStart() {
        super.onStart();
        if (remoteView!= null){
            remoteView.onStart();
        }

    }

    @Override
    protected void onPause() {

        super.onPause();

        animation.cancel();
        if (remoteView!= null){

            remoteView.onPause();
        }

    }

    @Override
    protected void onDestroy() {

        super.onDestroy();
        if (remoteView!= null){

            remoteView.onDestroy();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (remoteView!= null){

            remoteView.onStop();
        }
    }


}

6:页面xml布局

activity_scanqr.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    android:background="#32CF9C"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/scan_qr_rim"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#C0C0C0" />

        <ImageView
            android:layout_marginBottom="100dp"
            android:layout_alignParentBottom="true"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:id="@+id/flush_btn"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:src="@mipmap/flashlight_off" />

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <RelativeLayout
                android:layout_marginBottom="9dp"
                android:layout_marginTop="275dp"
                android:layout_gravity="center_horizontal"
                android:layout_width="300dp"
                android:layout_height="300dp">
                <View
                    android:id="@+id/scan_qr_line"
                    android:layout_width="2500dp"
                    android:layout_height="16dp"
                    android:background="@mipmap/scan_image"
                    android:visibility="invisible" />

                <ImageView
                    android:layout_width="300dp"
                    android:layout_height="300dp"
                    android:layout_centerHorizontal="true"
                    android:scaleType="fitXY"
                    android:src="@mipmap/pic_scaning"
                     />
                <!--                               -->

            </RelativeLayout>



        </LinearLayout>



    </RelativeLayout>
</LinearLayout>

备注:资源下载地址,码云项目地址

本文地址:https://blog.csdn.net/weixin_35861115/article/details/108974830