设备所有者Android应用程序的OTA更新(Kiosk模式)



我可以通过这里提到的NFC制作我的应用程序,即设备所有者应用程序。现在我想通过"空中传送"更新我的应用程序,但我找不到一个不支持的方法。

正如这里提到的,谷歌为企业开发应用程序提供了许多选择,但没有提供通过OTA更新应用程序的方法。

正在寻找解决方案。

这只是猜测,因为我自己从未尝试过使用包安装程序API:

您可以尝试为设备所有者应用程序设置安装程序包(使用PackageManager.setInstallerPackageName())。此安装程序包需要是一个单独的APK,使用与设备所有者APK相同的证书进行签名。

getPackageManager().setInstallerPackage("<device.owner.package.name>", "<installer.package.name>");

从安装程序APK,您可以使用PackageInstaller准备更新:

PackageInstaller pi = getPackageManager().getPackageInstaller();
int sessId = pi.createSession(new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));
PackageInstaller.Session session = pi.openSession(sessId);
OutputStream out = session.openWrite("app");
// .. write updated APK file to out
session.fsync(out);
session.commit(...);
session.close();

不过,我不确定这是否会悄悄地安装你的更新(或者是否以我预期的方式工作)。

创建一个服务以进行后台检查以进行更新。如果更新可用,请下载apk文件并将其写在一些类似sdcard的地方。等待几秒钟以完全刷新写入。然后调用以下代码来安装新的apk。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");
startActivity(intent);

fileName是sd卡上新apk文件的路径。

您可以使用Play Store为您的应用程序提供更新:

  1. 通过NFC提供设备所有者应用程序,就像您已经做的那样。

  2. 在Play Store上提供设备所有者应用程序的更新版本(相同的软件包名称、相同的签名、更高的版本号)。

  3. 在设备上的Play Store应用程序中,搜索应用程序的Play Store版本并安装更新。

  4. 在Play Store中激活设备所有者应用程序的自动更新(在应用程序的Play Store页面上,单击菜单(三个点)并激活自动更新复选框。

对于供应阶段来说,这是相当大的工作量,但设备应该会自动接收未来的更新。

我想你可能想成为EMM/MDM合作伙伴应用程序——它类似于设备所有者应用程序,但具有增强的权限和API。通常,像Samsung/HTC这样的原始设备制造商为MDM合作伙伴应用程序提供隐藏的API,用于升级应用程序。我不确定Android for Work是否也提供了这个api。

例如:OEM提供了一个名为updatePackage(StringpackageName)的api,设备上的MDM客户端可以使用它来更新包。您也可以使用此API更新设备所有者应用程序。

我偶然发现了这个问题,想补充一下,评论中链接中的问题答案已经扩展,现在可以静默安装应用程序,只要你的应用程序是设备所有者:

https://stackoverflow.com/a/37153867/7173050

以下是Android 6.0及以上版本的部分:一旦您的应用程序获得设备所有者权限,我们就可以在无需任何用户干预的情况下静默安装、卸载和更新。

public static boolean installPackage(Context context, InputStream in, String packageName) throws IOException {
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
        PackageInstaller.SessionParams.MODE_FULL_INSTALL);
    params.setAppPackageName(packageName);
    // set params
    int sessionId = packageInstaller.createSession(params);
    PackageInstaller.Session session = packageInstaller.openSession(sessionId);
    OutputStream out = session.openWrite("COSU", 0, -1);
    byte[] buffer = new byte[65536];
    int c;
    while ((c = in.read(buffer)) != -1) {
        out.write(buffer, 0, c);
    }
    session.fsync(out);
    in.close();
    out.close();
    session.commit(createIntentSender(context, sessionId));
    return true;
}

private static IntentSender createIntentSender(Context context, int sessionId) {
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
             context, sessionId, new Intent(ACTION_INSTALL_COMPLETE), 0);
    return pendingIntent.getIntentSender();
}

卸载:

String appPackage = "com.your.app.package";
Intent intent = new Intent(getActivity(), getActivity().getClass());
PendingIntent sender = PendingIntent.getActivity(getActivity(), 0, intent, 0);
PackageInstaller mPackageInstaller = getActivity().getPackageManager().getPackageInstaller();
mPackageInstaller.uninstall(appPackage, sender.getIntentSender());

最后但同样重要的是链接:https://github.com/android/platform_frameworks_base/blob/marshmallow-release/services/core/java/com/android/server/pm/PackageInstallerSession.java

相关内容

  • 没有找到相关文章

最新更新