【问题标题】:How to get phone numbers of MMS group conversation participants?如何获取彩信群聊参与者的电话号码?
【发布时间】:2018-09-05 13:32:46
【问题描述】:

我正在开发一个 Cordova 应用程序,该应用程序需要能够获取群组文本中涉及的电话号码列表。我正在为此查询content://mms/[id]/addr。我正在 Pixel 2 上进行测试,对于 2018 年 3 月 10 日之前的彩信,这工作正常。但是对于该日期或之后的消息,它会失败(返回为空)。我应该查询其他地址吗?还有其他想法吗?

【问题讨论】:

    标签: android mms


    【解决方案1】:

    使用content://mms/ 将为您提供彩信对话列表,使用content://mms-sms/conversations 将为您提供第一个或第二个,如果其中任何一个不起作用,您可以尝试两者

    所以首先你必须只使用

    获得一个彩信列表
    ContentResolver contentResolver = getContentResolver();
    final String[] projection = new String[]{"_id", "ct_t"};
    Uri uri = Uri.parse("content://mms-sms/conversations");
    Cursor query = contentResolver.query(uri, projection, null, null, null);
    if (query.moveToFirst()) {
        do {
            String itemId = query.getString(query.getColumnIndex("_id"));
            int getRowID = Integer.parseInt(itemId);        
            String string = query.getString(query.getColumnIndex("ct_t"));
            if ("application/vnd.wap.multipart.related".equals(string)) {
                // this item is MMS so get the number using function getAddressNumber and log it 
                Log.d("number","address/number:" + getAddressNumber(getRowID));
    
            } else {
                // item is sms do nothing                 
            }
        } while (query.moveToNext());
    }
    
    
    private String getAddressNumber(int id) {
        String selectionAdd = new String("msg_id=" + id);
        String uriStr = MessageFormat.format("content://mms/{0}/addr", id);
        Uri uriAddress = Uri.parse(uriStr);
        Cursor cAdd = getContentResolver().query(uriAddress, null,
            selectionAdd, null, null);
        String name = null;
        if (cAdd.moveToFirst()) {
            do {
                String number = cAdd.getString(cAdd.getColumnIndex("address"));
                if (number != null) {
                    try {
                        Long.parseLong(number.replace("-", ""));
                        name = number;
                    } catch (NumberFormatException nfe) {
                        if (name == null) {
                            name = number;
                        }
                    }
                }
            } while (cAdd.moveToNext());
        }
        if (cAdd != null) {
            cAdd.close();
        }
        return name;
    }
    

    如果上面的函数 getAddressNumber 不起作用,你也可以试试这个,稍作改动

    public static String getMMSAddress(Context context, String id) {
        String addrSelection = "type=137 AND msg_id=" + id;
        String uriStr = MessageFormat.format("content://mms/{0}/addr", id);
        Uri uriAddress = Uri.parse(uriStr);
        String[] columns = { "address" };
        Cursor cursor = context.getContentResolver().query(uriAddress, columns,
                addrSelection, null, null);
        String address = "";
        String val;
        if (cursor.moveToFirst()) {
            do {
                val = cursor.getString(cursor.getColumnIndex("address"));
                if (val != null) {
                    address = val;
                    break;
                }
            } while (cursor.moveToNext());
        }
        if (cursor != null) {
            cursor.close();
        }
        return address;
    }
    

    这里是行的定义

    String addrSelection = "type=137 AND msg_id=" + id;
    

    类型常量来自PduHeadersPduHeaders

    class: 0x97 / 151 是 PduHeaders.TO 和 0x89 / 137 是 PduHeaders.FROM 您可以更改 FROM 或 TO 您需要的内容。

    如果它仍然是空的,试试下面的部分并在你的代码中实现它

    Uri uriMms = Uri.parse("content://mms/");
    final String[] projection = new String[]{"*"};
    
    Cursor cursor = contentResolver.query(uriMms, projection, null, null, null);
    String id = cursor.getString(cursor.getColumnIndex("_id"));
    
    String selectionPart = "mid=" + id;
    Uri uri = Uri.parse("content://mms/part");
    Cursor cursor2 = getContentResolver().query(uri, null, selectionPart, null, null);
    

    【讨论】:

    • 您能说得更具体些吗?确切地说,我应该用content://mms-sms/conversations/ 做什么才能获得群组文本中涉及的电话号码列表?我是 Android 开发新手。
    • 谢谢。问题是您的代码仍然依赖于content://mms/[id]/addr。如问题所述,在我正在测试的 Pixel 2 上,该地址并不总是有效。有时它会返回为 null。
    • 您在 logcat 中是否遇到任何错误?你试过这条线吗? "type=137 AND msg_id=" + id;
    • 对 FROM 和 TO 号码都试试这个 "type=137 or type=151 AND msg_id=" + id;
    • 如果仍然为空,您可以尝试 Uri uri = Uri.parse("content://mms/part");我在最后添加的答案。
    【解决方案2】:

    以下是 AOSP(Android 开源项目)消息传递应用程序的工作方式:

    1. 每条消息 (SMS/MMS) 在各自的表中都有一个消息 ID,表示为 _ID
    2. 使用此id 拉动相应消息的线程
    3. threads 表有一个名为recipient_ids 的列,对于群组消息,这可能是空格分隔,如下所示:

      123 456 789

    123 456 等是收件人 ID。

    1. 获取相应收件人 ID 的地址。现在这有点棘手,但 AOSP 使用以下 uri:content://mms-sms/canonical-address

    因此,获取地址数组的最终方法如下所示:

    private fun getAddressFromRecipientId(spaceSepIds: String, context: Context): Array<String?> {
        val singleCanonicalAddressUri = Uri.parse("content://mms-sms/canonical-address")
        with(spaceSepIds.split(" ")) {
        val addressArray: Array<String?> = arrayOfNulls(this.size)
            this.forEachIndexed { index, address ->
                if (!address.isEmpty()) {
                    val longId = address.toLong()
                    context.contentResolver.query(ContentUris.withAppendedId(singleCanonicalAddressUri, longId), null, null, null, null).use { cursor ->
                        if (cursor != null && cursor.moveToNext())
                            addressArray[index] = "${cursor.getString(0)} "
                    }
                }
            }
            return addressArray
        }
        return arrayOf()
    }
    

    希望这会有所帮助。该功能也在 kotlin 中,但很容易弄清楚那里发生了什么。

    此外,您已经有了 ID,因此您可以使用空格分隔的 ID 或不使用它们来调用此方法,该函数可以双向工作。

    【讨论】:

    • 这让我知道了问题所在。我可能应该发布一些代码,因为也许有人会以这种方式抓住它。再说一次,这是我在 Stack Overflow 上找到的代码(可能是 this answer),所以也许没有人会抓住它。我使用的是MessageFormat.format("content://mms/{0}/addr", id);,超过 999 的 ID 被格式化为逗号。为了解决这个问题,我将其更改为 MessageFormat.format("content://mms/{0,number,#}/addr", id); 谢谢!
    • 哇,这个答案很漂亮。感谢您发布链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多