SMS-MMS类意外结果

时间:2018-02-09 15:44:40

标签: java android sms mms

我对这个sms-mms类有一些问题,问题是它返回预期数据的6倍。它显示了之前的3个消息,然后显示了3个当前消息,我只需要1个电流,我不确定如何以6结束...就像这样;

V / Debug:Observer Started

V / Debug:收到短信

V / Debug:来自:+15555551212

V / Debug:输入:1

V / Debug:时间:星期二09月10日10:01:53 2018年

V / Debug:正文:一些短信......

重建类来源

public class MessageService extends Service {

private static final String VER = "1.1.10";
private static final String TAG = "ClassMessageService";

private ContentResolver contentResolver;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {

    Log.v(TAG, "Message capturing service version: " + VER);
    Log.v(TAG, "Message capturing service created " + ReturnCurrentDateTime());

}

public int onStartCommand(Intent intent, int flags, int startId) {

    registerObserver();

    return START_STICKY;

}

public void registerObserver() {

    contentResolver = getContentResolver();
    contentResolver.registerContentObserver(Uri.parse("content://mms-sms"), true, new MessageObserver(new Handler()));

}

public String ReturnCurrentDateTime() {

    Date datetime = new Date();
    datetime.getTime();

    return datetime.toString();

}

class MessageObserver extends ContentObserver {

    private final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

    private static final int SMS_MESSAGE = 0;
    private static final int MMS_MESSAGE = 1;

    //static {
    //    MATCHER.addURI("sms", "#", SMS_MESSAGE);
    //    MATCHER.addURI("mms", "#", MMS_MESSAGE);
    //}

    public MessageObserver(Handler handler) {
        super(handler);
        Log.v(TAG, "MessageObserver...");
        MATCHER.addURI("sms", "#", SMS_MESSAGE);
        MATCHER.addURI("mms", "#", MMS_MESSAGE);
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {

        super.onChange(selfChange, uri);

        switch (MATCHER.match(uri)) {
            case SMS_MESSAGE:

                Cursor cursor = contentResolver.query(uri, null, null, null, null);
                cursor.moveToNext();

                String msg_id;
                String phone;
                String dateVal;
                String body;
                Date date;

                msg_id = cursor.getString(cursor.getColumnIndex("_id"));
                phone = cursor.getString(cursor.getColumnIndex("address"));
                dateVal = cursor.getString(cursor.getColumnIndex("date"));
                body = cursor.getString(cursor.getColumnIndex("body"));

                date = new Date(Long.valueOf(dateVal));

                Log.v(TAG, "SMS: " + phone + " " + body + " " + msg_id + " " + date);

                break;

            case MMS_MESSAGE:

                Cursor mcursor = contentResolver.query(uri, null, null, null, null);
                mcursor.moveToNext();

                String mmsg_id;
                String mphone;
                String mdateVal;
                String mbody;
                Date mdate;

                mmsg_id = mcursor.getString(mcursor.getColumnIndex("_id"));
                mphone = mcursor.getString(mcursor.getColumnIndex("address"));
                mdateVal = mcursor.getString(mcursor.getColumnIndex("date"));
                mbody = mcursor.getString(mcursor.getColumnIndex("body"));

                mdate = new Date(Long.valueOf(mdateVal));

                Log.v(TAG, "SMS: " + mphone + " " + mbody + " " + mmsg_id + " " + mdate);

                break;

            default:

        }
    }

}

}

1 个答案:

答案 0 :(得分:0)

ContentObserver URI上注册content://mms-sms - 大概是true后代 - 通常会为您提供大量冗余且不相关的更改通知,并且您的观察者会对所有它们。

标准SmsProviderMmsProvider调度都会将更改通知更改为多个URI。例如,标准SmsProvider将调度到特定的content://sms/# URI(其中#是消息ID),以及常规content://mms-sms URI和{{1 } URI。这是“观察者正在处理的每条消息至少有两个通知。”

此外,content://mms-sms/conversation - 一般地处理线程(对话)而不是单个消息 - 只要它修改线程就可以在MmsSmsProvider上发出更改通知;例如,更新其摘要,将其标记为已读等。如果您真的只想跟踪消息发送或收据,则这些更改无关紧要,但您的观察者仍然会抓取并每次处理最新消息。

我建议的解决方案分为两部分:更改content://mms-sms以覆盖ContentObserver方法,并在onChange(boolean, Uri)content://sms URI上单独注册。< / p>

首先,content://mms自API级别16开始,ContentObserver方法的onChange()参数为Uri。即:

@Override
public void onChange(boolean selfChange, Uri uri) {
    ...
}

单独,对观察者的这一更改不会有太大帮助,因为您到达那里的Uri可能会有一般性URI - 例如,content://mms-smscontent://mms-sms/conversation - 没有其他识别信息。

第二个建议可以解决这个问题 - 在content://smscontent://mms上单独注册,而不是content://mms-sms。那就是:

getContentResolver().registerContentObserver(Uri.parse("content://sms"), ...);
getContentResolver().registerContentObserver(Uri.parse("content://mms"), ...);

执行此操作会阻止您的观察者收到content://mms-sms URI上的不相关通知,您应该在[{1}}中获得Uri格式onChange()content://sms/#,其中content://mms/#是邮件的ID,#。此long可用于检查邮件是短信还是彩信,以及您是否对您感兴趣的更改,作为无关更改的URI - 例如,对SMS的更改{ {1}}表 - 不应与这些表格匹配。

如果对两个已注册的Uri使用单个Observer * ,则可以使用raw一次处理这两个检查。例如:

Uri

此外,您可以直接使用该特定UriMatcher查询以获取单个邮件的详细信息,而不是查询常规public class MessageObserver extends ContentObserver { private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH); private static final int SMS_MESSAGE = 0; private static final int MMS_MESSAGE = 1; static { MATCHER.addURI("sms", "#", SMS_MESSAGE); MATCHER.addURI("mms", "#", MMS_MESSAGE); } @Override public void onChange(boolean selfChange, Uri uri) { switch (MATCHER.match(uri)) { case SMS_MESSAGE: break; case MMS_MESSAGE: break; default: } } ... } Uri URI,并获取每封邮件提供者,只检查第一个。

最后,你可能已经注意到我在这里说了很多陈述,说&#34;应该&#34;,&#34;可能&#34;等等。这些提供商有实现那里的表现可能与预期的完全不同。我建议你尽可能彻底地测试你的观察者。

*据我所知,为多个URI注册单个Observer实例没有问题,我的测试从未遇到任何问题。但是,您当然可以为短信和彩信实施单独的content://sms,而content://mms在过滤不相关的URI时仍然有用。