Search code examples
androidnfcandroid-5.0-lollipopdevice-policy-manager

Activate a device owner using NFC on Android Lollipop


I am trying to set the device owner package on a device using NFC. The is mentioned in the Lollipop overview here:

To deploy and activate a device owner, you must perform an NFC data transfer from a programming app to the device while the device is in its unprovisioned state. This data transfer sends the same information as in the provisioning intent described in Managed provisioning.

The reason is once this is set you can use the screen pinning feature to lock the device in a kiosk mode. I have been able to test the this kiosk mode by manually setting the device owner by placing a device_owner.xml file to data/system/ on a rooted device.

I have never used NFC before so I may be way off but I came up with the following NdefMessage based on the info here:

Properties properties = new Properties();
properties.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, "com.my.package");
properties.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID, "MyWiFiSSID");
properties.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD, "WifiPassword");
properties.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM, "C9AD9E082457819B54CF76255A400375E4127112");
properties.setProperty(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION, "https://dl.dropboxusercontent.com/u/xxx/app-release.apk");


ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos);
out.writeObject(properties);
byte[] yourBytes = bos.toByteArray();
NdefRecord ndefRecord = NdefRecord.createMime(DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC, yourBytes);
NdefMessage msg = new NdefMessage(ndefRecord);

Sending this to a device that I have just restored with the Lollipop preview causes it to show:

Oops! Couldn't set up your device. Contact your IT department.

Its seems to be recognising the fact that it is receiving a provision request, but I do not think it is reading the properties I set, it does not try to connect the the wifi.


Solution

  • It appears you need to use the Properties.store to correctly create the bytes for the NdefRecord.

    Properties properties = new Properties();
    properties.setProperty(...);
    
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    OutputStream out = new ObjectOutputStream(bos);
    properties.store(out, "");
    byte[] bytes = bos.toByteArray();
    
    NdefMessage msg = new NdefMessage(NdefRecord.createMime(DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC, bytes));
    

    Currently, I'm having an issue with it downloading my APK and the checksum failing. Not at all sure why.