2

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

在此处输入图像描述

请任何人帮助我。

日志猫:

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)

爪哇:

 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;
            }
        }
4

2 回答 2

2

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

于 2020-08-10T10:24:50.070 回答
0

如果您的应用面向 Android Q,则android:requestLegacyExternalStorage="true"出于向后兼容性的原因,您应该在清单文件中进行定义。

<manifest..>
    ...
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>
于 2020-08-10T09:13:15.927 回答