首页 > 解决方案 > 在 android 6.0.1 中,为什么在通过相机拍照后尝试从 Uri 获取位图时为空?

问题描述

这个问题出现在 android 6.0.1 中,但不在 android 7.0 中。我有这个类 FileKit 通过相机拍照,它有uriToBitmap()将 Uri 转换为位图的方法。 taken_photo_uri存储拍摄照片的uri。

class FileKit{
  public static Uri taken_photo_uri = null;

  public static void takePhoto(RootActivity activity) {
        open_camera_activity = activity;
        if (ContextCompat.checkSelfPermission(MyApplicaiton.getContext(),
                Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            activity.setPermissionRequestInterface(getContext());
            ActivityCompat.requestPermissions(activity,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQ_READ_PHOTO);

        } else {
            File output_image = new File(MyApplicaiton.getContext().getExternalCacheDir(), "output_image.jpg");
            try {
                if (output_image.exists()) {
                    output_image.delete();
                }
                output_image.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (Build.VERSION.SDK_INT >= 24) {
                taken_photo_uri = FileProvider.getUriForFile(MyApplicaiton.getContext(),
                        activity.getResources().getString(R.string.main_package),
                        output_image);
            } else {
                taken_photo_uri = Uri.fromFile(output_image);
            }

            Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, taken_photo_uri);
            activity.startActivityForResult(intent, TAKE_PHOTO);
        }
    }

    public static Bitmap uriToBitmap(Uri uri) {
        Bitmap bitmap = null;

        try {
            bitmap = BitmapFactory.decodeStream(MyApplicaiton.getContext().getContentResolver().openInputStream(uri));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

这是我在演示活动中使用它的方式:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FileKit.takePhoto(activity);
            }
        });

 @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode) {
            case FileKit.TAKE_PHOTO:
                if (resultCode == RESULT_OK) {
                    Bitmap bitmap = FileKit.uriToBitmap(FileKit.taken_photo_uri);
                    if (bitmap == null) {
                        GeneralUtil.showToast("null picture");
                    } else {
                        GeneralUtil.showToast("not null picture");
                        imageView.setImageBitmap(bitmap);
                    }
                }
                break;
        }
    }

在 android 7.0 中情况很好,但uriToBitmap(Uri uri)在 android 6.0.1 中返回 null。如何解决?谢谢!

标签: javaandroid

解决方案


进去看看

takePhoto(){
 if (Build.VERSION.SDK_INT >= 24) {
                taken_photo_uri = FileProvider.getUriForFile(MyApplicaiton.getContext(),
                        activity.getResources().getString(R.string.main_package),
                        output_image);
            } else {
                taken_photo_uri = Uri.fromFile(output_image);
            }
}

您的版本检查在 Nougat 及更高版本上调用 FileProvider.getUriForFile()。从 android 文档 ( https://developer.android.com/reference/android/os/Build.VERSION_CODES ) 中, getUriForFile() 按预期返回 Uri。但是,在 Marshmallow 及以下,您调用 Uri.fromFile() 再次根据 android 文档(https://developer.android.com/reference/android/net/Uri.html#fromFile(java.io .File) ) 返回一个以“file://”为前缀的 Uri。

在不具体了解 Uri 或 Android 的情况下,我会说这可能是问题所在。


推荐阅读