在VS2019中基于.NET Standard2.1、Android目标框架API28的Xamarin.Forms项目中使用FileProvider安装存储目录APK时的问题求助
解决Xamarin.Forms中FileProvider找不到及APK安装问题
我刚碰到过类似的情况,你的问题根源在于旧的Android Support库和.NET Standard项目不兼容,而且从Android 9(API28)开始,Google已经推荐使用AndroidX替代旧的Support库了。咱们一步步来解决:
1. 迁移到AndroidX(关键步骤)
旧的Xamarin.Android.Support.Compat包只支持MonoAndroid目标框架,不兼容.NET Standard,所以必须切换到AndroidX:
- 右键你的Android项目 → 选择Migrate to AndroidX,VS会自动帮你替换所有旧Support库引用为对应的AndroidX库,同时更新相关配置。
2. 引入正确的FileProvider命名空间
把原来的错误命名空间:
using Android.v4.content.FileProvider;
替换为AndroidX的命名空间:
using AndroidX.Core.Content;
3. 配置AndroidManifest.xml中的FileProvider
在<application>标签内添加FileProvider的配置,这是Android要求的安全机制:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
${applicationId}会自动替换成你的App包名,不用手动写死exported="false"必须设置为false,因为FileProvider不能对外暴露grantUriPermissions="true"允许临时授权其他应用访问这个URI
4. 创建文件路径配置文件
在你的Android项目的Resources文件夹下新建xml子文件夹(如果没有的话),然后创建file_paths.xml文件,内容如下(根据你的APK存储位置调整):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 如果APK存在App的外部存储目录,用这个 --> <external-files-path name="apk_files" path="." /> <!-- 如果存在公共存储目录,比如Downloads,用这个 --> <!-- <external-public-path name="public_apk" path="Download" /> --> </paths>
name是自定义的别名,path是要共享的子目录,.表示整个目录
5. 修正APK安装代码
你原来的代码有个小错误:GetUriForFile的第三个参数应该是Java.IO.File对象,不是字符串路径。修正后的代码如下:
Java.IO.File file = new Java.IO.File(filepath); if (Build.VERSION.SdkInt >= BuildVersionCodes.N) { // 使用AndroidX的FileProvider Android.Net.Uri URIAPK = AndroidX.Core.Content.FileProvider.GetUriForFile( Android.App.Application.Context, $"{Android.App.Application.Context.PackageName}.fileprovider", file); Intent intS = new Intent(Intent.ActionInstallPackage); intS.SetData(URIAPK); // 必须添加NewTask标志,否则在后台启动会报错 intS.SetFlags(ActivityFlags.GrantReadUriPermission | ActivityFlags.NewTask); Android.App.Application.Context.StartActivity(intS); } else { Android.Net.Uri URIAPK = Android.Net.Uri.FromFile(file); Intent intS = new Intent(Intent.ActionView); intS.SetDataAndType(URIAPK, "application/vnd.android.package-archive"); intS.SetFlags(ActivityFlags.NewTask); Android.App.Application.Context.StartActivity(intS); }
备选方案(不迁移AndroidX)
如果暂时不想迁移到AndroidX,你可以把APK安装的逻辑放到Android项目的特定类(比如MainActivity的方法里,或者一个DependencyService的实现类),因为Android项目是MonoAndroid目标框架,支持安装Xamarin.Android.Support.Compat包。不过还是强烈推荐迁移到AndroidX,因为旧的Support库已经停止维护,后续会有更多兼容性问题。
内容的提问来源于stack exchange,提问作者Rai Micheal
相关产品推荐
相关产品推荐

