简体   繁体   English

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

[英]Upgrading app in background using Device Policy Controller

I have a working DPC app which is the Device Owner. 我有一个工作正常的DPC应用程序,它是设备所有者。 I have tried this on two different Android 6.0.1 devices to rule out any device/manufacturer issues. 我已经在两个不同的Android 6.0.1设备上进行了尝试,以排除任何设备/制造商问题。

I used adb shell dpm set-device-owner com.example.dpc/.DpcDeviceAdminReceiver to make my DPC-app the owner. 我使用了adb shell dpm set-device-owner com.example.dpc/.DpcDeviceAdminReceiver来使我的DPC应用成为所有者。 After making it the owner it can correctly grant COSU permissions to another app, which convinces me that this has worked. 成为所有者后,它可以正确地将COSU权限授予另一个应用程序,这使我确信这已经起作用。 The command returned the response: 该命令返回了响应:

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

I want to use this app to install and upgrade another app, without user intervention (like Google Play does). 我想使用此应用程序来安装和升级另一个应用程序,而无需用户干预(就像Google Play一样)。

I am using the following proof-of-concept code: 我正在使用以下概念验证代码:

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

With the code above, and variants, I receive an com.example.dpc.intent.UPDATE intent containing an error: 使用上面的代码和变体,我收到一个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 correctly reports the size of the apk which is being streamed into the session.openWrite stream. Logcat正确报告正在流式传输到session.openWrite流中的apk的大小。

I have already looked at: 我已经看过了:

What am I doing wrong? 我究竟做错了什么?

The error was coming from the following Android 6.0.1 code in frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java . 错误是来自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;
    }
}

I checked the app which I was trying to install, and found that the FLAG_TEST_ONLY bit was set. 我检查了要安装的应用程序,发现已设置FLAG_TEST_ONLY位。 Why is Android Studio 3.0.0 setting FLAG_TEST_ONLY on APKs? 为什么Android Studio 3.0.0在APK上设置FLAG_TEST_ONLY?

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

相关问题 设备策略控制器 (DCP) 应用程序和系统应用程序之间有什么区别? - What is the Difference between a Device Policy Controller (DCP) app and a System App? 应用程序成为设备的背景 - App becomes background of the device 将Android Studio升级到1.4后,无法使用Device Chooser部署应用程序 - Unable to deploy app using Device Chooser after upgrading Android Studio to 1.4 在Android上更新设备所有者应用的政策 - Update policy on a device owner app on Android 如何为Android设备策略控制器(DPC)配置GCM - How configure GCM for an Android Device Policy Controller (DPC) 应用程序在后台时的GeoFence设备 - GeoFence Device when app is in background 删除应用程序,因为它违反了设备和网络滥用政策 - Removing App because it it violates the device and network abuse policy 使用签名的 apk 升级时未安装应用程序 - App not installed while upgrading using signed apk Android 设备所有者模式由应用程序签名使用平台密钥(或使用签名的应用程序自定义设备策略) - Android Device Owner Mode by App Signed with platform key (or use signed App for custom device policy) 如何使我的 Android 应用程序符合“后台位置策略” - How to make my Android app comply with the “Background Location Policy”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM