From 7dfe12bd7ac0e0ba6b9965353fb5e12a1344ffae Mon Sep 17 00:00:00 2001 From: isamborskiy Date: Mon, 23 Dec 2019 15:15:24 +0800 Subject: [PATCH] Fix Android 10 issue with "permission denied" --- sample/build.gradle | 4 +- .../yalantis/ucrop/task/BitmapLoadTask.java | 74 +++++-------------- 2 files changed, 22 insertions(+), 56 deletions(-) diff --git a/sample/build.gradle b/sample/build.gradle index ce8dda607..fe59af377 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 buildToolsVersion '28.0.3' defaultConfig { applicationId "com.yalantis.ucrop.sample" minSdkVersion 14 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 13 versionName "1.2.4" } diff --git a/ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java b/ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java index c836fdd11..61235a158 100755 --- a/ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java +++ b/ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java @@ -1,34 +1,26 @@ package com.yalantis.ucrop.task; -import android.Manifest.permission; import android.content.Context; -import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.net.Uri; import android.os.AsyncTask; -import android.os.Build; -import android.os.ParcelFileDescriptor; -import android.text.TextUtils; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.yalantis.ucrop.callback.BitmapLoadCallback; import com.yalantis.ucrop.model.ExifInfo; import com.yalantis.ucrop.util.BitmapLoadUtils; -import com.yalantis.ucrop.util.FileUtils; import java.io.File; -import java.io.FileDescriptor; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -95,27 +87,8 @@ protected BitmapWorkerResult doInBackground(Void... params) { 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; @@ -124,11 +97,22 @@ protected BitmapWorkerResult doInBackground(Void... params) { boolean decodeAttemptSuccess = false; while (!decodeAttemptSuccess) { try { - decodeSampledBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); + InputStream stream = mContext.getContentResolver().openInputStream(mInputUri); + try { + decodeSampledBitmap = BitmapFactory.decodeStream(stream, 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 + "]")); + } + } finally { + BitmapLoadUtils.close(stream); + } decodeAttemptSuccess = true; } catch (OutOfMemoryError error) { Log.e(TAG, "doInBackground: BitmapFactory.decodeFileDescriptor: ", error); options.inSampleSize *= 2; + } catch (IOException e) { + Log.e(TAG, "doInBackground: ImageDecoder.createSource: ", e); + return new BitmapWorkerResult(new IllegalArgumentException("Bitmap could not be decoded from the Uri: [" + mInputUri + "]", e)); } } @@ -136,10 +120,6 @@ protected BitmapWorkerResult doInBackground(Void... params) { return new BitmapWorkerResult(new IllegalArgumentException("Bitmap could not be decoded from the Uri: [" + mInputUri + "]")); } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - BitmapLoadUtils.close(parcelFileDescriptor); - } - int exifOrientation = BitmapLoadUtils.getExifOrientation(mContext, mInputUri); int exifDegrees = BitmapLoadUtils.exifToDegrees(exifOrientation); int exifTranslation = BitmapLoadUtils.exifToTranslation(exifOrientation); @@ -171,16 +151,11 @@ private void processInputUri() throws NullPointerException, IOException { throw e; } } else if ("content".equals(inputUriScheme)) { - String path = getFilePath(); - if (!TextUtils.isEmpty(path) && new File(path).exists()) { - mInputUri = Uri.fromFile(new File(path)); - } else { - try { - copyFile(mInputUri, mOutputUri); - } catch (NullPointerException | IOException e) { - Log.e(TAG, "Copying failed", e); - throw e; - } + try { + copyFile(mInputUri, mOutputUri); + } catch (NullPointerException | IOException e) { + Log.e(TAG, "Copying failed", e); + throw e; } } else if (!"file".equals(inputUriScheme)) { Log.e(TAG, "Invalid Uri scheme " + inputUriScheme); @@ -188,15 +163,6 @@ private void processInputUri() throws NullPointerException, IOException { } } - private String getFilePath() { - if (ContextCompat.checkSelfPermission(mContext, permission.READ_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED) { - return FileUtils.getPath(mContext, mInputUri); - } else { - return null; - } - } - private void copyFile(@NonNull Uri inputUri, @Nullable Uri outputUri) throws NullPointerException, IOException { Log.d(TAG, "copyFile");