Ответ 1
Трудно найти документацию об этом, поэтому я собираю здесь всю информацию, которую я нашел. Если вы находитесь в спешке или просто не любите читать, перейдите к Как получить данные из раздела SMS.
содержание://MMS-SMS/разговоры
Это URI провайдера Mms и SMS... который позволяет нам одновременно запрашивать базы данных MMS и SMS, и смешивать их в одном потоке (который называется цепочками).
Почему это важно? Ну, это стандартный способ получения MMS и SMS-сообщений; например, когда вы получаете SMS-сообщение и нажимаете на панель уведомлений, он отправляет намерение трансляции следующим образом: content://mms-sms/conversations/XXX
, где XXX
является идентификатором разговора.
Получить список всех разговоров
Единственное, что вам нужно сделать, это запросить content://mms-sms/conversations
Uri:
ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"*"};
Uri uri = Uri.parse("content://mms-sms/conversations/");
Cursor query = contentResolver.query(uri, projection, null, null, null);
Примечание: обычно, когда вы вызываете query
и хотите вернуть все столбцы, вы можете передать null
в качестве параметра projection
. Однако вы не можете сделать это с этим провайдером, поэтому я использую *
.
Теперь вы можете прокручивать Cursor
, как обычно. Это наиболее важные столбцы, которые вы хотели бы использовать:
-
_id
- это идентификатор сообщения. Капитан явный для спасения? На самом деле, нет. Этот идентификатор может использоваться для получения подробной информации с использованием либоcontent://sms
, либоcontent://mms
. -
date
никаких объяснений не требуется. -
thread_id
- идентификатор беседы -
body
Содержание последнего SMS в этом разговоре. Если это MMS, даже если у него есть текстовая часть, это будетnull
.
Примечание:, если вы запросите content://mms-sms/conversations
, он вернет список разных разговоров, чей _id
является последним SMS или MMS в каждом разговоре. Если вы запросите content://mms-sms/conversations/XXX
, он вернет каждое SMS и/или MMS в разговор, чей идентификатор XXX
.
Как различать SMS и MMS
Обычно вам нужно знать, какой тип сообщения вы обрабатываете. Документация гласит:
Виртуальный столбец,
MmsSms.TYPE_DISCRIMINATOR_COLUMN
, может запрашиваться в проекции для запрос. Его значение равно либо "ммс", либо "смс", в зависимости от того, сообщение, представленное рядом, является MMS-сообщение или SMS-сообщение, соответственно.
Я думаю, что это ссылается на эту переменную... однако я не смог заставить ее работать. Если вы скажете мне, как это изменить или отредактировать это сообщение.
До сих пор это то, что я сделал и, похоже, работает, но должны быть лучшие способы:
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 string = query.getString(query.getColumnIndex("ct_t"));
if ("application/vnd.wap.multipart.related".equals(string)) {
// it MMS
} else {
// it SMS
}
} while (query.moveToNext());
}
Как получить данные из SMS
Итак, у вас есть идентификатор SMS, тогда вам нужно только:
String selection = "_id = "+id;
Uri uri = Uri.parse("content://sms");
Cursor cursor = contentResolver.query(uri, null, selection, null, null);
String phone = cursor.getString(cursor.getColumnIndex("address"));
int type = cursor.getInt(cursor.getColumnIndex("type"));// 2 = sent, etc.
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
Как получить данные из данных MMS?
MMS немного отличаются. Они могут быть построены с различными частями (текст, аудио, изображения и т.д.); поэтому здесь будет показано, как извлекать каждый вид данных отдельно.
Итак, давайте предположим, что у меня есть идентификатор MMS в переменной mmsId
. Мы можем получить подробную информацию об этом MMS с помощью поставщика content://mms/
:
Uri uri = Uri.parse("content://mms/");
String selection = "_id = " + mmsId;
Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
Однако только интересный столбец read
, который является 1
, если сообщение уже прочитано.
Как получить текстовый контент из MMS
Здесь мы должны использовать content://mms/part
... например:
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cursor = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cursor.moveToFirst()) {
do {
String partId = cursor.getString(cursor.getColumnIndex("_id"));
String type = cursor.getString(cursor.getColumnIndex("ct"));
if ("text/plain".equals(type)) {
String data = cursor.getString(cursor.getColumnIndex("_data"));
String body;
if (data != null) {
// implementation of this method below
body = getMmsText(partId);
} else {
body = cursor.getString(cursor.getColumnIndex("text"));
}
}
} while (cursor.moveToNext());
}
Он может содержать разные части текста... но обычно он будет только одним. Поэтому, если вы хотите удалить цикл, он будет работать большую часть времени. Вот как выглядит метод getMmsText
:
private String getMmsText(String id) {
Uri partURI = Uri.parse("content://mms/part/" + id);
InputStream is = null;
StringBuilder sb = new StringBuilder();
try {
is = getContentResolver().openInputStream(partURI);
if (is != null) {
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
String temp = reader.readLine();
while (temp != null) {
sb.append(temp);
temp = reader.readLine();
}
}
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return sb.toString();
}
Как получить изображение из MMS
Это то же самое, что и получение текстовой части... Единственное отличие состоит в том, что вы будете искать другой тип mime:
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cPart = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cPart.moveToFirst()) {
do {
String partId = cPart.getString(cPart.getColumnIndex("_id"));
String type = cPart.getString(cPart.getColumnIndex("ct"));
if ("image/jpeg".equals(type) || "image/bmp".equals(type) ||
"image/gif".equals(type) || "image/jpg".equals(type) ||
"image/png".equals(type)) {
Bitmap bitmap = getMmsImage(partId);
}
} while (cPart.moveToNext());
}
Вот как выглядит метод getMmsImage
:
private Bitmap getMmsImage(String _id) {
Uri partURI = Uri.parse("content://mms/part/" + _id);
InputStream is = null;
Bitmap bitmap = null;
try {
is = getContentResolver().openInputStream(partURI);
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return bitmap;
}
Как получить адрес отправителя
Вам нужно будет использовать поставщик content://mms/xxx/addr
, где XXX
- это идентификатор MMS:
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;
}
Заключительные мысли
- Не могу понять, почему Google, с тысячами миллионов долларов, не платит студенту или кому-то другому документировать этот API. Вы должны проверить исходный код, чтобы узнать, как он работает, и, что еще хуже, они не обнародуют те константы, которые используются в столбцах базы данных, поэтому мы должны писать их вручную.
- Для других видов данных внутри MMS вы можете применить ту же мысль, что и выше... это просто вопрос знания типа mime.