【问题标题】:Android install .apk file programmaticallyAndroid 以编程方式安装 .apk 文件
【发布时间】:2019-06-06 13:01:53
【问题描述】:

我正在尝试执行自动更新功能,经过大量搜索后,我找到了将 .apk 文件从我的服务器下载到我的设备的解决方案 但我无法启动此文件,提示用户安装的窗口打开但直接关闭。

这是我的代码

Java.IO.File file = new Java.IO.File(destination);

Android.Net.Uri apkURI = Android.Support.V4.Content.FileProvider.GetUriForFile(
                                  _context,
                                  _context.ApplicationContext.PackageName + ".provider", file);

 Intent promptInstall = new Intent(Intent.ActionView);
 //promptInstall.SetDataAndType(apkURI, "application/vnd.android.package-archive");
 promptInstall.SetData(apkURI);

 promptInstall.AddFlags(ActivityFlags.NewTask);
 promptInstall.AddFlags(ActivityFlags.GrantReadUriPermission);
         _context.GrantUriPermission(_context.ApplicationContext.PackageName, apkURI, ActivityFlags.GrantReadUriPermission);
_context.StartActivity(promptInstall);

我尝试了很多标志和 Ident.Action 的组合,例如 ActionInstallPackage

安卓版本是8.1

谢谢

【问题讨论】:

  • 我也有同样的问题,你解决了吗?

标签: android xamarin installation apk


【解决方案1】:

第 1 步

首先在您的 res/xml/provider_paths.xml 中创建 xml 文件 然后

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="files_root"
        path="Android/data/${applicationId}" />
    <external-path
        name="external_files"
        path="." />
</paths>

第二步

将此添加到 AndroidManifest.xml 文件中

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

<application>
 <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>
    </application>

STEP-3 最后一步

将此添加到您的 Activity 类中

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            Uri uri = FileProvider.getUriForFile(context,
                                    context.getApplicationContext().getPackageName() + ".provider", new File(apkFilePath));
                            Intent intent = new Intent(Intent.ACTION_VIEW);
                            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            intent.setDataAndType(uri, "application/vnd.android.package-archive");
                            startActivity(intent);

                        } else {
                            Intent intent = new Intent(Intent.ACTION_VIEW);
                            intent.setDataAndType(FileUtils.getFileToUri(BaseActivity.this, new File(apkFilePath)),
                                    "application/vnd.android.package-archive");
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                        }

注意: FileProvider 仅适用于 Android >= Nougat

使用 FileProvider 可以获取其他 .extension 文件,例如捕获图像 uri

Uri uri = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".provider", new File(imageFilePath));

【讨论】:

    【解决方案2】:

    我在写了一个代码,用于Uri访问曝光targetSdkVersion &gt;= 24,请自己在试试。

    ApkInstaller.java

    import android.content.ActivityNotFoundException;
    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Build;
    import android.support.v4.content.FileProvider;
    import android.util.Log;
    
    import java.io.File;
    
    public class ApkInstaller {
    
        public static void installApplication(Context context, String filePath) {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uriFromFile(context, new File(filePath)), "application/vnd.android.package-archive");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            try {
                context.startActivity(intent);
            } catch (ActivityNotFoundException e) {
                e.printStackTrace();
                Log.e("TAG", "Error in opening the file!");
            }
        }
    
        private static Uri uriFromFile(Context context, File file) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
            } else {
                return Uri.fromFile(file);
            }
        }
    
    }
    

    ma​​nifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="package.identifier">
    
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
        <application ... >
    
            ...
    
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="${applicationId}.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_paths" />
            </provider>
    
        </application>
    
    </manifest>
    

    res/xml/provider_paths.xml

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

    用法:

    ApkInstaller.installApplication(context, filePath);
    

    【讨论】:

    • @r2b2s:你测试了吗?
    • 谢谢,但我已经测试过这个解决方案,而且它对我来说不是 wotking apk 安装程序窗口已启动但立即关闭......我已经放弃了这个想法并尝试了一些新的东西,使用谷歌带有测试版本的游戏商店
    • 你在安卓中测试过吗>奥利奥?
    • @roghayehhosseini:我已经在Android N 上测试过,因为问题来自N 及更高版本,我认为在O 上没问题。
    • @aminography 对我来说它显示对话框There was a problem while parsing the packageandroidx.core.content.FileProvider 的安全异常我还添加了FLAG_GRANT_READ_URI_PERMISSION 标志