Issue
For some reason, the QR code for installing our app as a device owner stopped working on Android12 devices (the same QR codeworks perfectly on previous Android versions).
The error message we are getting is:
Can't set up device
Contact your IT admin for help
This is the JSON of the QR code
{
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION": "https://someurlthatworkforsure",
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION": true,
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM": "validCheckSumThatWasTestedAndDoesWorkOnAndroidPriodTo12",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME": "com.brand.name/com.brand.some.SomeClass"
}
I have done some googling but haven't found whats wrong with our QR code,
I have also tried setting PROVISIONING_SKIP_ENCRYPTION to false and removing it, the result is the same.
The CHECKSUM is valid, if I mess with it throws a different error...
Thanks in advance.
Solution
Well, I eventually solved it in the following way
You must add two more activities that will handle the new flow In both activities, you will have to set results and finish the activity
setResult(RESULT_OK, intent);
finish();
Note that I noticed that the new approach worked 100% on Android 12 (v31) but sometimes failed on Android 11 v30, so I made this solution conditional, its being enabled on Android 12+, by checking the following boolean provision_mode_compliance_enabled
, which is stored in XML resource files
ProvisioningModeActivity.java
package com.my.pkg;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
import androidx.appcompat.app.AppCompatActivity;
import com.my.pkg.R;
import java.util.List;
public class ProvisioningModeActivity extends AppCompatActivity {
private String EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES = "android.app.extra.PROVISIONING_ALLOWED_PROVISIONING_MODES";
private int PROVISIONING_MODE_FULLY_MANAGED_DEVICE = 1;
private int PROVISIONING_MODE_MANAGED_PROFILE = 2;
private String EXTRA_PROVISIONING_MODE = "android.app.extra.PROVISIONING_MODE";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_provisioning_mode);
Intent intent = getIntent();
int provisioningMode = PROVISIONING_MODE_FULLY_MANAGED_DEVICE;
List<Integer> allowedProvisioningModes = intent.getIntegerArrayListExtra(EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES);
if (allowedProvisioningModes != null) {
if (allowedProvisioningModes.contains(PROVISIONING_MODE_FULLY_MANAGED_DEVICE)) {
provisioningMode = PROVISIONING_MODE_FULLY_MANAGED_DEVICE;
} else if (allowedProvisioningModes.contains(PROVISIONING_MODE_MANAGED_PROFILE)) {
provisioningMode = PROVISIONING_MODE_MANAGED_PROFILE;
}
}
//grab the extras (might contain some needed values from QR code) and pass to AdminPolicyComplianceActivity
PersistableBundle extras = intent.getParcelableExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);
Intent resultIntent = getIntent();
if (extras != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
resultIntent.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, extras);
}
}
resultIntent.putExtra(EXTRA_PROVISIONING_MODE, provisioningMode);
setResult(RESULT_OK, resultIntent);
finish();
}
}
and
AdminPolicyComplianceActivity.java
package com.my.pkg;
import android.content.Intent;
import android.os.Bundle;
import com.my.pkg.R;
import androidx.appcompat.app.AppCompatActivity;
public class AdminPolicyComplianceActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_policy_compliance);
Intent intent = getIntent();
setResult(RESULT_OK, intent);
finish();
}
}
Manifest entries: notice that these activities are enabled conditional (continue reading till the end of the answer)
<activity
android:name="com.communitake.android.lib.deviceadmin.AdminPolicyComplianceActivity"
android:exported="true"
android:enabled="@bool/provision_mode_compliance_enabled"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<intent-filter>
<action android:name="android.app.action.ADMIN_POLICY_COMPLIANCE"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.communitake.android.lib.deviceadmin.ProvisioningModeActivity"
android:screenOrientation="portrait"
android:exported="true"
android:enabled="@bool/provision_mode_compliance_enabled"
android:theme="@style/Theme.AppCompat"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<intent-filter>
<action android:name="android.app.action.GET_PROVISIONING_MODE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
activity_get_provisioning_mode.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GetProvisioningModeActivity">
<Button
android:id="@+id/get_provisioning_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Provisioning Data"/>
</LinearLayout>
activity_policy_compliance.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PolicyComplianceActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Policy Compliance Screen"/>
</LinearLayout>
Last thing is adding bools.xml
to the values
and values-v31
folders, with the following content, note that the new flow better be enabled on Android 12 and higher
values folder
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="provision_mode_compliance_enabled">false</bool>
</resources>
values-v31 folder
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="provision_mode_compliance_enabled">true</bool>
</resources>
Answered By - Daniel
Answer Checked By - Robin (JavaFixing Admin)