读取短信本身没什么难度,仅仅是读取SQLite数据库而已。
Activity::managedQuery函数基本上是一个接收SQL查询的接口,参数分别为:
要读取短信,需要加入权限:
关于content://sms/inbox表,大致包含的域有:
_id | 短消息序号 如100
thread_id | 对话的序号 如100
address | 发件人地址,手机号.如+8613811810000
person | 发件人,返回一个数字就是联系人列表里的序号,陌生人为null
date | 日期 long型。如1256539465022
protocol | 协议 0 SMS_RPOTO, 1 MMS_PROTO
read | 是否阅读 0未读, 1已读
status | 状态 -1接收,0 complete, 64 pending, 128 failed
type | 类型 1是接收到的,2是已发出
body | 短消息内容
service_center | 短信服务中心号码编号。如+8613800755500
关于短信相关的应用,大致还包括:监听短信数据库(可用于监听短信的到来)、发送短信。使用起来基本上还算简单。
12.16.2010 updated
上面罗列了短信表的字段名,但是没有给出数据类型。在调用Cursor.getString时,该函数会将对应的值转换为字符串(如果不是字符串的话)。要查看SMS表的字段,可以用DDMS把/data/data/com.android.providers.telephony/databases/mmssms.db这个文件,即数据库文件导出,然后找一个SQLite数据库的浏览软件,即可获取出。
sms表大部分都是INTEGER类型,对应到JAVA里也就是long型数据。基本上我只关注以下字段:
person字段取出的值如果该短信是联系人发来的,则指定了联系人表里_id字段的值,例如1、2、3,否则就是0。所以,我们可以通过继续查询联系人数据库表里的内容来取得该短信是谁发来的:
以上代码可能会有BUG,因为在我的手机上测试,moveToFirst经常会失败,继续person字段非0,也取不出联系人信息。这个问题改日再研究。
放上我的测试程序
- public Uri SMS_INBOX = Uri.parse("content://sms/inbox");
- private void fillListView() {
- ListView view = (ListView) findViewById(R.id.sms_list);
- ArrayList<HashMap<String, String>> list = readAllSMS();
- SimpleAdapter listItemAdapter = new SimpleAdapter(this, list,
- android.R.layout.simple_list_item_2,
- new String[] {"addr","body"},
- new int[] {android.R.id.text1, android.R.id.text2}
- );
- view.setAdapter(listItemAdapter);
- }
- private ArrayList<HashMap<String, String>> readAllSMS() {
- Cursor cursor = managedQuery(SMS_INBOX, new String[] { "address", "person", "body" },
- null, null, null );
- ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>> ();
- if(cursor.moveToFirst()) {
- int addrIdx = cursor.getColumnIndex("address");
- int personIdx = cursor.getColumnIndex("person");
- int bodyIdx = cursor.getColumnIndex("body");
- do {
- String addr = cursor.getString(addrIdx);
- String person = cursor.getString(personIdx);
- String body = cursor.getString(bodyIdx);
- HashMap<String, String> item = new HashMap<String, String>();
- item.put("addr", addr);
- item.put("person", person);
- item.put("body", body);
- list.add(item);
- } while(cursor.moveToNext());
- }
- return list;
- }
Activity::managedQuery函数基本上是一个接收SQL查询的接口,参数分别为:
- Parameters
- uri The URI of the content provider to query.
- projection List of columns to return.
- selection SQL WHERE clause.
- selectionArgs The arguments to selection, if any ?s are pesent
- sortOrder SQL ORDER BY clause.
要读取短信,需要加入权限:
- <uses-permission android:name="android.permission.READ_SMS"></uses-permission>
关于content://sms/inbox表,大致包含的域有:
_id | 短消息序号 如100
thread_id | 对话的序号 如100
address | 发件人地址,手机号.如+8613811810000
person | 发件人,返回一个数字就是联系人列表里的序号,陌生人为null
date | 日期 long型。如1256539465022
protocol | 协议 0 SMS_RPOTO, 1 MMS_PROTO
read | 是否阅读 0未读, 1已读
status | 状态 -1接收,0 complete, 64 pending, 128 failed
type | 类型 1是接收到的,2是已发出
body | 短消息内容
service_center | 短信服务中心号码编号。如+8613800755500
关于短信相关的应用,大致还包括:监听短信数据库(可用于监听短信的到来)、发送短信。使用起来基本上还算简单。
12.16.2010 updated
上面罗列了短信表的字段名,但是没有给出数据类型。在调用Cursor.getString时,该函数会将对应的值转换为字符串(如果不是字符串的话)。要查看SMS表的字段,可以用DDMS把/data/data/com.android.providers.telephony/databases/mmssms.db这个文件,即数据库文件导出,然后找一个SQLite数据库的浏览软件,即可获取出。
sms表大部分都是INTEGER类型,对应到JAVA里也就是long型数据。基本上我只关注以下字段:
- public String mAddress;
- public String mBody;
- public String mSubject;
- public long mID;
- public long mThreadID;
- public long mDate;
- public long mRead;
- public long mPerson;
person字段取出的值如果该短信是联系人发来的,则指定了联系人表里_id字段的值,例如1、2、3,否则就是0。所以,我们可以通过继续查询联系人数据库表里的内容来取得该短信是谁发来的:
- class ContactItem {
- public String mName;
- }
- ContactItem getContact(Activity activity, final SMSItem sms) {
- if(sms.mPerson == 0) return null;
- Cursor cur = activity.managedQuery(ContactsContract.Contacts.CONTENT_URI,
- new String[] {PhoneLookup.DISPLAY_NAME},
- " _id=?",
- new String[] {String.valueOf(sms.mPerson)}, null);
- if(cur != null &&
- cur.moveToFirst()) {
- int idx = cur.getColumnIndex(PhoneLookup.DISPLAY_NAME);
- ContactItem item = new ContactItem();
- item.mName = cur.getString(idx);
- return item;
- }
- return null;
- }
以上代码可能会有BUG,因为在我的手机上测试,moveToFirst经常会失败,继续person字段非0,也取不出联系人信息。这个问题改日再研究。
放上我的测试程序