作者@恺风Wei。
读短信需要READ_SMS的权限。
<uses-permission android:name="android.permission.READ_SMS" />
Content Provider的URI
通过content Provider可以读取短信。相关的URI如下:
- 所有:
content://sms/all
- 收件箱:
content://sms/inbox
- 已发送:
content://sms/sent
- 草稿箱:
content://sms/draft
- 发信箱:
content://sms/outbox
- 发送失败:
content://sms/failed
- 排队待发送:
content://sms/queued
- 未送达:
content://sms/undelivered
- 会话:
content://sms/conversations
彩信也可以通过content provider来获取,authority改为mms-sms即可,例如content://mms-sms/inbox。
通过content Provider可以获得cursor,每个元素即为一条短信,下面是常用的属性:
_id 一个自增字段,从1开始
thread_id 序号,同一发信人的id相同
address 发件人手机号码
person 联系人列表里的序号,陌生人为null
date 发件日期
protocol 协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO
read 是否阅读 0未读, 1已读
status 状态 -1接收,0 complete, 64 pending, 128 failed
type ALL = 0;INBOX = 1; SENT = 2; DRAFT = 3;OUTBOX = 4; FAILED = 5; QUEUED = 6;
body 短信内容
service_center 短信服务中心号码编号
subject 短信的主题
读取短信
小例子代码如下:
public class ReadSMSActivity extends ListActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor c = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);
String[] columns = new String[] { "address","body" };
int[] names = new int[] {android.R.id.text1,android.R.id.text2};
ListAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,
c, columns, names, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(adapter);
}
}
读取新收短信
短信的顺序是按时间反序排列,第一条短信即使最后接收的短信,我们需要的是在短信发生变化时,通过回调函数读取最后收到的短信。Content的内容,通过ContentProvider来获取,而Content的内容变化,则通过ContentObserver来获取。
public class SMSContentObserver extends ContentObserver{
private Activity activity = null;
public SMSContentObserver(Handler handler, Activity activity) {
super(handler);
this.activity = activity;
}
@Override //content发生变化的回调函数,可以直接通过该uri来获得该短信内容,或者读取全部的短信,获取其最新的一条。
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
getFirstSMS();
}
//通过content provider读取第一条短信
private void getFirstSMS(){
Cursor c = activity.getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);
if(!c.moveToFirst())
return;
String address = c.getString(c.getColumnIndex("address"));
String body = c.getString(c.getColumnIndex("body"));
c.close();
Toast.makeText(activity, "From " + address + ":\n" + body, Toast.LENGTH_LONG).show();
}
}
我们在Activity中注册要观察内容变更,如下:
public class ReadSMSActivity extends ListActivity{
… …
private SMSContentObserver observer = null;
@Override
protected void onResume() {
super.onResume();
observer = new SMSContentObserver(new Handler(),ReadSMSActivity.this); // 在测试中,如果填入content://sms/inbox,除一台4.1.2的设备起作用外,其他都不其作用 getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, observer);
}
@Override
protected void onPause() {
super.onPause();
getContentResolver().unregisterContentObserver(observer);
}
}
小例子代码在:Pro Android学习:telephony小例子