当前位置: 首页 > 知识库问答 >
问题:

使用FileProvider时设置文件权限

洪鸿
2023-03-14

我的应用程序具有“附加文件”、“拍照”、“拍摄视频”等功能。我正在将文件Uri传递给一个新的Intent,但在Nougat中得到了FileUriExposedException。因此已修改代码以使用FileProvider。我的Content Uri很好,但当我尝试读取或上传文件/图片/视频时,我java.io.FileNotFoundException。我设置权限错误吗?还是需要以其他方式设置权限?

以下是我正在做的:

Android_清单。xml:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

provider\u路径。xml:

 <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="files" path="."/>
    <external-path name="external_files" path="."/>
    </paths>

主要活动。java:

/*
* Creating file uri to store image/video
*/
public Uri getOutputMediaFileUri() {

File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), Config.IMAGE_DIRECTORY_NAME);               

if (!mediaStorageDir.exists()) {
    try {
        mediaStorageDir.mkdirs();
        Log.d(TAG, "Created directory " + mediaStorageDir.getPath());
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

if (mediaStorageDir != null) {
    mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "IMG_1" + ".jpg");

    try {
        Uri photoURI = FileProvider.getUriForFile(MainActivity.this,BuildConfig.APPLICATION_ID + ".provider", mediaFile);

        return photoURI;
    } catch (IllegalArgumentException e) {
            Log.e("File Selector","The selected file can't be shared: " +mediaFile);         
    }
}
return null;
}

在应该OverrideUrlLoding(我设置Intent的地方)中:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("*/*");
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION );

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    intent.putExtra(Intent.EXTRA_MIME_TYPES,extraMimeTypes);
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
}
try {
    startActivityForResult(Intent.createChooser(intent, "Select a File to Upload"),PICKFILE_REQUEST_CODE);
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(getApplicationContext(), "Please install a File Explorer.",  Toast.LENGTH_SHORT).show();
}

在onActivityResult中:

case  PICKFILE_REQUEST_CODE:
    if (resultCode == RESULT_OK){
        Uri selectedFile = data.getData();
        try {
            filePath = getPath(this,selectedFile);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        System.out.println("PICKFILE_REQUEST " + filePath);
        if(filePath != null){
            new UploadFileToServer().execute();
        }else{
            Toast.makeText(getApplicationContext(), " Please select from  File Explorer or Gallery ",  Toast.LENGTH_SHORT).show();
        }
    }

在Android监视器中,我的输出显示I/System。输出:PICKFILE\u请求/存储/32CF-12FE/DCIM/Camera/20170711\u 161710。我想这意味着内容Uri是正确的

但是,我无法上传文件java。io。FileNotFoundException:/storage/32CF-12FE/DCIM/Camera/20170711\u 161710。jpg:open失败:EACCES(权限被拒绝)

这是否意味着我的权限设置不正确?我该如何纠正这一点。

共有1个答案

江衡
2023-03-14

您的代码看起来很好,但不是通过FileProvider获取文件URI,而是使用文件的绝对路径。使用您的媒体文件,通过媒体文件获得绝对路径。getAbsolutePath()。

这将返回一个字符串,您可以使用该字符串读取文件。

 类似资料:
  • 用户在轻推上传文件时,考虑到对文件的传播有着不同的考量,因此在发送文件时也可以对文件的转发和下载权限进行设置。转发权限可选择:可转发、仅在企业内转发、不可转;下载权限可设置:可下载和不可下载。 例如,当文件为企业内的重要文件,仅希望企业内员工可见,不希望外传时,则可以设置文件为仅在企业内转发,不可下载;设置后,则该文件只能在企业内分享,文件可以支持在线预览,不可下载,并且将加上阅读者的名字和手机号

  • 但是,执行这一行给了我(为了保护无辜者而改变了名字): 应用程序A在清单文件中有以下内容: filePaths.xml具有: 文件最终的实际路径是: 在这一点上,我被难住了。我不知道为什么不能授予我在同一个应用程序中创建的文件的权限。所以我的问题是:为什么我会得到这个异常,我如何才能成功地授予应用程序B的权限?

  • 问题内容: 创建用户AD帐户时,我正在使用Python创建一个新的个人文件夹。正在创建文件夹,但权限不正确。Python可以将用户添加到新创建的文件夹并更改其权限吗?我不确定从哪里开始编码。 问题答案: 您需要模块,它是pywin32的一部分。这是做您想做的事情的示例。 该示例为该文件创建了一个新的DACL并替换了旧的DACL,但是修改现有的DACL很容易。您需要做的就是从安全描述符中获取现有的D

  • 我正在尝试使用文件提供商共享存储在我的应用程序内部存储器的原始文件夹中的MP3文件,并允许用户使用他们选择的音频收听应用程序打开共享的MP3文件。 然而,在我编写的代码中,当我尝试使用附加的内容URI作为数据执行意图时,会出现FileNotFoundException。这会导致FileProvider系统的所有其他方面出现故障。 我创建了一个MediaPlayer,让它毫无问题地打开了我想要共享的

  • 问题内容: 我正在使用拥有者设置为的Apache Web服务器。我永远都不知道文件权限的最佳做法是什么,例如,当我创建新的Laravel 5项目时。 Laravel 5要求文件夹可写。我发现了很多不同的方法可以使其正常工作,而我通常以递归方式使其成为chmod。我知道这不是最好的主意。 官方文件说: Laravel可能需要配置一些权限:Web服务器中的文件夹, 并且需要Web服务器进行写访问。 这

  • 我使用的Apache Web服务器的所有者设置为。我从来不知道什么是文件权限的最佳实践,例如当我创建新的Laravel5项目时。 Laravel 5要求文件夹是可写的。我发现了许多不同的方法来使其工作,我通常以递归地使其chmod结束。我知道这不是最好的主意。 官方文件说: Laravel可能需要配置某些权限:和中的文件夹需要web服务器的写访问权限。 这是否意味着web服务器也需要访问和文件夹本