android - 权限拒绝:读取 androidx.core.content.FileProvider uri 内容/小米特定

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

在我的 Android 应用程序中,一些日志按日期写入文件(例如,写入文件

20.06.2024.txt
),能够收集
zip
存档中的所有文件并通过应用程序共享/通过电子邮件发送。存档文件附在信件上,在所有设备上都没有任何问题,除了经过测试的 6 台设备之一 - Xiaomi。在此设备上,我在日志中看到错误:

Writing exception to parcel
 java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.own.vpn.provider/files/logs/VPN_logs.zip from pid=6231, uid=1000 requires the provider to be exported , or grantUriPermission()

我的提供商在清单中定义:

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

文件提供者路径

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="files" path="/" />
</paths>

分享意向的方法

override fun goToFileSharing(logFile: File, shareWith: ShareWith) {
        // i get correct uri: content://com.own.vpn.provider/files/logs/VPN_logs.zip
        val fileUri: Uri = FileProvider.getUriForFile(
            context,
            "${BuildConfig.APPLICATION_ID}$AUTHORITY_EXTENSION", // AUTHORITY_EXTENSION = ".provider"
            logFile
        )

        val fileType = if (logFile.extension == LOG_FILE_EXTENSION_TXT)
            FILE_TYPE_TXT
        else
            FILE_TYPE_ZIP

        openApplicationChooser(fileUri, fileType)
    }

    private fun openApplicationChooser(fileUri: Uri, fileType: String) {
        val intent = Intent(Intent.ACTION_SEND).apply {
            // E-mail attachment
            setDataAndType(fileUri, fileType)
            putExtra(Intent.EXTRA_STREAM, fileUri)
        }

        // Applications chooser
        val shareIntent = Intent.createChooser(
            intent,
            null
        ).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
        startActivity(context, shareIntent, null)
    }

UPD 打开选择器时出现的第一个错误。当我选择任何应用程序(例如 gmail)时 - 我收到另一个错误:

Failed to find provider info for com.own.vpn.provider
。但在其他设备上一切正常...

android android-contentprovider
1个回答
0
投票

错误是由于小米处理URI权限的方式导致的

尝试下面的代码:

  1. file_provider_paths.xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="logs" path="logs/"/>
</paths>
  1. 使用此功能
    goToFileSharing
override fun goToFileSharing(logFile: File, shareWith: ShareWith) {
    
    val fileUri: Uri = FileProvider.getUriForFile(
        context,
        "${BuildConfig.APPLICATION_ID}$AUTHORITY_EXTENSION", // AUTHORITY_EXTENSION = ".provider"
        logFile
    )

    val fileType = if (logFile.extension == LOG_FILE_EXTENSION_TXT)
        FILE_TYPE_TXT
    else
        FILE_TYPE_ZIP

    openApplicationChooser(fileUri, fileType)
}

private fun openApplicationChooser(fileUri: Uri, fileType: String) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        // E-mail attachment
        setDataAndType(fileUri, fileType)
        putExtra(Intent.EXTRA_STREAM, fileUri)
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }

    // Applications chooser
    val shareIntent = Intent.createChooser(
        intent,
        null
    ).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
    startActivity(context, shareIntent, null)
}

注意:确保 MIUI 优化不会干扰您的应用程序的行为。

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