简体   繁体   English

在后台以编程方式安装 APK

[英]Installing APK programmatically in background

I have scenario where I have to download apk in background and install it without prompting any dialog to user.我有一个场景,我必须在后台下载 apk 并安装它,而不向用户提示任何对话框。 However when I try to install it using below code但是,当我尝试使用以下代码安装它时

File file = new File(filename);
if(file.exists()){
    try {
        String command;
        command = "pm install -r " + filename;
        Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
        proc.waitFor();
        Config.debug("Apk installed");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

It ask for super user access.它要求超级用户访问。 Is there any way to install apk without super user and prompting to user?有没有办法在没有超级用户并提示用户的情况下安装 apk?

Is there any way to install apk without super user and prompting to user?有没有办法在没有超级用户并提示用户的情况下安装 apk?

Fortunately, no, for obvious security reasons.幸运的是,没有,出于明显的安全原因。

UPDATE : One exception is on Android 5.0+ devices, if you are using the device owner system, I think there are some APIs for installing packages that are available to device owner apps.更新:一个例外是在 Android 5.0+ 设备上,如果您使用的是设备所有者系统,我认为有一些 API 可用于安装设备所有者应用程序可用的软件包。 I haven't played with these yet, and it is unclear whether they would meet your needs anyway.我还没有玩过这些,目前还不清楚它们是否能满足你的需求。

I am asking this becoz the user base that I have, have never used app or device before我问这个是因为我拥有的用户群,以前从未使用过应用程序或设备

Then either do not give them this technology or teach them how to use this technology.然后要么不给他们这项技术,要么教他们如何使用这项技术。

You can silently install apps starting Android Marshmallow (find info here ).您可以静默安装启动 Android Marshmallow 的应用程序(在此处查找信息)。 You would have to be a device owner in order to accomplish the task.您必须是设备所有者才能完成任务。

You can find more help about device owner here .您可以在此处找到有关设备所有者的更多帮助。 Thanks to Florent Dupont.感谢弗洛伦特杜邦。

是的,您可以通过使用系统签名对应用程序进行签名来静默安装 apk 而无需生根。

You should first look into the Android's native Package Installer .您应该首先查看 Android 的原生Package Installer I think you just need to extract the required functionality.我认为您只需要提取所需的功能。


Specifially, if you look at this method and its OnClickListener:具体来说,如果您查看此方法及其 OnClickListener:

public void onClick(View v) {
    if(v == mOk) {
        ...
        startActivity(newIntent);
        finish();
    } else if(v == mCancel) {
        // Cancel and finish
        setResult(RESULT_CANCELED);
        finish();
    }
}

Then you may notice the InstallAppProgress class on where the actual installer is located and the final thing to do is to call the PackageManager 's installPackage(...) function.然后您可能会注意到实际安装程序所在位置的InstallAppProgress类,最后要做的是调用PackageManager的 installPackage(...) 函数。

public void initView() {
  ...
  pm.installPackage(mPackageURI, observer, installFlags, installerPackageName);
}

Next step is to inspect PackageManager which is an abstract class.下一步是检查PackageManager这是一个抽象类。 You will find that installPackage(...) function there.您会在那里找到 installPackage(...) 函数。 The bad news is that this is marked with @hide .坏消息是它被标记为@hide This means it's not directly available to external developers.这意味着它不能直接供外部开发人员使用。

/**
 * @hide
 **/
public abstract void installPackage(Uri packageUri, IPackageInstallObserver installObserver, int flags, String installerPackageName);

But you will be able to access the method with using reflection.但是您将能够使用反射访问该方法。

Summary概括

You will reflect it using yourContext.getPackageManager() .您将使用yourContext.getPackageManager()反映它。 Then you may call the installPackage(...) function.然后你可以调用 installPackage(...) 函数。

The following code calls the installation:以下代码调用安装:

try {
  getPackageManager().installPackage(packageUri, myObserver, PackageManager.INSTALL_REPLACE_EXISTING, "com.your.package.name");
} catch (Exception e) {
   Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}

For the whole thing to work you need to declare this to your manifest or the code will fail silently.为了使整个工作正常运行,您需要在清单中声明这一点,否则代码将静默失败。

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

to get this permission you must install the APK as system which requires ROOT.要获得此权限,您必须将 APK 安装为需要 ROOT 的系统。

however after you have installed the APK as system it seem to work WITHOUT ROOT.但是,在您将 APK 安装为系统后,它似乎无需 ROOT 即可工作。

To do this, i created a signed APK and pushed it on:为此,我创建了一个签名的 APK 并将其推送:

adb push C:\Users\Example01\Desktop\release\app-release.apk /system/priv-app/MyApp.apk

with this i copied it to /system/priv-app which requires write access this is why the ROOT required.有了这个,我将它复制到/system/priv-app这需要写访问这就是为什么需要 ROOT。

I tested it using the debug version and when i tried it, i got the SecurityException .我使用调试版本对其进行了测试,当我尝试时,我得到了SecurityException

Conclusion结论

You should use a rooted device to install that as an sytem priveligied app.您应该使用有根设备将其安装为系统特权应用程序。

Hope this helps :)希望这可以帮助 :)

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

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