如何获取phone个彩信群聊参与人数?
How to get phone numbers of MMS group conversation participants?
我正在开发一个 Cordova 应用程序,该应用程序需要能够获取群组文本中涉及的 phone 号码列表。我正在查询 content://mms/[id]/addr
。我正在 Pixel 2 上进行测试,对于 2018 年 3 月 10 日之前的彩信,这工作正常。但对于该日期或之后的消息,它会失败(返回为空)。我应该查询其他地址吗?还有其他想法吗?
使用 content://mms/
会给你 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);
以下是 AOSP(Android 开源项目)消息传递应用程序的实现方式:
- 每条消息(SMS/MMS)在各自的 tables
中都有一个表示为 _ID
的消息 ID
- 有了这个
id
为相应的消息拉线
threads
table有个栏目叫recipient_ids
,这可能是Space分开的群消息,什么的像这样:
123 456 789
其中 123
456
等是收件人 ID。
- 获取各个收件人 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,因此您可以使用 space 分隔 ID 或不使用 ID 来调用此方法,该函数可以两种方式工作。
我正在开发一个 Cordova 应用程序,该应用程序需要能够获取群组文本中涉及的 phone 号码列表。我正在查询 content://mms/[id]/addr
。我正在 Pixel 2 上进行测试,对于 2018 年 3 月 10 日之前的彩信,这工作正常。但对于该日期或之后的消息,它会失败(返回为空)。我应该查询其他地址吗?还有其他想法吗?
使用 content://mms/
会给你 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);
以下是 AOSP(Android 开源项目)消息传递应用程序的实现方式:
- 每条消息(SMS/MMS)在各自的 tables 中都有一个表示为
- 有了这个
id
为相应的消息拉线 threads
table有个栏目叫recipient_ids
,这可能是Space分开的群消息,什么的像这样:123 456 789
_ID
的消息 ID
其中 123
456
等是收件人 ID。
- 获取各个收件人 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,因此您可以使用 space 分隔 ID 或不使用 ID 来调用此方法,该函数可以两种方式工作。