You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android 11以下版本使用Gmail 2022.05.01.449051655版本无法通过FileProvider分享PDF文件的问题求助

解决Gmail 2022.05.01版本在Android 10/9无法附加FileProvider提供的PDF问题

我碰到过类似的Gmail兼容性问题,结合你的测试结果,这个问题确实是Gmail 2022.05.01.449051655版本在Android 10及以下系统的专属bug——旧版Gmail通过开启存储权限就能兼容FileProvider的URI,但新版即使开了权限也存在逻辑漏洞,无法正确读取FileProvider提供的PDF文件。下面给你几个可行的解决方案:

1. 显式给Gmail授予URI读取权限

有时候隐式的FLAG_GRANT_READ_URI_PERMISSION可能因为Gmail的权限逻辑调整没生效,针对Gmail包名单独授权能确保权限传递到位,修改你的代码如下:

Uri fileURI = FileProvider.getUriForFile(context, "com.fileprovider", mFile);
Intent intent = ShareCompat.IntentBuilder.from(this)
    .setStream(fileURI)
    .setType("application/pdf")
    .getIntent()
    .setAction(Intent.ACTION_SEND)
    .setDataAndType(fileURI, "application/pdf");

// 针对Gmail应用显式授予URI读取权限
PackageManager pm = getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resolveInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    if (packageName.contains("com.google.android.gm")) { // 匹配Gmail包名
        grantUriPermission(packageName, fileURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
}

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

这个方法强制给Gmail应用授予当前PDF URI的读取权限,绕过它自身的权限判断逻辑。

2. 尝试添加持久化URI权限(可选)

如果上面的方法无效,可以尝试加上FLAG_GRANT_PERSISTABLE_URI_PERMISSION,让权限在应用重启后依然有效,修改授权代码:

grantUriPermission(packageName, fileURI, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);

这个flag主要针对需要长期访问文件的场景,但部分低版本系统可能需要它来稳定权限传递。

3. 临时降级Gmail版本作为Workaround

既然你测试过2021.10.17及更早的Gmail版本在开启存储权限后能正常工作,可以在用户遇到问题时提示他们暂时降级Gmail,同时通过Google Play的Gmail应用反馈渠道向Google提交bug报告,推动官方修复。

4. 检查FileProvider配置的正确性

虽然你在Android 11上能正常工作,但低版本Android对FileProvider的配置要求更严格,再确认以下几点:

  • res/xml/file_paths.xml的路径配置是否匹配你的PDF存储位置,比如:
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- 如果文件存在内部存储的files/pdfs目录下 -->
        <files-path name="pdf_files" path="pdfs/"/>
        <!-- 如果是外部存储的应用私有目录 -->
        <external-files-path name="external_pdfs" path="pdfs/"/>
    </paths>
    
  • AndroidManifest中FileProvider的注册是否正确,确保android:grantUriPermissions="true"
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"/>
    </provider>
    

5. 尝试使用ACTION_SEND_MULTIPLE绕过bug

部分应用对ACTION_SEND_MULTIPLE的处理逻辑不同,你可以尝试用发送多个文件的Intent来绕过单个文件的bug:

Uri fileURI = FileProvider.getUriForFile(context, "com.fileprovider", mFile);
ArrayList<Uri> uris = new ArrayList<>();
uris.add(fileURI);

Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setType("application/pdf");
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);

// 同样加上显式授权Gmail的代码
PackageManager pm = getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resolveInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    if (packageName.contains("com.google.android.gm")) {
        grantUriPermission(packageName, fileURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
}

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

总结

这个问题的核心是新版Gmail在低版本Android上的兼容性bug,显式授权URI权限是最有效的临时修复方案,同时一定要向Google提交bug报告,推动官方解决。长期来看,等Google修复该版本的bug后,这个问题会自然消失。

内容的提问来源于stack exchange,提问作者Priyanka Bakkar

火山引擎 最新活动