打开失败:在 onActivityResult 中使用 FileProvider 时 EACCES(权限被拒绝)

问题描述 投票:0回答:1

我正在尝试在 onActivityResult 中获取最近录制的视频。但我不明白这个内容提供商是如何工作的。我不习惯用 Java 为 Android 编程,所以这可能是一件简单的事情,但我自己无法解决。

问题只是如何使用应用程序文件夹中的提供程序将 content://media/external/video/media/17877 获取到本地文件,无需额外访问

这是我正在调试的代码部分:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    ....
    } else if (requestCode == CAMERA_REQUEST_VIDEO) {
        if (resultCode == Activity.RESULT_OK && data != null) {
    ....
            Uri selectedMediaUri = data.getData();
            String strMediaFile = getRealPathFromURI(getApplicationContext(),selectedMediaUri);
            Log.d("App","got link:"+selectedMediaUri+" File:"+strMediaFile);
            File fileCameraTemp = new File(strCameraTempFile);
            File fileCameraResult = new File(strMediaFile);
            Uri sharedFileUri = FileProvider.getUriForFile(this, "de.xyz.app.fileprovider", fileCameraResult);
            InputStream is = getContentResolver().openInputStream(sharedFileUri);
            FileOutputStream fos = new FileOutputStream(fileCameraTemp);

            byte[] buf = new byte[1024];
            int len;
            while ((len = is.read(buf)) > 0) {
                fos.write(buf, 0, len);
            }
            is.close();
            fos.close();
    ....
}

我正在尝试将视频文件存储到本地可访问的文件中。

getRealPathFromURI 函数:

public String getRealPathFromURI(Context context, Uri contentUri) {
  Cursor cursor = null;
  try {
    String[] proj = { MediaStore.Images.Media.DATA };
    cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
  } finally {
    if (cursor != null) {
      cursor.close();
    }
  }
}

所以我得到的日志输出如下:

App: onActivityResult
D App: CAMERA_REQUEST_VIDEO
D App: No valid strCameraTempFile:/storage/emulated/0/cameraresult.mp4 -> using data
D App: got data
D App: got link:content://media/external/video/media/17877 File:/storage/emulated/0/DCIM/Camera/20230824_113912.mp4
W System.err: java.io.FileNotFoundException: open failed: EACCES (Permission denied)
W System.err:   at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
W System.err:   at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
W System.err:   at androidx.core.content.FileProvider.openFile(FileProvider.java:566)
W System.err:   at android.content.ContentProvider.openAssetFile(ContentProvider.java:1733)
W System.err:   at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1915)
W System.err:   at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1982)
W System.err:   at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:511)
W System.err:   at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1701)
W System.err:   at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1517)
W System.err:   at android.content.ContentResolver.openInputStream(ContentResolver.java:1201)
W System.err:   at de.versicherungsmarkt.vemamaklerapp.VemaMaklerApp.onActivityResult(VemaMaklerApp.java:484)
W System.err:   at android.app.Activity.dispatchActivityResult(Activity.java:8300)
W System.err:   at android.app.ActivityThread.deliverResults(ActivityThread.java:5353)
W System.err:   at android.app.ActivityThread.handleSendResult(ActivityThread.java:5401)
W System.err:   at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
W System.err:   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
W System.err:   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
W System.err:   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
W System.err:   at android.os.Handler.dispatchMessage(Handler.java:107)
W System.err:   at android.os.Looper.loop(Looper.java:237)
W System.err:   at android.app.ActivityThread.main(ActivityThread.java:8167)
W System.err:   at java.lang.reflect.Method.invoke(Native Method)
W System.err:   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
W System.err:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

我的 Android 清单中有一个 Provider:

    <provider android:name="androidx.core.content.FileProvider" android:authorities="de.xyz.app.fileprovider" android:exported="false" android:grantUriPermissions="true">

        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/>
    </provider>

具有以下配置:

<?xml version="1.0" encoding="utf-8"?>
<paths>
     <external-files-path name="images" path="Pictures"/>
     <cache-path name="cache" path="."/>
     <files-path name="files" path="."/>
     <external-path name="external" path="." />
     <cache-path name="cache" path="." />
     <external-cache-path name="external_cache" path="." />
</paths>

我不知道该怎么做才能完成这项工作,希望有人可以帮助我

strCameraTempFile 是本地应用程序文件夹中的文件。

java android permissions camera provider
1个回答
0
投票

getRealPathFromURI 函数

删除该功能。

然后,替换:

            Uri sharedFileUri = FileProvider.getUriForFile(this, "de.xyz.app.fileprovider", fileCameraResult);
            InputStream is = getContentResolver().openInputStream(sharedFileUri);

与:

            InputStream is = getContentResolver().openInputStream(selectedMediaUri);

此时,将内容复制到标识为

fileCameraTemp
的文件系统路径的代码应该可以更好地工作。您还可以删除其余的
FileProvider
配置,以及现有代码中现在未使用的变量。

© www.soinside.com 2019 - 2024. All rights reserved.