Android中Zxing二维码的扫描、生成(带有动态权限申请)
其实好多时候我们生活中都会使用到二维码,超市的买东西、商店的购物等。。。。。。做开发的过程中我们使用到二维码来进行扫描下载app,下面我来给大家介绍一下如何使用吧!!!
这是我看的大神的github:https://github.com/yipianfengye/android-zxingLibrary
一、添加model依赖
在module的build.gradle中执行compile操作
compile 'cn.yipianfengye.android:zxing-library:2.2'
二、初始化Application
在demo中新建一个application执行初始化操作
@Override
public void onCreate() {
super.onCreate();
ZXingLibrary.initDisplayOpinion(this);
}
三、打开默认二维码界面
先看下activity_main代码
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/mBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="打开二维码扫描界面" /> </RelativeLayout>
MainActivity代码如下:
在代码中执行打开扫描二维码界面操作
/**
* 打开默认二维码扫描界面
*/
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, REQUEST_CODE);
}
});
这里的REQUEST_CODE是我们定义的int型常量。
在Activity的onActivityResult方法中接收扫描结果
/**
* 处理二维码扫描结果
*/
if (requestCode == REQUEST_CODE) {
//处理扫描结果(在界面上显示)
if (null != data) {
Bundle bundle = data.getExtras();
if (bundle == null) {
return;
}
if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
String result = bundle.getString(CodeUtils.RESULT_STRING);
Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
} else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
}
}
}
三、添加动态权限
首先需要判断下版本号是大于还是小于23,(大于6.0或小于6.0)就需要做权限申请
//首先判断用户手机的版本号 如果版本大于6.0就需要动态申请权限 //如果版本小于6.0就直接去扫描二维码 if(Build.VERSION.SDK_INT<23){ //说明是android6.0之前的 Intent intent = new Intent(MainActivity.this, CaptureActivity.class); //第二个参数是请求码 startActivityForResult(intent, REQUEST_CODE); }else { //添加动态权限申请 //1.定义一个数组,用来装载申请的权限 String[] permissons={ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.VIBRATE }; //2.判断这些权限有没有申请,没有申请的话,就把没有申请的权限放到一个数组里面 ArrayList<String> deniedPermissions=new ArrayList<String>(); for(String permission:permissons){ int i = ContextCompat.checkSelfPermission(this, permission); if(PackageManager.PERMISSION_DENIED==i){ //说明权限没有被申请 deniedPermissions.add(permission); } } if(deniedPermissions.size()==0){ return; } //当你不知道数组多大的时候,就可以先创建一个集合,然后调用集合的toArray方法需要传递一个数组参数,这个数组参数的长度 //设置成跟集合一样的长度 String[] strings = deniedPermissions.toArray(new String[permissons.length]); //3.去申请权限 ActivityCompat.requestPermissions(MainActivity.this,strings,REQUEST_ERWERMA_CODE); }
//4.去检查有没有申请成功 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(requestCode==REQUEST_ERWERMA_CODE){ //说明是我们为二维码申请的权限的回调 for(int i=0;i<grantResults.length;i++){ if(grantResults[i]==PackageManager.PERMISSION_GRANTED){ //说明申请成功了 Toast.makeText(this, permissions[i]+"申请成功了", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(MainActivity.this, CaptureActivity.class); //第二个参数是请求码 startActivityForResult(intent, REQUEST_CODE); }else { Toast.makeText(this, permissions[i]+"没有申请成功,请检查下次通过该权限", Toast.LENGTH_SHORT).show(); } } } }
下面看下效果图吧:
打开默认的二维码扫描页面
扫描成功时就会弹出吐司哈~~~
四、定制化显示UI
由于我们的扫描组件是通过Fragment实现的,所以能够很轻松的实现扫描UI的定制化
在新的Activity中定义Layout布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_second"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/second_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:layout_gravity="bottom|center_horizontal"
/>
<FrameLayout
android:id="@+id/fl_my_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
></FrameLayout>
</FrameLayout>
启动id为fl_my_container的FrameLayout就是我们需要替换的扫描组件,也就是说我们会将我们定义的扫描Fragment替换到id为fl_my_container的FrameLayout的位置。而上面的button是我们添加的一个额外的控件,在这里你可以添加任意的控件,各种UI效果等。具体可以看下面在Activity的初始化过程。
在Activity中执行Fragment的初始化操作
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
/**
* 执行扫面Fragment的初始化操作
*/
CaptureFragment captureFragment = new CaptureFragment();
// 为二维码扫描界面设置定制化界面
CodeUtils.setFragmentArgs(captureFragment, R.layout.my_camera);
captureFragment.setAnalyzeCallback(analyzeCallback);
/**
* 替换我们的扫描控件
*/ getSupportFragmentManager().beginTransaction().replace(R.id.fl_my_container, captureFragment).commit();
}
其中analyzeCallback是我们定义的扫描回调函数,其具体的定义:
/**
* 二维码解析回调函数
*/
CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() {
@Override
public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
Intent resultIntent = new Intent();
Bundle bundle = new Bundle();
bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
bundle.putString(CodeUtils.RESULT_STRING, result);
resultIntent.putExtras(bundle);
SecondActivity.this.setResult(RESULT_OK, resultIntent);
SecondActivity.this.finish();
}
@Override
public void onAnalyzeFailed() {
Intent resultIntent = new Intent();
Bundle bundle = new Bundle();
bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
bundle.putString(CodeUtils.RESULT_STRING, "");
resultIntent.putExtras(bundle);
SecondActivity.this.setResult(RESULT_OK, resultIntent);
SecondActivity.this.finish();
}
};
仔细看的话,你会发现我们调用了CondeUtils.setFragmentArgs方法,该方法主要用于修改扫描界面扫描框与透明框相对位置的,与若不调用的话,其会显示默认的组件效果,而如果调用该方法的话,可以修改扫描框与透明框的相对位置等UI效果,我们可以看一下my_camera布局文件的实现.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<com.uuzuche.lib_zxing.view.ViewfinderView
android:id="@+id/viewfinder_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:inner_width="200dp"
app:inner_height="200dp"
app:inner_margintop="150dp"
app:inner_corner_color="@color/scan_corner_color"
app:inner_corner_length="30dp"
app:inner_corner_width="5dp"
app:inner_scan_bitmap="@drawable/scan_image"
app:inner_scan_speed="10"
app:inner_scan_iscircle="false"
/>
</FrameLayout>
上面我们自定义的扫描控件的布局文件
五、生成默认的、带logo的二维码
先看activity_third代码
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <EditText android:id="@+id/edit_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:minLines="3" android:layout_marginTop="20dp" android:layout_marginRight="20dp" android:layout_marginLeft="20dp" /> <Button android:id="@+id/button_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="20dp" android:layout_below="@+id/edit_content" android:text="生成logo二维码图片" /> <Button android:id="@+id/button1_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="20dp" android:layout_below="@+id/button_content" android:text="生成普通二维码图片" /> <ImageView android:id="@+id/image_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button1_content" android:layout_marginTop="20dp" android:layout_centerHorizontal="true" /> </RelativeLayout>
生成不带logo的二维码图片
/**
* 生成不带logo的二维码图片
*/
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textContent = editText.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
editText.setText("");
mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
imageView.setImageBitmap(mBitmap);
}
});
生成带Logo的二维码图片:
/**
* 生成二维码图片
*/
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textContent = editText.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
editText.setText("");
mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
imageView.setImageBitmap(mBitmap);
}
});
下面来看下效果图吧哈哈哈~~~
默认的不带logo的二维码
生成带logo的二维码
哈哈哈哈,一切都结束了,下次再见~~~~