本文共 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; }} 通过以上步骤,我们可以在应用程序中实现从相册中读取图片,并解析其中的二维码。确保在处理图片数据时,遵循正确的权限管理流程,以提高应用程序的稳定性和用户体验。
转载地址:http://ffgs.baihongyu.com/