【问题标题】:How do I intercept a rich communication message on Android如何在 Android 上截获丰富的通信消息
【发布时间】:2016-04-30 10:33:22
【问题描述】:

我想截获 Rich Communication 消息(在 Vodafone 等某些网络上称为 Chat)。我已经使用意图过滤器和广播接收器成功地实现了一个 SMS 接收器,效果很好。但是,如果 SMS 是富通信消息,则接收者永远不会被调用。

在我的清单中:

<receiver
    android:name=".IncomingSMS"
    android:enabled="true"
    android:exported="true">
    <intent-filter android:priority="999">
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

我的广播接收器看起来像这样:

public class IncomingSMS extends WakefulBroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Retrieves a map of extended data from the intent.
        final Bundle bundle = intent.getExtras();

        if (bundle != null)
        {
            final Object[] pdusObj = (Object[]) bundle.get("pdus");

            SmsMessage currentMessage;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            {
                String format = bundle.getString("format");
                currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[0], format);

            }
            else
            {
                //noinspection deprecation
                currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[0]);
            }

            String number = currentMessage.getDisplayOriginatingAddress();

            Intent serviceintent = new Intent(context, ChargingMonitorService.class);
            serviceintent.putExtra(NUMBER, number);
            startWakefulService(context, serviceintent);

        } // bundle is null
    }
}

这一切都很完美,除非文本消息是富通信(或聊天)消息,否则永远不会调用 onReceive()。

Android 文档中没有任何内容,所以我假设它是供应商特定的意图,但它是什么?

【问题讨论】:

  • RCS 确实与 SMS 没有任何关系,因此您的 Receiver 永远不会为这些而开火。您可以查看几个适用于 Android 的开源 RCS 实现,但它比处理简单的文本消息要复杂得多。
  • 虽然 RCS 与 SMS 不同,但它在 Vodafone 上的三星手机上的相同默认消息应用程序中处理。我不知道,但我假设它不是三星独有的功能。您可以在气泡中看到一些消息带有“SMS”,而有些消息带有“Chat”。 Android 开发人员文档中没有任何内容,因此我怀疑这将是供应商特定的意图,可能仅适用于特定设备,但我仍然想知道它们是什么。我只对检测发件人详细信息感兴趣,因此我不需要更多涉及的代码来完全解释消息。

标签: android broadcastreceiver sms chat intentfilter


【解决方案1】:

经过一些逆向工程,我找到了三星设备的答案。我在有根三星设备上查看了 Messages 应用程序的清单以查找意图。然后我设置了自己的接收器并检查了 Bundle extras 是否有任何有用的数据。

在清单中:

    <receiver
        android:name=".RCSReceiver"
        android:permission="com.samsung.rcs.permission.RCS_APP_PERMISSION"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <category android:name="com.samsung.rcs.framework.instantmessaging.category.ACTION"/>
            <category android:name="com.samsung.rcs.framework.instantmessaging"/>
            <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_INVITATION"/>
            <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_INSERTED"/>
            <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_UPDATED"/>
        </intent-filter>
    </receiver>

附加权限:

<uses-permission android:name="com.samsung.rcs.im.READ_PERMISSION"/>

接收方代码如下所示:

public class RCSReceiver extends BroadcastReceiver
{
    private static final String RECEIVE_CHAT_INVITATION = "com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_INVITATION";
    private static final String RECEIVE_PARTICIPANT_UPDATED = "com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_UPDATED";
    private static final String RECEIVE_PARTICIPANT_INSERTED = "com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_INSERTED";
    private Logger log = LoggerFactory.getLogger(MainActivity.class);

    @Override
    public void onReceive(Context context, Intent intent)
    {
        log.debug("RCS Receiver");
        String action = intent.getAction();

        Bundle bundle = intent.getExtras();
        if(bundle != null)
        {
            if (RECEIVE_PARTICIPANT_UPDATED.equals(action) || RECEIVE_PARTICIPANT_INSERTED.equals(action))
            {
                String participant = bundle.getString("participant");
                if (participant != null)
                {
                    String number = participant.substring(4); // get the string after "tel:"
                    log.debug("Chat number is: " + number);
                }
            }
            else if (RECEIVE_CHAT_INVITATION.equals(action))
            {
                String subject = bundle.getString("subject");
                if(subject != null)
                {
                    log.debug("Chat subject: " + subject);
                }
            }
        }
    }
}

在“participant”extra 中,电话号码以“tel:”为前缀,消息文本在主题包中。

当然,这仅适用于三星设备,并且由于其未发布的 API 显然可能会在没有通知的情况下进行更改,因此它可以工作多长时间,或者它是否适用于三星的所有 Android 版本。但是,它达到了我拦截传入聊天号码的目的。

完整的操作列表如下,但是只有上面显示的两个在捆绑附加功能中有任何有用的东西。其他意图的额外数据位于 Parcels 中,需要在逆向工程中付出更多努力。

    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_TYPING_NOTIFICATION"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_CLOSED"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_NEW_MESSAGE"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.DELETE_MESSAGES_RESPONSE"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.DELETE_CHATS_RESPONSE"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_CHAT_INVITATION"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.SEND_MESSAGE_RESPONSE"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_MESSAGE_NOTIFICATION_STATUS"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_SEND_MESSAGE_RESPONSE"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.ADD_PARTICIPANTS_RESPONSE"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_MESSAGE_INSERTED"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_INSERTED"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.RECEIVE_PARTICIPANT_UPDATED"/>
    <action android:name="com.samsung.rcs.framework.instantmessaging.action.GET_IS_COMPOSING_ACTIVE_URIS_RESPONSE"/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    相关资源
    最近更新 更多