Как восстановить длинное SMS (текстовое) сообщение из нескольких коротких текстовых сообщений, хранящихся в базе данных Android? - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть 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
}
...