io.FileNotFoundException:打开失败:EACCES(权限被拒绝)

Posted

技术标签:

【中文标题】io.FileNotFoundException:打开失败:EACCES(权限被拒绝)【英文标题】:io.FileNotFoundException: open failed: EACCES (Permission denied) 【发布时间】:2020-11-29 21:09:08 【问题描述】:

我正在尝试将 API 级别 28 更新到 30。这是一个照片编辑器项目。该应用程序已成功运行,但是从本地存储中为作物挑选照片时,该应用程序无法正常工作,我看到了此错误。 “打开失败:EACCES(权限被拒绝)”当我尝试使用 API 28 等旧 API 时,该应用程序运行正常。我检查了 Logcat 并没有找到任何解决方案。另外,我正在尝试改善我的清单许可。但清单权限是可以的。我认为问题出在java代码或方法之下。

请任何人帮助我。

Logcat:

java.io.FileNotFoundException: open failed: EACCES (Permission denied)
        at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
        at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1505)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1345)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1293)
        at com.yalantis.ucrop.task.BitmapLoadTask.doInBackground(BitmapLoadTask.java:101)
        at com.yalantis.ucrop.task.BitmapLoadTask.doInBackground(BitmapLoadTask.java:45)
        at android.os.AsyncTask$3.call(AsyncTask.java:378)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)

Java:

 public class BitmapLoadTask extends AsyncTask<Void, Void, BitmapLoadTask.BitmapWorkerResult> 

    private static final String TAG = "BitmapWorkerTask";

    private final Context mContext;
    private Uri mInputUri;
    private Uri mOutputUri;
    private final int mRequiredWidth;
    private final int mRequiredHeight;

    private final BitmapLoadCallback mBitmapLoadCallback;

    public static class BitmapWorkerResult 

        Bitmap mBitmapResult;
        ExifInfo mExifInfo;
        Exception mBitmapWorkerException;

        public BitmapWorkerResult(@NonNull Bitmap bitmapResult, @NonNull ExifInfo exifInfo) 
            mBitmapResult = bitmapResult;
            mExifInfo = exifInfo;
        

        public BitmapWorkerResult(@NonNull Exception bitmapWorkerException) 
            mBitmapWorkerException = bitmapWorkerException;
        

    

    public BitmapLoadTask(@NonNull Context context,
                          @NonNull Uri inputUri, @Nullable Uri outputUri,
                          int requiredWidth, int requiredHeight,
                          BitmapLoadCallback loadCallback) 
        mContext = context;
        mInputUri = inputUri;
        mOutputUri = outputUri;
        mRequiredWidth = requiredWidth;
        mRequiredHeight = requiredHeight;
        mBitmapLoadCallback = loadCallback;
    

    @Override
    @NonNull
    protected BitmapWorkerResult doInBackground(Void... params) 
        if (mInputUri == null) 
            return new BitmapWorkerResult(new NullPointerException("Input Uri cannot be null"));
        

        try 
            processInputUri();
         catch (NullPointerException | IOException e) 
            return new BitmapWorkerResult(e);
        

        final ParcelFileDescriptor parcelFileDescriptor;
        try 
            parcelFileDescriptor = mContext.getContentResolver().openFileDescriptor(mInputUri, "r");

         catch (FileNotFoundException e) 
            return new BitmapWorkerResult(e);
        

        final FileDescriptor fileDescriptor;
        if (parcelFileDescriptor != null) 
            fileDescriptor = parcelFileDescriptor.getFileDescriptor();
         else 
            return new BitmapWorkerResult(new NullPointerException("ParcelFileDescriptor was null for given Uri: [" + mInputUri + "]"));
        

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
        if (options.outWidth == -1 || options.outHeight == -1) 
            return new BitmapWorkerResult(new IllegalArgumentException("Bounds for bitmap could not be retrieved from the Uri: [" + mInputUri + "]"));
        

        options.inSampleSize = BitmapLoadUtils.calculateInSampleSize(options, mRequiredWidth, mRequiredHeight);
        options.inJustDecodeBounds = false;

        Bitmap decodeSampledBitmap = null;

        boolean decodeAttemptSuccess = false;
        while (!decodeAttemptSuccess) 
            try 
                decodeSampledBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
                decodeAttemptSuccess = true;
             catch (OutOfMemoryError error) 
                Log.e(TAG, "doInBackground: BitmapFactory.decodeFileDescriptor: ", error);
                options.inSampleSize *= 2;
            
        

【问题讨论】:

【参考方案1】:

你应该添加 android:requestLegacyExternalStorage=true 在您的清单中。

【讨论】:

【参考方案2】:

如果您的应用以 Android Q 为目标,您应该在清单文件中定义 android:requestLegacyExternalStorage="true" 以实现向后兼容性。

<manifest..>
    ...
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

【讨论】:

以上是关于io.FileNotFoundException:打开失败:EACCES(权限被拒绝)的主要内容,如果未能解决你的问题,请参考以下文章

java.io.FileNotFoundException:(访问被拒绝)

System.IO.FileNotFoundException 的含义是啥 [重复]

java.io.FileNotFoundException

Xamarin System.IO.FileNotFoundException

eclipse 中的 java.io.FileNotFoundException

getInputStream() 上的 java.io.FileNotFoundException