博客
关于我
Android实现二维码扫描功能(四)-ZXing识别图片二维码,相册选图
阅读量:242 次
发布时间:2019-02-28

本文共 4965 字,大约阅读时间需要 16 分钟。

如何识别相册中的图片(含二维码)

引言

在本文中,我们将介绍如何从相册中识别图片,特别是包含二维码的图片。这个过程涉及到读取图片文件、处理图片数据以及解析二维码的内容。

第一步:添加权限

首先,我们需要确保应用程序有权限读取外部存储设备,以便可以访问相册中的图片文件。我们可以通过以下步骤在AndroidManifest.xml中添加读取权限:

第二步:动态权限申请

在应用启动时,我们需要动态地请求权限。我们可以在MainActivity中实现这一点。例如,以下是申请相机和读取权限的代码:

private void startQrCode() {    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, Constant.REQ_PERM_CAMERA);        return;    }    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Constant.REQ_PERM_EXTERNAL_STORAGE);        return;    }    // 开始扫描    Intent intent = new Intent(MainActivity.this, CaptureActivity.class);    startActivityForResult(intent, Constant.REQ_QR_CODE);}

第三步:处理权限结果

当用户同意或拒绝权限请求时,我们需要在onRequestPermissionsResult方法中进行处理。这可以确保应用程序在权限被拒绝时能够提示用户设置权限:

@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {    super.onRequestPermissionsResult(requestCode, permissions, grantResults);    switch (requestCode) {        case Constant.REQ_PERM_CAMERA:            // 处理相机权限结果            break;        case Constant.REQ_PERM_EXTERNAL_STORAGE:            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {                //权限已授予,开始扫描                startQrCode();            } else {                //权限未授予,提示用户                Toast.makeText(this, "请至权限中心打开本应用的文件读写权限", Toast.LENGTH_LONG).show();            }            break;    }}

第四步:实现相册选择功能

在CaptureActivity中,我们需要实现点击相册按钮的功能,以便用户可以选择图片:

private View.OnClickListener albumOnClick = new View.OnClickListener() {    @Override    public void onClick(View view) {        Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT);        innerIntent.setType("image/*");        startActivityForResult(innerIntent, REQUEST_CODE_SCAN_GALLERY);    }};

第五步:处理返回的图片数据

在onActivityResult方法中,我们需要处理返回的图片数据,并将其传递给QRCodeReader进行解析:

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    if (requestCode == REQUEST_CODE_SCAN_GALLERY && resultCode == RESULT_OK) {        Bundle bundle = data.getExtras();        String scanResult = bundle.getString(Constant.INTENT_EXTRA_KEY_QR_SCAN);        tvResult.setText(scanResult);    }}

第六步:处理图片数据

在handleAlbumPic方法中,我们需要处理选中的图片数据,并将其转换为Bitmap:

private void handleAlbumPic(Intent data) {    final Uri uri = data.getData();    mProgress = new ProgressDialog(CaptureActivity.this);    mProgress.setMessage("正在扫描...");    mProgress.setCancelable(false);    mProgress.show();    runOnUiThread(new Runnable() {        @Override        public void run() {            Result result = scanningImage(uri);            mProgress.dismiss();            if (result != null) {                Intent resultIntent = new Intent();                Bundle bundle = new Bundle();                bundle.putString(Constant.INTENT_EXTRA_KEY_QR_SCAN, result.getText());                resultIntent.putExtras(bundle);                CaptureActivity.this.setResult(RESULT_OK, resultIntent);                finish();            } else {                Toast.makeText(CaptureActivity.this, "识别失败", Toast.LENGTH_SHORT).show();            }        }    });}

第七步:优化图片处理

为了避免内存溢出,我们可以在BitmapUtil类中优化图片的处理过程。以下是一个示例:

public class BitmapUtil {    public static Bitmap decodeUri(Context context, Uri uri, int maxWidth, int maxHeight) {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        int scale = 1;        while ((options.outWidth / scale > maxWidth || options.outHeight / scale > maxHeight)) {            scale *= 2;        }        options.inSampleSize = scale;        options.inPreferredConfig = Bitmap.Config.RGB_565;        InputStream stream = null;        try {            stream = context.getContentResolver().openInputStream(uri);            BitmapFactory.decodeStream(stream, null, options);        } catch (Exception e) {            Log.w("BitmapUtil", "Unable to open content: " + uri, e);        } finally {            if (stream != null) {                try {                    stream.close();                } catch (IOException e) {                    Log.e("BitmapUtil", "Unable to close content: " + uri, e);                }            }        }        return stream != null && options.outWidth > 0 && options.outHeight > 0 ? BitmapFactory.decodeStream(stream, null, options) : null;    }}

注意事项

  • 确保在AndroidManifest.xml中正确声明所需的权限。
  • 在请求权限时,使用ActivityResultLauncher来处理。
  • 在处理图片数据时,确保使用高效的Bitmap处理方法,以避免内存溢出。
  • 进行全面测试,确保在不同设备和系统版本下都能正常工作。

通过以上步骤,我们可以在应用程序中实现从相册中读取图片,并解析其中的二维码。确保在处理图片数据时,遵循正确的权限管理流程,以提高应用程序的稳定性和用户体验。

转载地址:http://ffgs.baihongyu.com/

你可能感兴趣的文章
Objective-C实现double linear search recursion双线性搜索递归算法(附完整源码)
查看>>
Objective-C实现double linear search 双线性搜索算法(附完整源码)
查看>>
Objective-C实现DoublyLinkedList双链表的算法(附完整源码)
查看>>
Objective-C实现DoublyLinkedList双链表算法(附完整源码)
查看>>
Objective-C实现DPLL(davisb putnamb logemannb loveland)算法(附完整源码)
查看>>
Objective-C实现Edmonds-Karp算法(附完整源码)
查看>>
Objective-C实现EEMD算法(附完整源码)
查看>>
Objective-C实现EM算法(附完整源码)
查看>>
Objective-C实现EM算法(附完整源码)
查看>>
Objective-C实现entropy熵算法(附完整源码)
查看>>
Objective-C实现euclidean distance欧式距离算法(附完整源码)
查看>>
Objective-C实现Euclidean GCD欧几里得最大公约数算法(附完整源码)
查看>>
Objective-C实现euclideanDistance欧氏距离算法(附完整源码)
查看>>
Objective-C实现euler method欧拉法算法(附完整源码)
查看>>
Objective-C实现eulerianPath欧拉路径算法(附完整源码)
查看>>
Objective-C实现EulersTotient欧拉方程算法(附完整源码)
查看>>
Objective-C实现eval函数功能(附完整源码)
查看>>
Objective-C实现even_tree偶数树算法(附完整源码)
查看>>
Objective-C实现Exceeding words超词(差距是ascii码的距离) 算法(附完整源码)
查看>>
Objective-C实现extended euclidean algorithm扩展欧几里得算法(附完整源码)
查看>>