【问题标题】:Upgrading app in background using Device Policy Controller使用设备策略控制器在后台升级应用程序
【发布时间】:2017-10-30 16:54:37
【问题描述】:

我有一个有效的 DPC 应用程序,它是设备所有者。我已经在两个不同的 Android 6.0.1 设备上尝试过这个,以排除任何设备/制造商问题。

我使用adb shell dpm set-device-owner com.example.dpc/.DpcDeviceAdminReceiver 让我的 DPC 应用程序成为所有者。使其成为所有者后,它可以正确地将 COSU 权限授予另一个应用程序,这让我相信这已经奏效了。命令返回响应:

Success: Device owner set to package com.example.dpc
Active admin set to component {com.examplem.dpc/com.example.dpc.DpcDeviceAdminReceiver}

我想使用此应用安装和升级另一个应用,无需用户干预(就像 Google Play 一样)。

我正在使用以下概念验证代码:

void upgrade() {
    String apkFileName = "app_debug_2_0_0";

    PackageManager packageManger = getPackageManager();
    PackageInstaller packageInstaller = packageManger.getPackageInstaller();
    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
            PackageInstaller.SessionParams.MODE_FULL_INSTALL);
    params.setAppPackageName("com.example.dummy");
    try {
        Log.e(TAG, "apkFileName " + apkFileName);

        InputStream ins = getResources().openRawResource(
                getResources().getIdentifier(apkFileName,
                        "raw", getPackageName()));

        int sessionId = packageInstaller.createSession(params);
        PackageInstaller.Session session = packageInstaller.openSession(sessionId);
        OutputStream out = session.openWrite(apkFileName, 0, -1);

        final int bufsize = 4096;
        byte[] bytes = new byte[bufsize];

        int len = 1; // any value > 0
        int tot = 0;
        while (len > 0) {
            len = ins.read(bytes, 0, bufsize);
            Log.d(TAG, "len: " + len);
            if (len < 1) break;
            out.write(bytes, 0, len);
            tot += len;
            Log.d(TAG, "copied: " + tot);
        }
        ins.close();

        session.fsync(out);
        out.close();

        Log.e(TAG, "about to commit ");
        session.commit(PendingIntent.getBroadcast(this, sessionId,
                new Intent("com.example.dpc.intent.UPDATE"), 0).getIntentSender());
        Log.e(TAG, "committed ");
    } catch (IOException e) {
        Log.e(TAG, "Error installing package " + apkFileName, e);
    }
}

使用上面的代码和变体,我收到了一个包含错误的 com.example.dpc.intent.UPDATE 意图:

Intent { 
    act=com.example.dpc.intent.UPDATE 
    flg=0x10 
    cmp=com.example.dpc/.DpcUpdateReceiver 
    bqHint=4 
    (has extras) 
}
Bundle[
    android.content.pm.extra.STATUS=4, 
    android.content.pm.extra.PACKAGE_NAME=com.example.dummy,
    android.content.pm.extra.SESSION_ID=1055214117, 
    android.content.pm.extra.LEGACY_STATUS=-15, 
    android.content.pm.extra.STATUS_MESSAGE=INSTALL_FAILED_TEST_ONLY: installPackageLI
]

Logcat 正确报告了apk 的大小,该session.openWrite 流式传输。

我已经看过了:

我做错了什么?

【问题讨论】:

    标签: android device-policy-manager android-6.0.1-marshmallow


    【解决方案1】:

    错误来自frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java 中的以下 Android 6.0.1 代码。

    if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
        if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
            res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
            return;
        }
    }
    

    我检查了我尝试安装的应用程序,发现FLAG_TEST_ONLY 位已设置。 Why is Android Studio 3.0.0 setting FLAG_TEST_ONLY on APKs?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      • 2019-04-09
      相关资源
      最近更新 更多