找到这方面的文档有点困难,所以我将在这里收集我找到的所有信息。如果您很着急或只是不喜欢阅读,请跳至如何从短信中获取数据部分。
内容://mms-sms/对话
这是 URI彩信和短信提供商 http://android.git.kernel.org/?p=platform/packages/providers/TelephonyProvider.git;a=blob;f=src/com/android/providers/telephony/MmsSmsProvider.java;h=e379c454ee203cb02aee59737b58bea24ac405cf;hb=HEAD...这允许我们同时查询 MMS 和 SMS 数据库,并将它们混合在一个线程中(称为对话).
为什么 URI 很重要?嗯,这是获取彩信和短信的标准方式;例如,当您收到短信并点击通知栏时,它会发送如下广播意图:content://mms-sms/conversations/XXX
, where XXX
是对话的 id。
获取所有对话的列表
您唯一要做的就是查询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);
Note:通常,当你打电话时query
并想要返回所有可以传递的列null
as the projection
范围。但是,您无法通过此提供程序执行此操作,因此这就是我使用的原因*
.
现在您可以循环遍历Cursor
照常。这些是您想要使用的更重要的列:
-
_id
是消息的 ID。队长明显要来救援吗?并不真地。此 ID 可用于检索详细信息,使用content://sms
or content://mms
.
-
date
无需解释。
-
thread_id
是对话的ID
-
body
此对话的最后一条短信的内容。如果是彩信,即使有文本部分,这也会是null
.
Note:如果你查询content://mms-sms/conversations
它将返回不同对话的列表,其_id
是每次对话中的最后一条短信或彩信。如果您查询content://mms-sms/conversations/xxx
它将返回 ID 为 的对话中的每条短信和/或彩信xxx
.
如何区分短信和彩信
通常,您会想知道您正在处理哪种类型的消息。文档说:
虚拟专栏,MmsSms.TYPE_DISCRIMINATOR_COLUMN
, 可能
在预测中要求
询问。它的值是“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 string = query.getString(query.getColumnIndex("ct_t"));
if ("application/vnd.wap.multipart.related".equals(string)) {
// it's MMS
} else {
// it's SMS
}
} while (query.moveToNext());
}
如何从短信中获取数据
现在你已经有了短信的ID,那么你唯一要做的就是:
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"));
如何从彩信数据中获取数据?
彩信有点不同。它们可以由不同的部分(文本、音频、图像等)构建;所以这里将看看如何分别检索每种数据。
所以我们假设彩信 ID 位于mmsId
多变的。我们可以通过使用以下方式获取有关此彩信的详细信息content://mms/
提供者:
Uri uri = Uri.parse("content://mms/");
String selection = "_id = " + mmsId;
Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
然而,唯一有趣的专栏是read
这是1
如果该消息已被阅读。
如何从彩信中获取文本内容
这里我们必须使用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();
}
如何从彩信中获取图像
这与获取文本部分相同...唯一的区别是您将寻找不同的 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
是彩信的 ID:
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。您必须检查源代码才能知道它是如何工作的,更糟糕的是,他们没有公开数据库列中使用的那些常量,因此我们必须手动编写它们。
- 对于彩信中的其他类型的数据,您可以应用上面学到的相同想法......这只是了解 mime 类型的问题。