Sms ContentObserver onChange() fires multiple times

后端 未结 4 1799
春和景丽
春和景丽 2020-12-09 13:36

I know this question has been asked multiple times, but nobody has been able to come up with a working answer from what I have seen.

Im working on an app to intercep

相关标签:
4条回答
  • 2020-12-09 13:38

    I just use SharedPreference to remark last SMS info (like: id\type ...). if it is the same, I will return.

    0 讨论(0)
  • 2020-12-09 13:41

    If the two are identical:
    store each message recv'd
    compare it to previous messages recv'd
    if not found, process
    if found, discard the message

    The life of the messages stored should be infinitesimal, a little circular buffer of 5 messages should be fine.

    0 讨论(0)
  • 2020-12-09 13:42

    here is my code, it works fine for me

    public class SmsObserver extends ContentObserver {  
        private Context context;
        private static int initialPos;
        private static final String TAG = "SMSContentObserver";
        private static final Uri uriSMS = Uri.parse("content://sms/sent");
    
        public SmsObserver(Handler handler, Context ctx) {
            super(handler);
            context = ctx;
            initialPos = getLastMsgId();
    
        }
    
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            queryLastSentSMS();
        }
    
        public int getLastMsgId() {
    
            Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
            cur.moveToFirst();
            int lastMsgId = cur.getInt(cur.getColumnIndex("_id"));
            Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId));
            return lastMsgId;
        }
    
        protected void queryLastSentSMS() {
    
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    Cursor cur =
                        context.getContentResolver().query(uriSMS, null, null, null, null);
    
                    if (cur.moveToNext()) {
    
    
                        try {
                            if (initialPos != getLastMsgId()) {
                                // Here you get the last sms. Do what you want.
                                String receiver = cur.getString(cur.getColumnIndex("address"));
                               System.out.println(" Receiver Ph no :"+receiver);
    
    
                                // Then, set initialPos to the current position.
                                initialPos = getLastMsgId(); 
                            }
                        } catch (Exception e) {
                            // Treat exception here
                        }
                    }
                    cur.close();
                }
            }).start();
    
        }
    
    }//End of class SmsObserver
    
    0 讨论(0)
  • 2020-12-09 14:03

    You can save last message's id and compare it to the id of the message that is returned by cur in onChange. you then can simply disregard the message if ids are the same.

    // might contain mistakes, but you'll get the idea:
    protected void querySMS() {
        Cursor cur = getContentResolver().query(u, null, null, null, null);
        cur.moveToNext(); 
        if (lastId == cur.getLong(cur.getColumnIndex("_id")))
            return;
        lastId = cur.getLong(cur.getColumnIndex("_id"));
        ... //continue as it was
    }
    

    However - GO SMS only prevents other app's from recieving Broadcast if the user selected this option (Recieve Settings - Disable other message notification) - so if the user does not want other apps to disturb him - I think it's good idea not to do so.

    0 讨论(0)
提交回复
热议问题