Github项目解析(十)–>几行代码快速集成二维码扫描库 - CSDN博客 http://blog.csdn.net/qq_23547831/article/details/52037710
**
**:
1.添加权限
2.添加依赖:
compile 'cn.yipianfengye.android:zxing-library:2.2'
准备就绪了,马上开干啦。最开始解析本地含二维码的图片时,获取图片路径总报错,我就把它单独放出来进行测试了,现在当然是没问题啦~
所以首界面的功能就是:二维码的扫描、生成(有无logo)、条形码的生成,解析图片界面的功能就只是解析本地包含二维码的图片而已。说了这么多的废话了,是时候亮家伙了
**
**
我喜欢写很多注释,这样方便自己复习功能时,直接看代码就可以看到很多相关的知识点,但也许这篇的注释并不多,因为不需要啊。
注意,需要先执行初始化操作ZXingLibrary.initDisplayOpinion(this);
/**
* 扫描二维码
* 解析图片二维码
* 根据输入的文字生成有无logo的二维码
* 根据输入的文字生成条形码
*/
public class HomeActivity extends AppCompatActivity {
private TextView tvScan;
private TextView tvParseResult;
private TextView tvMakeCode;
private TextView tvMakeCodeNoLogo;
private TextView tvMakeBarCode;
private EditText edInput;
private ImageView imgCode;
private Bitmap mBitmap;
private TextView tvParseImage;
private static final int REQUEST_CODE = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//初始化
ZXingLibrary.initDisplayOpinion(this);
tvScan = (TextView) this.findViewById(R.id.tv_scan);
tvParseResult = (TextView) this.findViewById(R.id.tv_parse_result);
edInput = (EditText) this.findViewById(R.id.ed_input);
tvMakeCode = (TextView) this.findViewById(R.id.tv_make_code);
tvMakeCodeNoLogo = (TextView) this.findViewById(R.id.tv_make_code_no_logo);
tvMakeBarCode = (TextView) this.findViewById(R.id.tv_make_bar_code);
imgCode = (ImageView) this.findViewById(R.id.img_code);
tvParseImage = (TextView) this.findViewById(R.id.tv_parse_image);
//解析二维码图片
tvParseImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(HomeActivity.this,ActParseImage.class);
startActivity(intent);
}
});
//扫描二维码
tvScan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(HomeActivity.this, CaptureActivity.class);
startActivityForResult(intent, REQUEST_CODE);
}
});
//生成有logo的二维码图片
tvMakeCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String textContent = edInput.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
imgCode.setImageBitmap(mBitmap);
}
});
//生成无logo的二维码图片
tvMakeCodeNoLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String textContent = edInput.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
imgCode.setImageBitmap(mBitmap);
}
});
tvMakeBarCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textContent = edInput.getText().toString();
if (TextUtils.isEmpty(textContent)) {
Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
return;
}
makeBarCode(textContent);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case 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);
tvParseResult.setText("扫描解析结果:" + result);
} else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
Toast.makeText(HomeActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
}
}
break;
}
}
/**
* 制作条形码
*/
public void makeBarCode(String barCode){
int size = barCode.length();
for (int i = 0; i < size; i++) {
int c = barCode.charAt(i);
if ((19968 <= c && c < 40623)) {
Toast.makeText(HomeActivity.this, "生成条形码的时刻不能是中文", Toast.LENGTH_SHORT).show();
return;
}
}
Bitmap bmp = null;
try {
if (!TextUtils.isEmpty(barCode)) {
bmp = CreateOneDCode(barCode);
}
} catch (WriterException e) {
e.printStackTrace();
}
if (bmp != null) {
imgCode.setImageBitmap(bmp);
}
}
/**
* 用于将给定的内容生成成一维条码 注:目前生成内容为中文的话将直接报错,要修改底层jar包的内容
*
* @param content 将要生成一维条码的内容
* @return 返回生成好的一维条码bitmap
* @throws WriterException WriterException异常
*/
public Bitmap CreateOneDCode(String content) throws WriterException {
// 生成一维条码,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
int imgWidth = this.getResources().getDisplayMetrics().widthPixels - 40;
int imgHeight = imgWidth / 5 * 2;
BitMatrix matrix = new MultiFormatWriter().encode(content,
BarcodeFormat.CODE_128, imgWidth, imgHeight);
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] = 0xff000000;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
// 通过像素数组生成bitmap,具体参考api
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
}
注意哦,Android6.0及以上不仅要声明权限,还需要在使用的时候,自动询问,此处读取本地图片是必须要进行这样的操作的,但我在这偷了个懒,我没有写自动询问权限,直接去设置里面全部授予了
public class ActParseImage extends AppCompatActivity{
private TextView tvParseImage;
private TextView tvParseResult;
private ImageView imgCode;
private static final int REQUEST_IMAGE = 1102;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_act_parseimage);
//初始化
ZXingLibrary.initDisplayOpinion(this);
tvParseImage = (TextView) this.findViewById(R.id.tv_parse_image);
tvParseResult = (TextView) this.findViewById(R.id.tv_parse_result);
imgCode = (ImageView) this.findViewById(R.id.img_code);
//解析二维码图片
tvParseImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
tvParseResult.setText("");
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case REQUEST_IMAGE:
if (data != null) {
String imagePath = "";//获得图片路径
Uri uri = data.getData();
imagePath = getRealPathFromUri(this,uri);
try {
CodeUtils.analyzeBitmap(imagePath, new CodeUtils.AnalyzeCallback() {
@Override
public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
tvParseResult.setText("解析结果:" + result);
imgCode.setImageBitmap(mBitmap);
}
@Override
public void onAnalyzeFailed() {
Toast.makeText(ActParseImage.this, "解析二维码失败", Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
break;
}
}
/**
* 根据Uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri 图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
public static String getRealPathFromUri(Context context, Uri uri) {
int sdkVersion = Build.VERSION.SDK_INT;
if (sdkVersion >= 19) { // api >= 19
return getRealPathFromUriAboveApi19(context, uri);
} else { // api < 19
return getRealPathFromUriBelowAPI19(context, uri);
}
}
/**
* 适配api19以下(不包括api19),根据uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri 图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
return getDataColumn(context, uri, null, null);
}
/**
* 适配api19及以上,根据uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri 图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
@SuppressLint("NewApi")
private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
String filePath = null;
if (DocumentsContract.isDocumentUri(context, uri)) {
// 如果是document类型的 uri, 则通过document id来进行处理
String documentId = DocumentsContract.getDocumentId(uri);
if (isMediaDocument(uri)) { // MediaProvider
// 使用':'分割
String id = documentId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = {id};
filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
} else if (isDownloadsDocument(uri)) { // DownloadsProvider
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
filePath = getDataColumn(context, contentUri, null, null);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())){
// 如果是 content 类型的 Uri
filePath = getDataColumn(context, uri, null, null);
} else if ("file".equals(uri.getScheme())) {
// 如果是 file 类型的 Uri,直接获取图片对应的路径
filePath = uri.getPath();
}
return filePath;
}
/**
* 获取数据库表中的 _data 列,即返回Uri对应的文件路径
* @return
*/
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
String path = null;
String[] projection = new String[]{MediaStore.Images.Media.DATA};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
path = cursor.getString(columnIndex);
}
} catch (Exception e) {
if (cursor != null) {
cursor.close();
}
}
return path;
}
/**
* @param uri the Uri to check
* @return Whether the Uri authority is MediaProvider
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri the Uri to check
* @return Whether the Uri authority is DownloadsProvider
*/
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
}