Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Android 10 issue with "permission denied" (non-native) #614

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sample/build.gradle
Original file line number Diff line number Diff line change
@@ -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"
}
Expand Down
74 changes: 20 additions & 54 deletions ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -124,22 +97,29 @@ 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));
}
}

if (decodeSampledBitmap == null) {
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);
Expand Down Expand Up @@ -171,32 +151,18 @@ 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);
throw new IllegalArgumentException("Invalid Uri scheme" + inputUriScheme);
}
}

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");

Expand Down