Custom DPC QR Provisioning fails ("Something went wrong") on Lenovo (Android 15) & OnePlus, but works on Xiaomi & Vivo
Hi everyone,
We are developing a dedicated kiosk attendance application that runs on company-owned tablets. We are using Android Enterprise QR code enrollment during the factory-reset out-of-the-box setup wizard to provision our app as a fully managed Device Owner (DO).
What We Are Doing: We host our signed release APK on an HTTPS server and generate a standard Android Enterprise provisioning QR code with the following payload structure:
{
"android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME": "com.ciphus.biometric/com.ciphus.attendance.receiver.AttendanceDeviceAdminReceiver",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION": "https://our-domain.com/app_release.apk",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM": "<URL_SAFE_BASE64_SHA256_WITHOUT_PADDING>",
"android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED": true
}Where the Failure Happens & Device Discrepancy:
-
Xiaomi & Vivo Devices (Android 14/15): The QR enrollment succeeds without issue. The app downloads, provisions as Device Owner, and locks into kiosk mode properly.
-
Lenovo Tablet (TB311XU, Android 15) & OnePlus (Android 15/16): After scanning the QR code and connecting to Wi-Fi, the system transitions to the screen that says:
"Getting ready for work setup..."
While on this screen (before our application opens or executes), it abruptly fails with the generic modal:
"Something went wrong. Can't set up your device. Contact your IT department." (Offering only a "Reset" button).
What We Have Already Verified & Implemented:
- Provisioning Activities are Minimal & Non-blocking:
GetProvisioningModeActivity(android.app.action.GET_PROVISIONING_MODE): Handles the intent, returnsPROVISIONING_MODE_FULLY_MANAGED_DEVICE, callssetResult(RESULT_OK), andfinish()immediately. No network calls or heavy work.AdminPolicyComplianceActivity(android.app.action.ADMIN_POLICY_COMPLIANCE): CallssetResult(RESULT_OK)andfinish()immediately. No DPM calls, UI, or network calls are executed here.- All kiosk policies, lock task packages, and runtime permissions are deferred to
AttendanceDeviceAdminReceiver.onProfileProvisioningComplete().
- ABI Compatibility:
- Verified native libraries: our APK bundles both
arm64-v8aandarmeabi-v7a.
- Verified native libraries: our APK bundles both
- Optimized Package Size & Hosting:
- Slimmed the APK down from 179 MB to ~78 MB to eliminate any potential download timeouts.
- Hosted on valid HTTPS with
content-type: application/vnd.android.package-archiveand direct raw byte delivery (no HTML redirects or captchas).
- Checksum Precision:
- Computed SHA-256, encoded as URL-safe Base64 with padding (
=) stripped, and verified byte-for-byte against the remote file on the server.
- Computed SHA-256, encoded as URL-safe Base64 with padding (
Our Questions for the Community:
- Since the failure happens right on the "Getting ready for work setup..." screen, is Google's
ManagedProvisioningblocking unverified custom DPCs via Google Play Protect / Android Enterprise cloud verification on stock Google Setup Wizard builds? - Does an in-house custom DPC need to be enrolled with an approved EMM partner / published to a private Google Play Console to pass this setup phase on Android 15/16?
- Are there specific manifest flags or intent extras required for Android 15 ManagedProvisioning that OEM skins like MIUI/FuntouchOS overlook but Lenovo ZUI and OxygenOS strictly enforce?
Any guidance from anyone who has deployed custom DPCs on Android 15 would be greatly appreciated!
