Explain the use of ContentObserver class in Android development in detail

  • 2021-07-06 11:44:05
  • OfStack

ContentObserver-Content Observer, the purpose of which is to observe (capture) the changes in the database caused by a specific Uri, and then do some corresponding processing, which is similar to
A trigger in database technology (Trigger) that triggers when the Uri observed by ContentObserver changes. Triggers are divided into table triggers, row triggers,
Accordingly, ContentObserver is also divided into "table" ContentObserver and "row" ContentObserver, which is related to Uri, MIME and Type it listens to.

Those familiar with Content Provider (content provider) should know that we can register different types of Uri through the UriMatcher class, and we can use these different
Uri to query different results. According to the results returned by Uri, Uri Type can be divided into Uri that returns multiple pieces of data and Uri that returns single piece of data.

Register/unregister the ContentObserver method. The method prototype in the abstract class ContentResolver class is as follows:

public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
Function: Registers an ContentObserver derived class instance for the specified Uri, and calls back the instance object to process when the given Uri changes.
Parameter: uri, Uri to be observed (it needs to be registered in UriMatcher, otherwise the Uri is meaningless)
notifyForDescendents is false for exact match, that is, only the Uri is matched
true means that its derived Uri can be matched at the same time, for example:
Assume that there are 1 types of Uri registered in UriMatcher:
1. content://com.qin.cb/student (students)
2. content://com.qin.cb/student/#
3. content://com.qin.cb/student/schoolchild (primary school students, derived Uri)

Assume that the Uri we need to observe at present is content://com.qin.cb/student, and if the data changes, Uri is
content://com.qin.cb/student/schoolchild. When notifyForDescendents is false, the ContentObserver will not be monitored.
However, when notifyForDescendents is ture, the database changes of Uri can be captured.

Derived class instance of observer ContentObserver


public final void unregisterContentObserver(ContentObserver observer)

Function: Cancel the observation of a given Uri
Parameter: Derived class instance of observer ContentObserver

Introduction to ContentObserver Class

Construction method public void ContentObserver (Handler handler)
Explanation: All derived classes of ContentObserver need to call this constructor
Parameter: handler Handler object. It can be the main thread Handler (UI can be updated at this time), or it can be any Handler object.
Commonly used methods


void onChange(boolean selfChange)

Function: When the observed Uri changes, call back the method to deal with it. All derived classes of ContentObserver need to overload this method to handle logic.
Parameter: After selfChange is called back, its value of 1 is generally false, which is of little significance (I don't understand it either, it is most important to understand the method).

The other two methods are of little use, and I don't understand them either. Please refer to SDK to understand them by yourself, and take the liberty.
boolean deliverSelfNotifications()
Description: Returns true if this observer is interested in notifications for changes made through cursor the observer is registered with.


final void dispatchChange(boolean selfChange)


The steps to observe a specific Uri are as follows:

1. To create our specific ContentObserver derived class, we must overload the parent class constructor and the onChange () method to handle the function implementation after callback
2. Obtain the ContentResolove object using context. getContentResolover (), then call the registerContentObserver () method to register the content observer
3. Because the life cycle of ContentObserver is not synchronized with Activity and Service, it is necessary to call manually when it is not needed
unregisterContentObserver () to deregister.

Ok, that's the introduction of the basic explanation. The following is a brief description of the small DEMO:
There are two different ContentObserver derived classes in Demo, as follows:
1. It is used to observe whether the system has changed the flight mode state.
PS: You can see this class in SDK: Android. provider. Settings. System. This class encapsulates access to all values under the settings module, such as:
Flight mode status, Bluetooth status, screen brightness value, etc., and the corresponding Uri is provided.
2. Observe that the short message data of the system has changed. When listening to the change of SMS data, query all sent SMS and display them.

There are 1 kinds of Uri of SMS:

content://sms/inbox Inbox content://sms/sent sent Draft content://sms/draft content://sms/outbox Outbox (information being sent) content://sms/failed send failed content://sms/queued to be sent list (for example, after the flight mode is turned on, the text message is in the to be sent list)

Examples of use:


package com.example.android_contentobserver;
 
import android.app.Activity;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
 
public class MainActivity extends Activity {
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
     
    // Registered observer Observser
    this.getContentResolver().registerContentObserver(Uri.parse("content://sms"),true,new SMSObserver(new Handler()));
 
  }
 
  private final class SMSObserver extends ContentObserver {
 
    public SMSObserver(Handler handler) {
      super(handler);
 
    }
 
   
    @Override
    public void onChange(boolean selfChange) {
 
      Cursor cursor = MainActivity.this.getContentResolver().query(
          Uri.parse("content://sms/inbox"), null, null, null, null);
 
      while (cursor.moveToNext()) {
        StringBuilder sb = new StringBuilder();
 
        sb.append("address=").append(
            cursor.getString(cursor.getColumnIndex("address")));
 
        sb.append(";subject=").append(
            cursor.getString(cursor.getColumnIndex("subject")));
 
        sb.append(";body=").append(
            cursor.getString(cursor.getColumnIndex("body")));
 
        sb.append(";time=").append(
            cursor.getLong(cursor.getColumnIndex("date")));
 
        System.out.println("--------has Receivered SMS::" + sb.toString());
 
         
      }
 
    }
 
  }
}


Related articles: