You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中Intent.ACTION_VIEW打开文件报“no file received”错误排查

使用Intent.ACTION_VIEW打开文件时出现“no file received”错误的解决方案

我在使用Intent.ACTION_VIEW打开文件时遇到了“no file received”错误,以下是相关信息及修复方案:


当前代码

重点关注fileOpener变量,SafeFiles为自定义类无需过多关注:

fileOpener = { file: File ->
    val uri: Uri = Uri.fromFile(file).normalizeScheme()
    val mime = MimeTypeMap
        .getSingleton()
        .getMimeTypeFromExtension(safeFile.extension.substring(1))
    Log.d(TAG, "mime = $mime")
    val intent = Intent(Intent.ACTION_VIEW)
    intent.data = uri
    intent.type = mime
    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
    Log.d(
        TAG, "data received:" +
                "uri = $uri\n" +
                "extension = ${safeFile.extension.substring(1)}\n" +
                "path = ${file.absolutePath}\n" +
                "size = ${file.totalSpace} "
    )
    CoroutineScope(Dispatchers.Main).launch {
        context!!.startActivity(intent)
    }
}

日志信息

2022-07-30 16:41:41.005 19233-19285/com.example.cryptile D/SafeViewerFragment: mime = image/png
2022-07-30 16:41:41.005 19233-19285/com.example.cryptile D/SafeViewerFragment: data received:uri = file:///storage/emulated/0/Cryptile/CRYPTILE_2022_07_30/.CACHE/aa854c7e-9fa4-4313-9750-cf58fde467b8.png
    extension = png
    path = /storage/emulated/0/Cryptile/CRYPTILE_2022_07_30/.CACHE/aa854c7e-9fa4-4313-9750-cf58fde467b8.png
    size = 119640424448

注:日志中totalSpace是存储分区总容量,并非文件实际大小,应使用file.length()验证文件有效性。文件确实存在且可通过系统文件管理器打开,因此问题出在FileProvider的使用上。

Manifest配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cryptile">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.USE_BIOMETRIC" />

    <application
        android:name=".app_data.AppApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.CRYPTILE">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.cryptile.fileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>
    </application>
</manifest>

filepaths.xml配置

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="/storage/emulated/0"
        path="." />
</paths>

问题根源

你当前用Uri.fromFile(file)生成的是file://格式Uri,Android 7.0(API 24)及以上版本中,这种Uri无法直接共享给其他应用——其他应用没有权限访问该路径,因此出现“no file received”错误。虽然已配置FileProvider,但并未实际使用它生成合法的content://格式Uri。

修复步骤

1. 修改Uri生成逻辑,使用FileProvider

替换Uri.fromFile(file)为FileProvider生成content://Uri,并给Intent添加权限标记,确保目标应用能读取文件。

2. 修正filepaths.xml的name属性

name是路径别名,无需写完整路径,避免冲突。

3. 合并Intent的data和type设置

分开设置intent.data和intent.type可能导致冲突,建议用setDataAndType统一设置。

修改后的代码

fileOpener = { file: File ->
    val mime = MimeTypeMap
        .getSingleton()
        .getMimeTypeFromExtension(safeFile.extension.substring(1))
    Log.d(TAG, "mime = $mime")
    // 使用FileProvider生成合法的content:// Uri
    val uri: Uri = FileProvider.getUriForFile(
        context!!,
        "com.example.cryptile.fileProvider", // 与Manifest中authorities保持一致
        file
    )
    val intent = Intent(Intent.ACTION_VIEW)
    // 统一设置data和type,避免冲突
    intent.setDataAndType(uri, mime)
    // 添加权限标记,允许目标应用读取文件
    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
    Log.d(
        TAG, "data received:" +
                "uri = $uri\n" +
                "extension = ${safeFile.extension.substring(1)}\n" +
                "path = ${file.absolutePath}\n" +
                "size = ${file.length()} " // 改用file.length()获取实际文件大小
    )
    CoroutineScope(Dispatchers.Main).launch {
        context!!.startActivity(intent)
    }
}

修正后的filepaths.xml

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

内容的提问来源于stack exchange,提问作者Vaishnav Kanhirathingal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:48:30