Use ContentObserver to listen for text messages to receive onChange method calls twice

Posted by samvelyano on Sun, 12 Jul 2020 18:29:20 +0200

I used to use BroadcastReceiver to listen for text messages, but I later learned that ContentObserver can also do this, and it's more convenient.So try this.

ContentObserver works by observing (capturing) changes in the database caused by a particular Uri and then doing some appropriate work.

During the process of listening for text messages using ContentObserver, a problem was found, which is described as follows: When the mobile phone receives the text message, the onChange method is called once, and when the text message App is opened, the onChange method is called again.This calls onChange twice.

We generally don't want it to be called twice, for example, Apps with rings on the market currently have SMS alerts. As long as the phone receives a text message, App with rings will send some instructions to the rings, and the rings will receive instructions for vibration alerts.The general idea is to send data to the ring in the onChange method.If the above problems occur, the result is that when the mobile phone receives the text message, the ring vibrates, the text message App is opened, and the ring vibrates again.

After a series of queries.A solution was found.

Usage method:

// Get ContentResolver 
mContentResolver = getContentResolver();
// Register ContentObserver, the first parameter is Uri, and the second parameter, if true, is the derived Uri of that Uri (for example, "Content://sms/Inbox") can also listen, and the third parameter is a ContentObserver.
    mContentResover.registerContentObserver(Uri.parse("content://sms"), true,
new SmsContentObserverr(new Handler()));

// SmsContentObserver inherits ContentObserver:
class SmsContentObserver extends ContentObserver{

   private Uri mUri;

   public SmssReciever(Handler handler) {



    // As long as "content://sms"The method is called when the data inside changes
    public void onChange(boolean selfChange,Uri uri){

        Log.e("onChange","selfChange = "+selfChange+", Uri = "+uri.toString());
// After receiving the text message, and then opening the text message App, the Log message twice:
// SelfChange = false, Uri =Content://sms/2750Called after receiving a text message
// SelfChange = false, Uri =Content://sms/inboxCalled after opening SMS App

        // Execute first pass firstContent://sms/raw 
        // The second time isContent://sms/inbox
        if (uri.toString().equals("content://sms/inbox")) {
        // The code to send data to the ring is not executed after return ing 

        // Code to send data to the ring



Topics: Mobile Database