二维码识别及生成

jar包地址:http://repo1.maven.org/maven2/com/google/zxing/

一 首先谈下遇到的问题:

1.提示 You should manually set the same version via DependencyResolution

Android dependency 'com.android.support:support-compat' has different version for the compile (25.3.0) and runtime (28.0.0) classpath. You should manually set the same version via DependencyResolution

1、分析原因:引用了不同版本的v4包造成的

2、解决方案:在当前project :app的build.gradle用下面这个方法

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
                details.useVersion '25.3.0'
            }
        }
    }
}

2 AndroidManifest.xml:5:5-19:19 to override.

Manifest merger failed : Attribute application@icon value=(@mipmap/ic_launcher) from AndroidManifest.xml:7:9-43

is also present at [:qrlibs-debug:] AndroidManifest.xml:52:9-47 value=(@drawable/launcher_icon).
Suggestion: add 'tools:replace="android:icon"' to <application> element at AndroidManifest.xml:5:5-19:19 to override.

解决方法

注意两个地方:

1. 在manifest节点加上:xmlns:tools="http://schemas.android.com/tools"

2. 在application 节点加上:tools:replace="android:icon, android:theme"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.panzq.myqrcode">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        tools:replace="android:icon, android:theme"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".activity.GenerateQRActivity" />
        <activity android:name=".activity.ScanQRActivity"></activity>
    </application>

</manifest>

 

3、提示 'compile' is obsolete and has been replaced with 'implementation' and 'api'.

Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html

 

implementation project(path: ':qrlibs')

4、参看编译出现的具体代码问题

androidstudio中查看编译报错信息,在Terminal中输入下面命令:

gradlew compileDebugSources --stacktrace -info

 

 5、安装到vivo手机时提示“安装包解析失败”

 

6 ActivityCompat类找不到

 

二 具体实现

话不多说,直接上代码

1、生成aar文件

首先创建一个Android Library。

名字就用zxing源码的包名com.google.zxing.client.android

将zxing源码中的文件拷贝到library目录中对应的目录下面

Build ->Rebuild Project 一下会生成一个aar文件

2.将aar文件导入到项目当中

将上面生成的aar文件拷贝到新建项目的libs目下

在项目的build.gradle最后加入下面两句话


dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation(name: 'qrlibs-debug', ext: 'aar')
implementation 'com.android.support:appcompat-v7:28.0.0'
}
repositories {
flatDir {
dirs 'libs'
}
}
 

重新编译一下OK

3.开始实现代码

这里有个简化版的,直接上代码吧

3.1 扫描二维码

private void startScan() {
        getPermission();
        // 获得授权
        Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
        ZxingConfig config = new ZxingConfig();
        config.setFullScreenScan(false);
        intent.putExtra(Constant.INTENT_ZXING_CONFIG, config);
        startActivityForResult(intent, REQUEST_CODE_SCAN);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case Common.REQ_PERM_CAMERA:
                // 摄像头权限申请
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                } else {
                    // 被禁止授权
                    Uri packageURI = Uri.parse("package:" + getPackageName());
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                    startActivity(intent);

                    //Toast.makeText(MainActivity.this, "没有权限无法扫描呦", Toast.LENGTH_LONG).show();
                    Toast.makeText(MainActivity.this, "请至权限中心打开本应用的相机访问权限", Toast.LENGTH_LONG).show();
                }
                break;
            case Common.REQ_PERM_EXTERNAL_STORAGE:
                // 文件读写权限申请
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 获得授权
                } else {
                    // 被禁止授权
                    Toast.makeText(MainActivity.this, "请至权限中心打开本应用的文件读写权限", Toast.LENGTH_LONG).show();
                }
                break;
        }
    }

    private void getPermission() {
        // 申请相机权限
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            // 申请权限
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, Common.REQ_PERM_CAMERA);
            return;
        }
        // 申请文件读写权限(部分朋友遇到相册选图需要读写权限的情况,这里一并写一下)
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            // 申请权限
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Common.REQ_PERM_EXTERNAL_STORAGE);
            return;
        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // 扫描二维码/条码回传
        if (requestCode == REQUEST_CODE_SCAN && resultCode == RESULT_OK) {
            if (data != null) {
                String content = data.getStringExtra(Constant.CODED_CONTENT);
                result.setText("扫描结果为:" + content);
            }
        }
    }

 

3.2 生成二维码

case R.id.encodeBtnWithLogo:
                contentEtString = contentEt.getText().toString().trim();
                if (TextUtils.isEmpty(contentEtString)) {
                    Toast.makeText(this, "请输入要生成二维码图片的字符串", Toast.LENGTH_SHORT).show();
                    return;
                }

                Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.springmakeup);
                bitmap = CodeCreator.createQRCode(contentEtString, 400, 400, logo);

                if (bitmap != null) {
                    contentIvWithLogo.setImageBitmap(bitmap);
                }
                break;
            case R.id.encodeBtn:
                contentEtString = contentEt.getText().toString().trim();
                if (TextUtils.isEmpty(contentEtString)) {
                    Toast.makeText(this, "请输入要生成二维码图片的字符串", Toast.LENGTH_SHORT).show();
                    return;
                }
                bitmap = CodeCreator.createQRCode(contentEtString, 400, 400, null);
                if (bitmap != null) {
                    contentIv.setImageBitmap(bitmap);
                }
                break;

 

3.3 识别图片二维码

private void identifyQR() {
        String result = new IdentifyQR(this).identiryQR(ivQr);
        if (!TextUtils.isEmpty(result))
            tvQrcontent.append(result);
    }


...

public String identiryQR(ImageView bigImage){
        Bitmap obmp = ((BitmapDrawable) (bigImage).getDrawable()).getBitmap();
        int width = obmp.getWidth();
        int height = obmp.getHeight();
        int[] data = new int[width * height];
        obmp.getPixels(data, 0, width, 0, 0, width, height);
        RGBLuminanceSource source = new RGBLuminanceSource(width, height, data);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader = new QRCodeReader();
        Result re = null;
        try {
            re = reader.decode(bitmap1);
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (ChecksumException e) {
            e.printStackTrace();
        } catch (FormatException e) {
            e.printStackTrace();
        }
        if (re == null) {
            return null;
        } else {
            return re.getText();
        }
    }

 

代码路径:https://dev.tencent.com/u/MichaelPan9999/p/QRcode

简化版代码路径:https://dev.tencent.com/u/MichaelPan9999/p/QRCode_simple

 

posted @ 2019-03-19 16:31  强哥10732  阅读(955)  评论(0)    收藏  举报