Java – Android NFC Device Owner Configuration : send custom properties. Is it possible?

Android NFC Device Owner Configuration : send custom properties. Is it possible?… here is a solution to the problem.

Android NFC Device Owner Configuration : send custom properties. Is it possible?

I am currently developing an app and am experiencing the following issues.

When using NFC for device owner configuration, I want to send a string that the new device owner application will use.

I know the standard MIME properties configured by the device owner and found here

This is a fragment that gives you a better idea of my problem. Note the “myCustomValue” property.

Properties properties = new Properties();
properties.put("myCustomValue", value);
properties.put(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, "com.example.some.app");
try {                    
    properties.store(stream, "NFC Provisioning");            
    ndefMessage = new NdefMessage(new NdefRecord[{NdefRecord.createMime(DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC, stream.toByteArray())});
} catch (IOException e) {                         

}

This code is inside

public NdefMessage createNdefMessage(NfcEvent event)

You can find a templatehere

If this is possible, I would also like to know how to retrieve that string value as soon as the configured application starts.

Solution

The code below should be what you’re looking for. For brevity, I’ve just set the package name plus two strings that will be sent to your DeviceAdminReceiver.

@Override
public NdefMessage createNdefMessage(NfcEvent event) {
    try {
        Properties p = new Properties();

p.setProperty(
                DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
                "com.example.some.app");

Properties extras = new Properties();
        extras.setProperty("Key1", "TestString1");
        extras.setProperty("Key2", "TestString2");
        StringWriter sw = new StringWriter();
        try{
            extras.store(sw, "admin extras bundle");
            p.put(DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE,
                    sw.toString());
            Log.d(TAG, "Admin extras bundle=" + p.get(
                    DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE));
        } catch (IOException e) {
            Log.e(TAG, "Unable to build admin extras bundle");
        }

ByteArrayOutputStream bos = new ByteArrayOutputStream();
        OutputStream out = new ObjectOutputStream(bos);
        p.store(out, "");
        final byte[] bytes = bos.toByteArray();

NdefMessage msg = new NdefMessage(NdefRecord.createMime(
                DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC, bytes));
        return msg;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

The next fragment will go into your DeviceAdminReceiver to receive “Admin Extras”… If you do not override onReceive, onProfileProvisioningComplete will need to be overwritten by the EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE processed there.

@Override
public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "onReceive " + intent.getAction());
    if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(intent.getAction())) {
        PersistableBundle extras = intent.getParcelableExtra(
                EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);
        Log.d(TAG, "onReceive Extras:" + extras.getString("Key1") + " / "  + extras.getString("Key2"));
    }
}

Related Problems and Solutions