Android Q:从System Gallery Picker获取图像并在下一个活动上对其应用效果

问题描述

打开图库意图

 Intent galleryIntent = new Intent( Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        galleryIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivityForResult(galleryIntent,FILE_REQUEST);
           

OnActivity结果

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
     selected_photo = data.getData();

     String[] filePath = {MediaStore.Images.Media.DATA};
     Cursor c = getContentResolver().query(selected_photo,filePath,null,null);
     c.movetoFirst();
     int columnIndex = c.getColumnIndex(filePath[0]);
     picturePath = c.getString(columnIndex);
     c.close();

     Intent i = new Intent(First.this,Second.class);
     i.putExtra("pic",picturePath);
     startActivity(i);
  }

一个活动日志

E / BitmapFactory:无法解码流: java.io.FileNotFoundException:46:打开失败:ENOENT(没有这样的文件 或目录)

在下次活动中,我在此函数内遇到错误

public Bitmap decodeBitmapFromPath(String filePath) {
    Bitmap scaledBitmap = null;

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    scaledBitmap = BitmapFactory.decodeFile(filePath,options);

    options.inSampleSize = calculateInSampleSize(options,30,30);
    options.inDither = false;
    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inJustDecodeBounds = false;

    scaledBitmap = BitmapFactory.decodeFile(filePath,options);

    ExifInterface exif;
    try {
        exif = new ExifInterface(filePath);

        int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,0);
        Matrix matrix = new Matrix();
        if (orientation == 6) {
            matrix.postRotate(90);
        } else if (orientation == 3) {
            matrix.postRotate(180);
        } else if (orientation == 8) {
            matrix.postRotate(270);
        }
        scaledBitmap = Bitmap.createBitmap(scaledBitmap,scaledBitmap.getWidth(),scaledBitmap.getHeight(),matrix,true);

        eW = scaledBitmap.getWidth();
        eH = scaledBitmap.getHeight();
        eM = matrix;

    } catch (IOException e) {
        e.printstacktrace();
        FirebaseCrashlytics.getInstance().recordException(e);
    }
    return scaledBitmap;
}

第二个活动日志

java.io.FileNotFoundException:46:打开失败:ENOENT(无此文件 或目录)位于libcore.io.IoBridge.open(IoBridge.java:492)处 java.io.FileInputStream。(FileInputStream.java:160)在 java.io.FileInputStream。(FileInputStream.java:115)在 android.media.ExifInterface.initForFilename(ExifInterface.java:2531) 在android.media.ExifInterface。(ExifInterface.java:1500) .SecondActivity.decodeBitmapFromPath(SecondActivity.java:889)

现在,我如何才能在下一个活动中以位图的方式访问这张照片,并对其应用不同的效果

解决方法

如果您想从图库中选择图片,请尝试使用这个新 API。 它叫做ActivityResultLauncher

无需记住任何请求代码即可获得结果,并且易于使用

按照以下步骤从存储中访问图像并将其转换为位图:

  1. 首先像这样创建 ActivityResultLauncher :

    ActivityResultLauncher<String> mGetContent = 
             registerForActivityResult(new GetContent(),new ActivityResultCallback<Uri>() {
     @Override
     public void onActivityResult(Uri uri) {
       // Handle the returned Uri,We will get a bitmap from it here.
    
     }
    });
    
  2. 然后,在单击按钮时或在您想要的任何位置启动系统图像选择器。

    mGetContent.launch("image/*");
    
  • 来自 Uri 方法的位图。

    public statice Bitmap getBitmapFromUri(Context ctx,Uri uri) {
         try {
              if (uri != null) {
                  Bitmap bitmap =
                      MediaStore.Images.Media.getBitmap(ctx.getContentResolver(),uri);
              }
          } catch (Exception e) {
              //handle exception
          }
      }
    

现在您可以在任何地方使用位图。