java - Android Java奇怪的UCrop权限问题

标签 java android permissions ucrop

因此,我在理解这个问题时遇到了很多麻烦。首先让我说我在 list 文件中有适当的权限设置。我还验证用户是否有权访问外部存储中的文件。所以这是一个疯狂的问题。我正在使用 UCrop 来在我的应用程序中裁剪图像。出于某种原因,我必须先将文件复制到内部存储,然后才能将其与 UCrop 一起使用。这就是我的意思

    private void LoadImage( Intent data ) {
    try {
        Uri imageUri = data.getData();
        Uri tempUri = IO.CopyTemporaryBitmap( getApplicationContext(), imageUri );

        StartCrop( tempUri , getFilesDir() + "/tempimage.png" );
    }
    catch ( Exception e) {
        e.printStackTrace();
        Toast.makeText(this, "Unable to load picture: ", Toast.LENGTH_LONG).show();
    }
}

IO.CopyTemporaryBitmap

    public static Uri CopyTemporaryBitmap( Context context, Uri src ) {
    Bitmap bmp;
    try {
        InputStream imageStream = context.getContentResolver().openInputStream( src );
        bmp = BitmapFactory.decodeStream(imageStream);
    }
    catch ( Exception e ) {
        e.printStackTrace();
        return null;
    }

    if ( bmp == null ) return null;
    File tempPath = new File( GetTempFolder() );
    File file = new File( GetTempFolder() + "tempImage.png" );

    try {
        boolean b = true;
        if (!tempPath.exists()) b = tempPath.mkdirs();
        if ( !file.exists() && b ) b = file.createNewFile();

        if (b) {
            FileOutputStream out = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
        }

        return Uri.fromFile( file );
    }
    catch ( Exception e ) {
        e.printStackTrace();
    }
    return null;
}

如果我这样做,它就会起作用。我有读/写访问权限,所以我可以将图像复制到内部然后裁剪它,但如果我只是这样做的话

    private void LoadImage( Intent data ) {
    try {
        Uri imageUri = data.getData();
        StartCrop( imageUri, getFilesDir() + "/tempimage.png" );
    }
    catch ( Exception e) {
        e.printStackTrace();
        Toast.makeText(this, "Unable to load picture: ", Toast.LENGTH_LONG).show();
    }
}

然后我得到

E/TransformImageView: onFailure: setImageUri
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:1498)
    at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1338)
    at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1286)
    at com.yalantis.ucrop.task.BitmapLoadTask.doInBackground(BitmapLoadTask.java:97)
    at com.yalantis.ucrop.task.BitmapLoadTask.doInBackground(BitmapLoadTask.java:41)
    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)

经过大量调试后,我发现罪魁祸首是 TransformImageView.java 类中的 setImageUri 方法,它是 UCrop 的一部分,我没有写。

/**
 * This method takes an Uri as a parameter, then calls method to decode it into Bitmap with specified size.
 *
 * @param imageUri - image Uri
 * @throws Exception - can throw exception if having problems with decoding Uri or OOM.
 */
public void setImageUri(@NonNull Uri imageUri, @Nullable Uri outputUri) throws Exception {
    int maxBitmapSize = getMaxBitmapSize();

    BitmapLoadUtils.decodeBitmapInBackground(getContext(), imageUri, outputUri, maxBitmapSize, maxBitmapSize,
            new BitmapLoadCallback() {

                @Override
                public void onBitmapLoaded(@NonNull Bitmap bitmap, @NonNull ExifInfo exifInfo, @NonNull String imageInputPath, @Nullable String imageOutputPath) {
                    mImageInputPath = imageInputPath;
                    mImageOutputPath = imageOutputPath;
                    mExifInfo = exifInfo;

                    mBitmapDecoded = true;
                    setImageBitmap(bitmap);
                }

                @Override
                public void onFailure(@NonNull Exception bitmapWorkerException) {
                    Log.e(TAG, "onFailure: setImageUri", bitmapWorkerException);
                    if (mTransformImageListener != null) {
                        mTransformImageListener.onLoadFailure(bitmapWorkerException);
                    }
                }
            });
}

无论出于何种原因,“BitmapLoadUtils.decodeBitmapInBackground...”总是会触发带有“权限被拒绝”的“onFailure”选项。有什么线索吗?

最佳答案

这是我发现的解决问题的方法:

我加了

android:requestLegacyExternalStorage="true"

到应用程序部分下的我的 list 。

看起来事情随着存储发生了变化。有关详细信息,您可以阅读,

https://commonsware.com/blog/2019/06/07/death-external-storage-end-saga.html

关于java - Android Java奇怪的UCrop权限问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58372141/

相关文章:

java - 如何将本地 ActiveMQ 代理发送到远程 ActiveMQ 代理上的 "mirror"队列?

java - 有人知道如何克服 IntelliJ 中的 "Compiler internal error. Process terminated with exit code 138"吗?

android - 检测 Widevine DRM HDCP 保护级别

php - php中的Google Drive API(团队驱动器)文件权限对任何人或特定域

amazon-web-services - 仅适用于付款和使用事件 View 的 AWS IAM 政策(适用于会计人员)

java - 如何在不修改 java.policy 文件的情况下向我的小程序授予打印权限

java - `ArrayList::get` 是线程安全的吗?

java - 我的Java服务器的相对路径

android - onCleared如何运作AndroidViewModel [android-architecture-component]

java - 改变android中的背景颜色