I would like to intercept incomming MMS to enable mobile data. For that, I need to intercept them before any other app.
I have setup my intent filter to receive WAP_PUSH_RECEIVED_ACTION broadcasts with the highest possible priority.
But, in the Android documentation (https://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html), there are the two following broadcasts:
WAP_PUSH_DELIVER_ACTION(Only sent to default sms app)WAP_PUSH_RECEIVED_ACTION(Sent to all apps)
Please, can you tell me which of these broadcasts is sent first (WAP_PUSH_DELIVER_ACTION or WAP_PUSH_RECEIVED_ACTION) and where did you find this information ?
From where are them send in Android source code ?
Does listening for WAP_PUSH_RECEIVED_ACTION with the highest possible priority let me be the first to receive WAP PUSH broadcasts ?
Thanks
This topic seems to be not so popular! I tried to answer the question myself and I found something interesting.
Analysis
SMS and MMS reception are mainly managed in the file
InboundSmsHandler.java. This file starts with a comment block that explains the SMS/MMS receiving state machine.Here is an extract of this comment with explanations:
InboundSmsHandler.IdleStatestate.SMSDispatcherreceives a new SMS from the radio, it callsdispatchNormalMessage(com.android.internal.telephony.SmsMessageBase), which transitions toInboundSmsHandler.DeliveringStatestate.InboundSmsHandler.DeliveringStatestate,processMessagePart(InboundSmsTracker tracker)is called. Within this method, if the destination port number of the SMS isSmsHeader.PORT_WAP_PUSH(in other words if the SMS is an MMS), theWapPushOverSms.dispatchWapPdu(byte[] pdu, BroadcastReceiver receiver, InboundSmsHandler handler)method is called.dispatchWapPdumethod, they callInboundSmsHandler.dispatchIntent(Intent intent, String permission, int appOp, BroadcastReceiver resultReceiver, UserHandle user). They check if there is a default MMS app and if it's the case, configure the intent to only be delivered to this app.Code:
dispatchIntentwe have what we are looking for, the call toContext.sendOrderedBroadcastAsUser(...). So, it is this method that sends theWAP_PUSH_DELIVER_ACTIONbroadcast as an ordered broadcast.SmsBroadcastReceiver) by theSmsBroadcastReceiver.onReceive(Context context, Intent intent)handler located inInboundSmsHandler.java. Inside this handler, theWAP_PUSH_DELIVER_ACTIONcase is processed. The intent is changed toWAP_PUSH_RECEIVED_ACTIONand broadcasted again through theInboundSmsHandler.dispatchIntent(Intent intent, String permission, int appOp, BroadcastReceiver resultReceiver, UserHandle user)method. This time, not only the default app is concerned, but all interested apps.Code:
Conclusion (Quick answer to the original question)
When an MMS is received,
WAP_PUSH_DELIVER_ACTIONis broadcasted first to the default app followed by theWAP_PUSH_RECEIVED_ACTION.Both broadcasts are ordered broadcasts that means that priorities can be used.
Well, it's a bad news for me because it also means that I cannot be the first to be notified for an incoming MMS and turn on the modile data before the MMS app is notified.
Ahh Google, with Lollipop, you make the things harder for us : Android Issue 78084 - setMobileDataEnabled removed
So, I have to look for another way in order to do that.