我有ContentObserver
听content://sms/inbox
。当我从一个 Android 模拟器向另一个 Android 模拟器发送长 SMS 消息时,这ContentObserver
会触发多次(取决于长 SMS 消息中的短 SMS 消息的数量)。我需要将短消息连接到一条长消息中,但我没有一个功能可以确定这些消息是作为一条长消息的一部分发送还是它们是独立的连续短消息。似乎可用cursor
的列根本不包含这样的功能:
0 = "_id"
1 = "thread_id"
2 = "address"
3 = "person"
4 = "date"
5 = "date_sent"
6 = "protocol"
7 = "read"
8 = "status"
9 = "type"
10 = "reply_path_present"
11 = "subject"
12 = "body"
13 = "service_center"
14 = "locked"
15 = "sub_id"
16 = "error_code"
17 = "creator"
18 = "seen"
据我所知,有一种方法可以通过receiver
和进行所需的连接"pdus"
。这是唯一的方法吗?
PS我发现真正的(不是模拟器)Android SMS 客户端不会将长消息保留为一系列短消息。它在方法中连接短消息storeMessage
并将它们作为一个完整的长消息保存在数据库中。那么问题来了,为什么安卓模拟器短信客户端和真实的不一样!?
更新:
SmsObserver
类:
public class SMSObserver1 extends ContentObserver {
private Context context;
private SmsListener listener;
public SMSObserver(Context context, Handler handler, SmsListener listener) {
super(handler);
this.context = context;
this.listener = listener;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Uri mUri = Uri.parse("content://sms");
Cursor mCursor = context.getContentResolver().query(mUri, null, null, null, null);
if (mCursor != null && mCursor.moveToNext()) {
SmsEntity entity = null;
int type = mCursor.getInt(mCursor.getColumnIndex("type"));//now we need to decide SMS message is sent or received
if (type == 1) //it's received SMS
entity = getSMS(true);
else if (type == 2) //it's sent SMS
entity = getSMS(false);
mCursor.close();
if (entity != null)
listener.addSms(entity);
}
}
private SmsEntity getSMS(boolean isIncoming) {
SmsEntity entity = null;
Uri uri = Uri.parse(isIncoming ? "content://sms/inbox" : "content://sms/sent");
Cursor cursor = context.getContentResolver().query(uri, null,null, null, null);
if (cursor != null && cursor.moveToNext()) {
entity = printSms(cursor, isIncoming);
cursor.close();
}
return entity;
}
private SmsEntity printSms(Cursor cursor, boolean isIncoming){
int type = cursor.getInt(cursor.getColumnIndex("type"));
long msg_id= cursor.getLong(cursor.getColumnIndex("_id"));
String phone = cursor.getString(cursor.getColumnIndex("address"));
long dateVal = cursor.getLong(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
Date date = new Date(dateVal);
String str = (isIncoming ? "Received" : "Sent") + " SMS: \n phone is: " + phone;
str +="\n SMS type is: " + type;
str +="\n SMS time stamp is:" + date;
str +="\n SMS body is: " + body;
str +="\n id is : " + msg_id;
Log.v("Debug", str);
return new SmsEntity(msg_id, dateVal, true, isIncoming, phone, body);
}
}
注册/注销发生在onResume
/onPause
回调中Fragment
:
@Override
public void onPause() {
super.onPause();
unregisterContentObserver();
}
public void unregisterContentObserver() {
if (mSmsObserver != null) {
try {
getActivity().getContentResolver().unregisterContentObserver(mSmsObserver);
} catch (IllegalStateException ise) {
Timber.w(ise.getMessage());
} finally {
mSmsObserver = null;
}
}
}
@Override
public void onResume() {
super.onResume();
registerContentObserver();
}
private void registerContentObserver() {
mSmsObserver = new SMSObserver(getActivity(), new Handler(),this);
getActivity().getContentResolver().registerContentObserver(Uri.parse("content://sms/inbox"), true, mSmsObserver);//To track an incoming SMS only
}