Xamarin.Forms(Android)编程实现APK自动安装的方案咨询
Xamarin.Forms(Android) 实现APK安装的可行方案
问题根因
你之前的代码有三个核心问题:
- OpenApk方法使用了安卓专属API,不能放在共享层的App.xaml.cs中,必须通过DependencyService在安卓端实现
- 旧版Android.Support包已被Xamarin.Android淘汰,需替换为AndroidX对应的FileProvider
- 缺少必要的权限配置和FileProvider路径声明
具体实现步骤
1. 共享层定义安装服务接口
在共享项目中新增IInstaller.cs:
public interface IInstaller { void InstallApk(string filePath); }
2. 安卓端实现安装逻辑
在安卓项目中新增AndroidInstaller.cs,使用AndroidX的FileProvider替代旧版Support包:
[assembly: Dependency(typeof(AndroidInstaller))] namespace NoguianaNucleo.Droid { public class AndroidInstaller : IInstaller { public void InstallApk(string filePath) { var file = new Java.IO.File(filePath); if (!file.Exists()) return; Intent installIntent; if (Build.VERSION.SdkInt >= BuildVersionCodes.N) { var apkUri = AndroidX.Core.Content.FileProvider.GetUriForFile( Application.Context, $"{Application.Context.PackageName}.fileprovider", file); installIntent = new Intent(Intent.ActionView); installIntent.SetDataAndType(apkUri, "application/vnd.android.package-archive"); installIntent.AddFlags(ActivityFlags.GrantReadUriPermission); installIntent.AddFlags(ActivityFlags.NewTask); } else { var apkUri = Android.Net.Uri.FromFile(file); installIntent = new Intent(Intent.ActionView); installIntent.SetDataAndType(apkUri, "application/vnd.android.package-archive"); installIntent.SetFlags(ActivityFlags.NewTask); } Application.Context.StartActivity(installIntent); } } }
3. 配置安卓清单文件
打开安卓项目的Properties/AndroidManifest.xml,添加必要权限和FileProvider声明:
新增权限
<!-- 安卓8.0及以上安装未知来源APK必需权限 --> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <!-- 如果你下载APK需要网络/存储权限也一并加上 --> <uses-permission android:name="android.permission.INTERNET" />
在节点内添加FileProvider声明
<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>
4. 新增FileProvider路径配置
在安卓项目的Resources目录下新建xml文件夹,文件夹的生成操作设置为AndroidResource,在其中新增file_paths.xml:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 匹配应用内部存储根目录,对应你存放APK的路径 --> <files-path name="internal_apk" path="." /> </paths>
5. 下载完成后调用安装接口
修改共享层App.xaml.cs的下载完成回调:
private void OnFileDownloaded(object sender,DownloadEventArgs e) { if(e.FileSaved) { // 拼接你下载APK的实际存储路径 string apkPath = Path.Combine( System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "folder", "nucleo.apk"); DependencyService.Get<IInstaller>().InstallApk(apkPath); App.Current.MainPage.DisplayAlert("XF Downloader","文件保存成功,正在启动安装","关闭"); } else { App.Current.MainPage.DisplayAlert("XF Downloader","文件保存时出错","关闭"); } }
注意事项
- 安卓8.0及以上首次调用安装时会跳转至系统设置页,需用户手动允许当前应用的未知来源安装权限
- 不要直接用
Uri.Parse传入本地文件路径,安卓7.0以上禁止向其他应用暴露file://格式的Uri,必须通过FileProvider生成content://格式Uri - 你存储APK的路径是应用专属内部存储,无需申请额外读写权限即可访问
内容的提问来源于stack exchange,提问作者David Zomada
相关产品推荐
相关产品推荐

