简体   繁体   English

Android 以编程方式安装 .apk 文件

[英]Android install .apk file programmatically

I'm trying to do an autoupdate function, after a lot of search I've found solution for download .apk file from my server to my device But i'can't launch this file, window to prompt user for install open but close direct.我正在尝试执行自动更新功能,经过大量搜索,我找到了将 .apk 文件从我的服务器下载到我的设备的解决方案但我无法启动此文件,提示用户安装的窗口打开但关闭直接的。

this is my code这是我的代码

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);

I've tryed with a lot of combinaison of flags and Ident.Action like ActionInstallPackage我已经尝试了很多标志和 Ident.Action 的组合,比如 ActionInstallPackage

android version is 8.1安卓版本是8.1

thanks谢谢

I have wrote a code in with respect to Uri access exposure for targetSdkVersion >= 24 , please try it in yourself.我已经在编写了一个关于targetSdkVersion >= 24 Uri访问暴露的targetSdkVersion >= 24 ,请自己在尝试。

ApkInstaller.java安装程序.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);
        }
    }

}

manifest.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 res/xml/provider_paths.xml

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

Usage:用法:

ApkInstaller.installApplication(context, filePath);

STEP-1第1步

First Create xml file inside your res/xml/provider_paths.xml and then首先在 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>

STEP-2第2步

Add this in AndroidManifest.xml file将此添加到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 Final step STEP-3 最后一步

Add this in your Activity class将此添加到您的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);
                        }

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

Using FileProvider you can get other .extension file like capture image uri使用 FileProvider,您可以获得其他.extension文件,例如捕获图像uri

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

@r2b2s, same issue here with window closing immediately. @ r2b2s,此处相同的问题是立即关闭窗口。 Were you able to solve that issue 您能解决这个问题吗

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM