Saturday, November 26, 2016

Taming Android am command

In Android an intent can carry data of a certain mime type.
To test this feature, I had an App which sets up an IntentFilter, and then I would manually trigger it:

am broadcast -t text/xml -a my.action.START -d "file:///system/usr/share/mmc/settings.xml"

It did not work, so I had to read better about am options:

So I learned about FLAG_DEBUG_LOG_RESOLUTION (I also saw it in the sources). So I added "-t 8" as option.
Then I saw that the type used during the matching was Null, so I verified the binder transaction code:reading from binder tx data and writing tx data Here the writing:

ActivityManagerProxy
broadcastIntent()....
intent.writeToParcel(data, 0); // serializes the Intent
data.writeString(resolvedType); // separately adds the type


So the type has to be delivered separately, but am does not do it:

private void sendBroadcast() throws Exception {
Intent intent = makeIntent(UserHandle.USER_CURRENT);
IntentReceiver receiver = new IntentReceiver();
System.out.println("Broadcasting: " + intent);
// this is the fix null -> intent.getType()
mAm.broadcastIntent(null, intent, /* null */ intent.getType(), receiver, 0, null, null, mReceiverPermission,
android.app.AppOpsManager.OP_NONE, true, false, mUserId);
receiver.waitForFinish();
}