Как узнать номера телефонов участников группового разговора MMS? - PullRequest
0 голосов
/ 05 сентября 2018

Я работаю над приложением Cordova, которое должно иметь возможность получить список телефонных номеров, участвующих в групповом тексте. Я запрашиваю content://mms/[id]/addr за это. Я тестирую на Pixel 2 и для сообщений MMS до 10 марта 2018 года это работает нормально. Но для сообщений в эту дату или после нее происходит сбой (возвращается как ноль). Есть другой адрес, который я должен запрашивать? Любые другие идеи?

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Вот как приложение для обмена сообщениями AOSP (Android Open Source Project) делает это:

  1. Каждое сообщение (SMS / MMS) имеет идентификатор сообщения, представленный как _ID в соответствующих таблицах
  2. С этим id потянуть за ветку соответствующего сообщения
  3. В таблице threads есть столбец с именем recipient_ids, это может быть Разделенный пробелом для группового сообщения, что-то вроде этого:

    123 456 789

Где 123 456 и т. Д. - идентификаторы получателя.

  1. Получить адрес для соответствующих идентификаторов получателей. Теперь это немного сложно, но 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, но довольно легко понять, что там происходит.

Кроме того, у вас уже есть идентификаторы, так что вы можете просто вызвать этот метод с идентификаторами, разделенными пробелами, или без них, функция работает в обоих направлениях.

0 голосов
/ 11 сентября 2018

Использование content://mms/ даст вам список MMS-сообщений, а использование content://mms-sms/conversations даст вам как первый, так и второй, который вы можете попробовать оба, если какой-либо из них не работает

поэтому сначала вам нужно будет получить список MMS только с помощью

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

класс: 0x97 / 151 - это PduHeaders.TO, а 0x89 / 137 - это PduHeaders.FROM, который вы можете изменить ОТ или НА, что вам нужно.

если он все еще пуст, попробуйте ниже часть и реализуйте это в своем коде

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);
...