使用步骤:
步骤1: app.gradle中引入
implementation 'cn.bingoogolapple:bga-qrcode-zxing:1.2.1'
步骤2: 申请运行时权限,主要是:
Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE
我这边用的是PermissionDispatcher一键插入用起来特别便捷 PermissionDispatcher Permission开源地址
步骤3: xml书写
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.initproject.ui.activity.me.ZxingActivity">
<include
layout="@layout/include_toolbar"
/>
<!--app:qrcv_barcodeRectHeight条码扫描框的宽度
qrcv_borderSize扫描框的宽度
qrcv_cornerColor扫描框的颜色
qrcv_cornerLength扫描框边角线的长度
qrcv_cornerSize扫描框边角线的宽度
qrcv_customScanLineDrawable扫描线的图片资源「默认的扫描线图片样式不能满足你的需求时使用,
*********** 自定义的扫描线
设置该属性后 qrcv_isShowDefaultScanLineDrawable、qrcv_scanLineSize、qrcv_scanLineColor 将失效」
qrcv_isBarcode是否是扫条形码
qrcv_isCenterVertical扫描框是否垂直居中,该属性为true时会忽略 qrcv_topOffset 属性
qrcv_isOnlyDecodeScanBoxArea 是否只识别扫描框区域的二维码
qrcv_isScanLineReverse扫描线是否来回移动
qrcv_isShowDefaultGridScanLineDrawable是否显示默认的网格图片扫描线
qrcv_isShowTipBackground是否显示提示文案的背景
qrcv_isShowTipTextAsSingleLine是否把提示文案作为单行显示
qrcv_isTipTextBelowRect提示文案是否在扫描框的底部
qrcv_maskColor除去扫描框,其余部分阴影颜色
qrcv_qrCodeTipText
qrcv_rectWidth 扫描框的宽度
qrcv_scanLineColor扫描线的颜色「扫描线和默认的扫描线图片的颜色」
qrcv_scanLineMargin扫描线距离上下或者左右边框的间距
qrcv_scanLineSize扫描线的宽度
qrcv_toolbarHeight Toolbar 的高度,通过该属性来修正由 Toolbar 导致扫描框在垂直方向上的偏差
qrcv_topOffset扫描框距离 toolbar 底部的距离-->
<cn.bingoogolapple.qrcode.zxing.ZXingView
android:id="@+id/zxingview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:qrcv_animTime="1000"
app:qrcv_barCodeTipText="将条码放入框内,即可自动扫描"
app:qrcv_barcodeRectHeight="140dp"
app:qrcv_borderColor="@android:color/white"
app:qrcv_borderSize="1dp"
app:qrcv_cornerColor="@color/green3"
app:qrcv_cornerLength="20dp"
app:qrcv_cornerSize="3dp"
app:qrcv_isBarcode="false"
app:qrcv_isCenterVertical="false"
app:qrcv_isOnlyDecodeScanBoxArea="false"
app:qrcv_isScanLineReverse="true"
app:qrcv_isShowDefaultGridScanLineDrawable="false"
app:qrcv_isShowDefaultScanLineDrawable="true"
app:qrcv_isShowTipBackground="true"
app:qrcv_isShowTipTextAsSingleLine="false"
app:qrcv_isTipTextBelowRect="true"
app:qrcv_maskColor="#33FFFFFF"
app:qrcv_qrCodeTipText="将二维码/条码放入框内,即可自动扫描"
app:qrcv_rectWidth="220dp"
app:qrcv_scanLineColor="@color/green1"
app:qrcv_scanLineMargin="0dp"
app:qrcv_scanLineSize="1dp"
app:qrcv_tipTextColor="@android:color/white"
app:qrcv_tipTextSize="12sp"
app:qrcv_toolbarHeight="56dp"
app:qrcv_topOffset="90dp"/>
<!-- app:qrcv_scanLineSize 扫描线的宽度-->
<!-- app:qrcv_topOffset 扫描框顶部距离toolbar底部距离-->
<LinearLayout
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal"
android:layout_marginBottom="20dp"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:padding="15dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/open_flashlight"
style="@style/AutoWrapTv"
android:text="开灯" />
<TextView
android:id="@+id/close_flashlight"
style="@style/AutoWrapTv"
android:text="关灯" />
<TextView
android:id="@+id/choose_qrcde_from_gallery"
style="@style/AutoWrapTv"
android:text="相册" />
</LinearLayout>
</RelativeLayout>
步骤4:activity中书写,打开相册运用了PictureSelector框架
public class ZxingActivity extends BaseActivity implements QRCodeView.Delegate {
@BindView(R.id.ivToolbarNavigation)
ImageView mIvToolbarNavigation;
@BindView(R.id.vToolbarDivision)
View mVToolbarDivision;
@BindView(R.id.tvToolbarTitle)
TextView mTvToolbarTitle;
@BindView(R.id.llToolbarTitle)
LinearLayout mLlToolbarTitle;
@BindView(R.id.flToolBar)
FrameLayout mFlToolBar;
@BindView(R.id.zxingview)
ZXingView mZxingview;
@BindView(R.id.open_flashlight)
TextView mOpenFlashlight;
@BindView(R.id.close_flashlight)
TextView mCloseFlashlight;
@BindView(R.id.choose_qrcde_from_gallery)
TextView mChooseQrcdeFromGallery;
private List<LocalMedia> selectList = new ArrayList<>();
@Override
protected void initListener() {
mIvToolbarNavigation.setOnClickListener(view -> finish());
mOpenFlashlight.setOnClickListener(view -> mZxingview.openFlashlight());
mCloseFlashlight.setOnClickListener(view -> mZxingview.closeFlashlight());
mChooseQrcdeFromGallery.setOnClickListener(view -> choosePictureEvent());
}
@Override
protected void initData() {
}
@Override
protected void initView(Bundle savedInstanceState) {
mTvToolbarTitle.setText("扫一扫");
mZxingview.setDelegate(this);
}
@Override
protected int provideContentViewId() {
return R.layout.activity_zxing;
}
@Override
protected void init() {
}
@Override
protected BasePresenter createPresenter() {
return null;
}
// *****************核心方法进行数据的处理 未完待续 *******************
public void handleResult(String result){
LogUtils.e("扫描", result);
UIUtils.showToast(result);
mZxingview.startSpot(); // 延迟1.5秒后开始识别
vibrate();
// 这里还要进行处理呢别急哦
if (result.startsWith(AppConst.QrCodeCommon.ADD)){
// 判断
// 首先查询联系人是否已经是好友,是好友的话那么就返回了,否则就进行加入了
// finish();
}
}
/**
* 震动手机
*/
private void vibrate() {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(200);
}
/**
* 扫描二维码成功回调
*/
@Override
public void onScanQRCodeSuccess(String result) {
handleResult(result);
}
/**
* 扫描二维码失败回调
*/
@Override
public void onScanQRCodeOpenCameraError() {
LogUtils.e("扫描", "打开相机时出错");
UIUtils.showToast("打开相机时出错");
}
/*===============================打开相册开始============================*/
public void choosePictureEvent() {
PictureSelector.create(ZxingActivity.this)
.openGallery(PictureMimeType.ofAll())// 全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
.theme(R.style.picture_default_style)// 主题样式设置 具体参考 values/styles 用法:R.style.picture.white.style
.maxSelectNum(1)// 最大图片选择数量
.minSelectNum(1)// 最小选择数量
.imageSpanCount(4)// 每行显示个数
.selectionMode(PictureConfig.SINGLE)// 多选 or 单选 PictureConfig.MULTIPLE : PictureConfig.SINGLE
.previewImage(true)// 是否可预览图片
.previewVideo(false)// 是否可预览视频
.enablePreviewAudio(true) // 是否可播放音频
.isCamera(true)// 是否显示拍照按钮
.isZoomAnim(true)// 图片列表点击 缩放效果 默认true
//.imageFormat(PictureMimeType.PNG)// 拍照保存图片格式后缀,默认jpeg
//.setOutputCameraPath("/CustomPath")// 自定义拍照保存路径
.enableCrop(false)// 是否裁剪
.compress(false)// 是否压缩
.synOrAsy(true)//同步true或异步false 压缩 默认同步
//.compressSavePath(getPath())//压缩图片保存地址
//.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效
.glideOverride(160, 160)// glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度
.withAspectRatio(1, 1)// 裁剪比例 如16:9 3:2 3:4 1:1 可自定义
.hideBottomControls(false)// 是否显示uCrop工具栏,默认不显示
.isGif(true)// 是否显示gif图片
.freeStyleCropEnabled(false)// 裁剪框是否可拖拽
.circleDimmedLayer(false)// 是否圆形裁剪
.showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false
.showCropGrid(false)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false
.openClickSound(false)// 是否开启点击声音
.selectionMedia(selectList)// 是否传入已选图片
//.isDragFrame(false)// 是否可拖动裁剪框(固定)
// .videoMaxSecond(15)
// .videoMinSecond(10)
//.previewEggs(false)// 预览图片时 是否增强左右滑动图片体验(图片滑动一半即可看到上一张是否选中)
//.cropCompressQuality(90)// 裁剪压缩质量 默认100
.minimumCompressSize(100)// 小于100kb的图片不压缩
//.cropWH()// 裁剪宽高比,设置如果大于图片本身宽高则无效
//.rotateEnabled(true) // 裁剪是否可旋转图片
//.scaleEnabled(true)// 裁剪是否可放大缩小图片
//.videoQuality()// 视频录制质量 0 or 1
//.videoSecond()//显示多少秒以内的视频or音频也可适用
//.recordVideoSecond()//录制视频秒数 默认60s
.forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case PictureConfig.CHOOSE_REQUEST:
selectList = PictureSelector.obtainMultipleResult(data);
// 例如 LocalMedia 里面返回三种path
// 1.media.getPath(); 为原图path
// 2.media.getCutPath();为裁剪后path,需判断media.isCut();是否为true
// 3.media.getCompressPath();为压缩后path,需判断media.isCompressed();是否为true
// 如果裁剪并压缩了,已取压缩路径为准,因为是先裁剪后压缩的
/* for (LocalMedia media : selectList) {
Log.i("图片-----》", media.getPath());
}*/
String path = selectList.get(0).getPath();
String spotResult = QRCodeDecoder.syncDecodeQRCode(path);
if (Check.isNull(spotResult)){
UIUtils.showToast("未发现二维码!");
}else {
handleResult(spotResult);
}
break;
}
}
}
/*==============================打开相册回调结束了============================*/
// 生命周期开启和关闭
@Override
protected void onStart() {
super.onStart();
mZxingview.startCamera();
// 开始扫描并展示扫描框
mZxingview.startSpotAndShowRect();
}
@Override
protected void onStop() {
mZxingview.stopCamera();
super.onStop();
}
@Override
protected void onDestroy() {
mZxingview.onDestroy();
super.onDestroy();
}
}
步骤5,生成二维码
Observable.just(QRCodeEncoder.syncEncodeQRCode(AppConst.QrCodeCommon.ADD+"我是帅逼",UIUtils.dip2Px(100),R.color.black,UIUtils.getBitmap(R.mipmap.default_header)))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Bitmap>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Bitmap bitmap) {
ivCard.setImageBitmap(bitmap);
}
@Override
public void onError(Throwable e) {
LogUtils.e("二维码生成",e.getLocalizedMessage());
}
@Override
public void onComplete() {
}
});