BitmapFactory:java.io.FileNotFoundException:オープンに失敗しました:AndroidのQ上のEACCES(パーミッション拒否)デコードストリームにできません。

K.tas:

私は権限が付与されますがBitmapFactory.decodeFile()、このエラーを返します:

E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20200130_165131.jpg: open failed: EACCES (Permission denied)

私はギャラリーから最後の画像を取得し、別のファイルに保存します。私はそれが実行されていたAndroidのP・テスト・デバイス上でそれをテストしました。しかし、それはアンドロイド版Q(APIレベル29)とAndroidのエミュレータで、このエラーを返します。それの何がいけないの?

これらは私のコードスニペットです:

writeStoragePermissionGranted();

BitmapFactory.Options options = null;
Bitmap bm = null;

String[] projection = new String[]{
            MediaStore.Images.ImageColumns._ID,
            MediaStore.Images.ImageColumns.DATA,
            MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
            MediaStore.Images.ImageColumns.DATE_TAKEN,
            MediaStore.Images.ImageColumns.MIME_TYPE,
            MediaStore.Images.ImageColumns.DISPLAY_NAME,
    };

    final Cursor cursor = this.getContentResolver()
            .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
                    null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
      if (cursor.moveToFirst()) {
        final ImageView imageView = (ImageView) findViewById(R.id.pictureView);
        String imageLocation = cursor.getString(1);
        File imageFile = new File(imageLocation);

        if (imageFile.exists()) {
            options = new BitmapFactory.Options();
            options.inSampleSize = 2;

            try {
                    bm = BitmapFactory.decodeFile(imageLocation, options);
            } catch(Exception e) {
                    e.printStackTrace();
            }
        }

        imageView.setImageBitmap(bm);



        try {
            saveImage(bm,"NAME" );
        } catch (IOException e) {
                e.printStackTrace();
        }
    }

writeStoragePermissionGranted() 関数:

 public void writeStoragePermissionGranted() {
       if (Build.VERSION.SDK_INT >= 23) {
           if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                   == PackageManager.PERMISSION_GRANTED) {
            startPeriodicRequest();
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION);
        }
    } else {
        return;
    }
} 

マニフェスト権限:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

私はそれについて多くの質問があります知っています。しかし、誰が、一方でAndroidエミュレータのバージョンQ.で働いていない、このコードは、Androidパイ(APIレベル28)で動作します

W0rmH0le:

Androidの10日、彼らはあなたは、もはやそのパスを使用して画像を開くことができ、「スコープストレージ」の概念と、このように導入されません。あなたはより多くの情報を得ることができますHERE

だから今は、その使用して、それをデコードする必要がありParcelFileDescriptor、そのをUri

あなたはできる:

final Cursor cursor = this.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        projection, null, null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
if (cursor.moveToFirst()) {
    final ImageView imageView = (ImageView) findViewById(R.id.pictureView);


    if (Build.VERSION.SDK_INT >= 29) {
        // You can replace '0' by 'cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID)'
        // Note that now, you read the column '_ID' and not the column 'DATA'
        Uri imageUri= ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor.getInt(0));

        // now that you have the media URI, you can decode it to a bitmap
        try (ParcelFileDescriptor pfd = this.getContentResolver().openFileDescriptor(mediaUri, "r")) {
            if (pfd != null) {
                bitmap = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
            }
        } catch (IOException ex) {

        }
    } else {
        // Repeat the code you already are using
    }
}

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=478369&siteId=1