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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:24:01