Preface:

In Android application development will be involved in the process of signing in the realization of the function modules, and many of the register or login or change password function is often need the user to input message authentication code, usually, users receive message authentication code need to minimize the application to view the message back to the input relative to the authentication code, This process is a bit troublesome, so it is necessary to automatically obtain the successful SMS verification code, convenient for users to operate, and the user experience will be better.

The principle of interpretation

This involves the use of the ContentObserver class. Contentproviders are used to listen for changes in the SMS database, and custom onChange methods are implemented within the ContentObserver to listen for messages from specific mobile phone numbers. Information is then intercepted to fill in the desired location.

ContentObserver is the content listener. When we send a message to our phone, the phone automatically calls the methods specified in ContentObserver to notify us that the message has changed. We then read the message, extract the verification code, and automatically fill in the input box. This completes the auto-fill function. The ContentObserver class listens for changes in SMS content, which refers to a common Android design pattern called observer mode.

ContentObserver Explanation – Observer mode

The observer pattern (sometimes also known as publish-subscribe, model-view, source-receiver or subordinator) is one of the software design patterns in which a target object manages all observer objects that depend on it. And it actively notifies itself when its state changes, usually by calling various observers to provide a method that is commonly used to implement event processing systems.

The Observer mode perfectly separates the Observer from the observed object. The Observer pattern sets clear boundaries between modules, improving application maintainability and reuse.

The observer design pattern defines a one-to-many dependency between objects so that when an object’s state changes, all dependent objects are notified and refreshed automatically.

ContentObserver – ContentObserver, whose purpose is to observe (catch) changes to the database caused by a particular Uri and do some processing accordingly, is similar to a Trigger in database technology that is triggered when the Uri observed by ContentObserver changes.

Observer (our application) : The Observer registers itself with the Subject, which stores the Observer in a Container.

Observed (SMS application of the system) : The observed object has some changes, all registered observers are obtained from the container, and the changes are notified to the observer.

Unobserve: The observer tells the observed to unobserve, and the observed removes the observer from the container.

Specific to our project, that is to say, when the application has just started to run, to our mobile phone system message application to register a observer, when SMS change SMS application will notify the registered observer has changed, our observers received such a notice, will perform the corresponding operation according to the code, In this way, the verification code can be filled in automatically. When we have completed the required functionality, we want to unregister the observer, unregister the observer, and remove the observer from the container. The observer no longer receives notification of the content change of the message after being revoked.

The steps to observe a particular Uri are as follows
  • To create our particular ContentObserver derived classes, we must override the parent class constructor and the onChange() method to handle the function implementation after the callback.

  • Using the context. GetContentResolover () to obtain ContentResolove object, then call registerContentObserver () method to register content viewer.

  • Life cycle as a result of the ContentObserver synchronization in the Activity and Service, etc., therefore, when not needed, need to manually call unregisterContentObserver () to cancel the registration.

The URIs of short messages are as follows:
content:/ / SMS/inbox inbox

content:/ / SMS/sent sent

content:/ / SMS/draft draft

content:// SMS /outbox (message being sent)

content:// SMS /failed Failed to send messages

content:// SMS /queued waiting list (for example, when airplane mode is enabled, the message is in the waiting list)Copy the code
Specific implementation code:
public class SmsObserver extends ContentObserver {  
    public static final String SMS_URI_INBOX = "content://sms/inbox";  
    private Activity activity = null;  
    private String smsContent = "";  
    private SmsListener listener;  

    public SmsObserver(Activity activity, Handler handler, SmsListener listener) {  
        super(handler);  
        this.activity = activity;  
        this.listener = listener;  
}  

    @Override  
    public void onChange(boolean selfChange) {  
        super.onChange(selfChange);  
        Cursor cursor = null;  
        // Read messages containing certain keywords in your inbox
        ContentResolver contentResolver = activity.getContentResolver();  
        cursor = contentResolver.query(Uri.parse(SMS_URI_INBOX), new String[] {  
                "_id"."address"."body"."read" }, "body like ? and read=?".new String[] { Express "% %"."0" }, "date desc");  
        if (cursor! =null) {  
            cursor.moveToFirst();  
            if (cursor.moveToFirst()) {  
                String smsbody = cursor  
                        .getString(cursor.getColumnIndex("body"));  
                String regEx = "[^ 0-9]." ";  
                Pattern p = Pattern.compile(regEx);  
                Matcher m = p.matcher(smsbody.toString());  
                smsContent = m.replaceAll("").trim().toString();  
                if(! TextUtils.isEmpty(smsContent)) { listener.onResult(smsContent); }}}}/* * SMS callback interface */  
    public interface SmsListener {  
        /** * accept SMS status ** @title: onResult */  
        void onResult(StringsmsContent); }}Copy the code
Use as follows:
SmsObserver smsObserver = new SmsObserver(this.new Handler(),  
            new SmsListener() {  
                @Override  
                public void onResult(String smsContent) {  
                    //todo  }});this.getContentResolver().registerContentObserver(  
            Uri.parse("content://sms/"), true, smsObserver);Copy the code
Add permission to read SMS messages:

uses-permission android:name="android.permission.READ_SMS" />