您的位置:首页 > 移动开发 > Android开发

Android集成Zxing实现二维码的扫描与生成(含动态权限)

2017-05-27 00:47 816 查看
不诗意的女程序猿不是好厨师~

【转载请注明出处:From李诗雨---http://blog.csdn.net/cjm2484836553/article/details/72774534

目前在做一个和机顶盒相关的app,项目中需要使用二维码扫描来绑定机顶盒。

由于工期的原因,也没时间细细研究,只是粗略集成了一下。

在此,又重新写了一个demo,以示记录。

源码demo:不含动态权限的源码

含动态权限的源码

Demo所包含的功能说明:

①实现二维码的扫描


②实现二维码的生成

③使用RxPermissions添加动态权限

效果图展示:







话不多说,下面就让我们按照如下步骤来一步一步集成Zxing。

第一步:将core-3.3.0.jar包考到libs目录下

点击下载jar包:core-3.3.0.jar



第二步:将整个zxing包考过来

将整个zxing包都拷贝过来,然后暂不做其他处理



第三步:拷贝相关资源文件

将res下的相关的资源文件拷贝过来

这里需要是在自己原有的文件内容的基础上进行叠加,而不是简单替换。

具体点来说就是:

①drawble,drawable-hdpi,drawabl-xhdpi的全部内容都拷贝过来 layout中拷贝2个布局过来



②将raw文件夹都拷过去



③values下的文件拷贝要小心一点!

比如:对于colors.xml文件,我们需要把其中Zxing相关的代码考到自己的colors.xml中去, 而不是简单的替换,其他文件也类似!





④将以下的东西拷贝到res下



第四步:拷贝manifest.xml文件中的相关权限和Activity





第五步先clean project,然后回过头来修改zxing包下报红的类

这无非是包的问题,删了,重新导包即可



第六步:记得将capture.xml下的ViewfinderView的全类名修改为正确的



第七步:先不加动态权限测试一下集成的正确性

先将build.gradle文件下的targetSdkVersion 改为22,

我们先不加动态权限来初步验证一下集成的正确性

MainActivity的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lishiyu.lsy_zxing_rxpermissions_demo.MainActivity">

<!--扫描二维码-->
<Button
android:onClick="canningMethod"
android:textSize="17sp"
android:text="点击扫一扫"
android:id="@+id/btn_scanning"
android:layout_width="match_parent"
android:layout_height="38dp"
/>

<TextView
android:id="@+id/tv_scanning_result"
android:gravity="center"
android:textSize="17sp"
android:text="扫描结果:"
android:layout_width="match_parent"
android:layout_height="38dp" />

<!--生成二维码-->
<EditText
android:textColorHint="#33000000"
android:textColor="#99000000"
android:hint="请输入你要生成的二维码内容"
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="38dp" />

<Button
android:onClick="makeErweimaMethod"
android:textSize="17sp"
android:text="点击生成二维码"
android:id="@+id/btn_make_erweima"
android:layout_width="match_parent"
android:layout_height="38dp"
/>

<ImageView
android:layout_gravity="center_horizontal"
android:id="@+id/result_img"
android:layout_width="200dp"
android:layout_height="200dp" />

</LinearLayout>


①扫描二维码并返回扫描结果

//点击跳转到扫描界面
public void canningMethod(View v) {
Intent intent = new Intent(MainActivity.this,
CaptureActivity.class);
startActivityForResult(intent, SCANNING_CODE);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);
// 扫描二维码/条码回传
if (requestCode == SCANNING_CODE && resultCode == RESULT_OK) {
if (data != null) {

String content = data.getStringExtra(DECODED_CONTENT_KEY);
Bitmap bitmap = data.getParcelableExtra(DECODED_BITMAP_KEY);

tv_scanning_result.setText("扫描结果: " + content);

}
}
}


②生成制定内容和logo的二维码

//点击生成带图片的二维码
public void makeErweimaMethod(View v) {
String aimContent=et_erweima_content.getText().toString();
Create2QR2(aimContent,result_img);
}

