Android 使用设备策略控制器在后台升级应用程序

Android 使用设备策略控制器在后台升级应用程序,android,device-policy-manager,android-6.0.1-marshmallow,Android,Device Policy Manager,Android 6.0.1 Marshmallow,我有一个可用的DPC应用程序,它是设备所有者。我已经在两个不同的安卓6.0.1设备上尝试过,以排除任何设备/制造商问题 我使用了adb shell dpm set device owner com.example.dpc/.DpcDeviceAdminReceiver使我的dpc应用程序成为所有者。在使其成为所有者之后,它可以正确地向另一个应用程序授予COSU权限,这让我确信这是有效的。该命令返回了响应: Success: Device owner set to package com.exam

我有一个可用的DPC应用程序,它是设备所有者。我已经在两个不同的安卓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);
    }
}
Logcat正确地报告了流入
会话.openWrite
流的
apk
的大小

我已经看过:

  • gradle版本-我使用的是Android Studio和gradle v3.0.0,而不是一个不稳定的版本
  • 从res/raw
    apk
    文件复制的字节数:1418604,这是正确的
  • 清单-没有testOnly属性

我做错了什么?

错误来自
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\u TEST\u ONLY

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