У меня есть ContentObserver
прослушивания content://sms/inbox
. Когда я отправляю длинное SMS-сообщение из одного эмулятора Android в другой эмулятор Android, этот ContentObserver
срабатывает многократно (в зависимости от количества коротких смс-сообщений в длинном смс-сообщении). Мне нужно объединить короткие сообщения в одно длинное сообщение, но у меня нет возможности решить, были ли эти сообщения отправлены как части одного длинного сообщения или они являются независимыми последовательными короткими сообщениями. Кажется, что доступные 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"
. Это единственный способ продолжить?
P.S. Я обнаружил, что реальный (не эмулятор) Android-клиент Android не хранит длинное сообщение в виде серии коротких сообщений. Он объединяет короткие сообщения в методе storeMessage
и сохраняет их как полное длинное сообщение в базе данных. Поэтому вопрос , почему SMS-клиент эмулятора Android отличается от реального !?
UPDATE:
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
}