//生成二维码的方法
private void Create2QR2(String urls,ImageView imageView) {
String uri = urls;
int mScreenWidth = 0;
Bitmap bitmap;
try {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
mScreenWidth = dm.widthPixels;

bitmap = BitmapUtil.createQRImage(uri, mScreenWidth,
BitmapFactory.decodeResource(getResources(), R.mipmap.me));//自己写的方法

if (bitmap != null) {
imageView.setImageBitmap(bitmap);
}
} catch (Exception e) {
e.printStackTrace();
}

}


涉及到的一个工具类:

public class BitmapUtil {
//生成二维码图片(不带图片)
public static Bitmap createQRCode(String url, int widthAndHeight)
throws WriterException {
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix matrix = new MultiFormatWriter().encode("lvu",
BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);

int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
//画黑点
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = BLACK; //0xff000000
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}

//带图片的二维码
public static Bitmap createQRImage(String content, int heightPix, Bitmap logoBm) {
try {
//配置参数
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//容错级别
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 图像数据转换,使用了矩阵转换
BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, heightPix, heightPix, hints);
int[] pixels = new int[heightPix * heightPix];
// 下面这里按照二维码的算法,逐个生成二维码的图片,
// 两个for循环是图片横列扫描的结果
for (int y = 0; y < heightPix; y++) {
for (int x = 0; x < heightPix; x++) {
if (bitMatrix.get(x, y)) {
pixels[y * heightPix + x] = 0xff000000;
} else {
pixels[y * heightPix + x] = 0xffffffff;
}
}
}

// 生成二维码图片的格式,使用ARGB_8888
Bitmap bitmap = Bitmap.createBitmap(heightPix, heightPix, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, heightPix, 0, 0, heightPix, heightPix);

if (logoBm != null) {
bitmap = addLogo(bitmap, logoBm);
}

//必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
}

return null;
}

/**
* 在二维码中间添加Logo图案
*/
private static Bitmap addLogo(Bitmap src, Bitmap logo) {
if (src == null) {
return null;
}

if (logo == null) {
return src;
}

//获取图片的宽高
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
int logoWidth = logo.getWidth();
int logoHeight = logo.getHeight();

if (srcWidth == 0 || srcHeight == 0) {
return null;
}

if (logoWidth == 0 || logoHeight == 0) {
return src;
}

//logo大小为二维码整体大小的1/5
float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
try {
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(src, 0, 0, null);
canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);

canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
} catch (Exception e) {
bitmap = null;
e.getStackTrace();
}

return bitmap;
}

}


好了,到这里简单的①二维码扫描和②生成二维码功能就实现了。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~华丽的分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面让我来使用RxPermissions增加动态权限 :

RxPermissions的github地址:https://github.com/tbruyelle/RxPermissions

前提:

现在将build.gradle文件下的targetSdkVersion 改为23,

然后在manifest.xml中添加相关权限(这里我们只涉及到 相机 权限):



接着RxPermissions就要正式登场了:

第一步:在build.gradle中做如下配置



[align=left][/align]

即:



第二步:使用



第①步先创建一个RxPermissions实例:



第②步代码中正式使用:

在对应的点击事件的方法中添加动态权限的相关代码:

rxPermissions
.request(Manifest.permission.CAMERA)
.subscribe(granted -> {
if (granted) { // Always true pre-M
//如果已经授权就直接跳转到二维码扫面界面
Intent intent = new Intent(MainActivity.this,
CaptureActivity.class);
startActivityForResult(intent, SCANNING_CODE);

Toast.makeText(this, "扫一扫", Toast.LENGTH_SHORT).show();
} else { // Oups permission denied
Toast.makeText(this, "相机权限被拒绝,无法扫描二维码", Toast.LENGTH_SHORT).show();
return;
}
});


这是你会发现报错了:Lambda expermission are not supported at this language level



这是由于lambda表达式的使用出了问题

解决办法 在build.gradle文件中添加如下代码( 注意必须是1.8以上!)





同步后发现就不再报错了:



(注:卸载后再重新运行)

运行后,点击“扫一扫”会出现下图的效果:



好了,这样加动态权限的扫描二维码和生成带图标的二维码也完成了~

源码demo:不含动态权限的源码
含动态权限的源码

积累点滴,做好自己,晚安~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