Android - 如何成为第一个接收WAP PUSH(MMS)的人

时间:2015-02-20 07:33:33

标签: android push broadcast mms wap

我想拦截接收彩信以启用移动数据。为此,我需要在任何其他应用程序之前拦截它们。

我已设置我的意图过滤器以接收具有最高优先级的WAP_PUSH_RECEIVED_ACTION广播。

但是,在Android文档(https://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html)中,有以下两个广播:

  • WAP_PUSH_DELIVER_ACTION(仅发送到默认短信应用)
  • WAP_PUSH_RECEIVED_ACTION(发送给所有应用)

请告诉我,首先发送了哪些广播(WAP_PUSH_DELIVER_ACTIONWAP_PUSH_RECEIVED_ACTION),您在哪里找到这些信息?

他们从哪里发送Android源代码?

以最高优先级收听WAP_PUSH_RECEIVED_ACTION是否让我成为第一个接收WAP PUSH广播的人?

由于

1 个答案:

答案 0 :(得分:4)

这个话题似乎不那么受欢迎! 我试着自己回答这个问题,然后发现了一些有趣的东西。

分析

短信和彩信接收主要在文件InboundSmsHandler.java中进行管理。 此文件以注释块开头,该注释块说明了SMS / MMS接收状态机。

以下是此评论的摘录及解释:

  1. 状态机以InboundSmsHandler.IdleState状态启动。
  2. SMSDispatcher收到来自广播的新短信时,它会调用dispatchNormalMessage(com.android.internal.telephony.SmsMessageBase),并转换为InboundSmsHandler.DeliveringState州。
  3. InboundSmsHandler.DeliveringState状态调用processMessagePart(InboundSmsTracker tracker)。在此方法中,如果SMS的目标端口号为SmsHeader.PORT_WAP_PUSH(换句话说,如果SMS是MMS),则会调用WapPushOverSms.dispatchWapPdu(byte[] pdu, BroadcastReceiver receiver, InboundSmsHandler handler)方法。
  4. dispatchWapPdu方法中,他们会调用InboundSmsHandler.dispatchIntent(Intent intent, String permission, int appOp, BroadcastReceiver resultReceiver, UserHandle user)。他们检查是否有默认的MMS应用程序,如果是这种情况,请将意图配置为仅发送到此应用程序。
  5. 代码:

    // Direct the intent to only the default MMS app. If we can't find a default MMS app
    // then sent it to all broadcast receivers.
    ComponentName componentName = SmsApplication.getDefaultMmsApplication(mContext, true);
    if (componentName != null) {
        // Deliver MMS message only to this receiver
        intent.setComponent(componentName);
        if (DBG) Rlog.v(TAG, "Delivering MMS to: " + componentName.getPackageName() +
                " " + componentName.getClassName());
    }
    
    handler.dispatchIntent(intent, permission, appOp, receiver, UserHandle.OWNER);
    
    1. dispatchIntent内,我们有我们正在寻找的内容,呼叫Context.sendOrderedBroadcastAsUser(...)。因此,正是这种方法将WAP_PUSH_DELIVER_ACTION广播作为有序广播发送。
    2. 此广播也由位于SmsBroadcastReceiver的{​​{1}}处理程序处理(默认应用和SmsBroadcastReceiver.onReceive(Context context, Intent intent))。在此处理程序中,处理InboundSmsHandler.java个案。意图更改为WAP_PUSH_DELIVER_ACTION,并通过WAP_PUSH_RECEIVED_ACTION方法再次广播。这一次,不仅涉及默认应用程序,还涉及所有感兴趣的应用程序。
    3. 代码:

      InboundSmsHandler.dispatchIntent(Intent intent, String permission, int appOp, BroadcastReceiver resultReceiver, UserHandle user)

      结论(对原始问题的快速回答)

      收到彩信后,@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Intents.SMS_FILTER_ACTION)) { // ... } else if (action.equals(Intents.SMS_DELIVER_ACTION)) { // ... } else if (action.equals(Intents.WAP_PUSH_DELIVER_ACTION)) { // Now dispatch the notification only intent intent.setAction(Intents.WAP_PUSH_RECEIVED_ACTION); intent.setComponent(null); // Only the primary user will receive notification of incoming mms. // That app will do the actual downloading of the mms. dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS, AppOpsManager.OP_RECEIVE_SMS, this, UserHandle.OWNER); } else { // ... } } 会先广播到默认应用,然后是WAP_PUSH_DELIVER_ACTION

      两个广播都是有序广播,这意味着可以使用优先级。

      嗯,这对我来说是一个坏消息,因为这也意味着我不能成为第一个收到彩信通知的人,并在通知MMS应用程序之前打开模态数据。

      啊,谷歌和Lollipop,你让事情变得更难:Android Issue 78084 - setMobileDataEnabled removed

      所以,我必须寻找另一种方法才能做到这一点。