Android implementation of SMS authentication code to obtain automatic filling function (detailed version) _android

Source: Internet
Author: User

Now the application in the registration or modify the password are used in the SMS authentication code, that in Android is how to achieve the acquisition of SMS Verification code and automatically fill it out?

First, you need to register the right to receive and read text messages in manifest:

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

Implement a broadcast smsbroadcastreceiver to listen for text messages:

Package com.example.receive;
Import Java.text.SimpleDateFormat;

Import Java.util.Date;
Import Android.content.BroadcastReceiver;
Import Android.content.Context;
Import android.content.Intent;


Import Android.telephony.SmsMessage; /** * SMS Monitor * @author * */public class Smsbroadcastreceiver extends Broadcastreceiver {private static messagelist
 Ener Mmessagelistener;
 
 public static final String sms_received_action = "Android.provider.Telephony.SMS_RECEIVED";
 Public Smsbroadcastreceiver () {super (); @Override public void OnReceive (context context, Intent Intent) {if (Intent.getaction (). Equals (Sms_received_actio
    N)) {object[] PDUs = (object[]) Intent.getextras (). Get ("PDUs");
     for (Object pdu:pdus) {smsmessage smsmessage = SMSMESSAGE.CREATEFROMPDU ((byte []) PDU);
     String sender = Smsmessage.getdisplayoriginatingaddress ();
     SMS Contents String content = Smsmessage.getdisplaymessagebody ();
     Long date = Smsmessage.gettimestampmillis (); DateTiemdate = new Date (date);
     SimpleDateFormat SimpleDateFormat = new SimpleDateFormat ("Yyyy-mm-dd HH:mm:ss");

     String time = Simpledateformat.format (tiemdate);
      Filter the sending number of text messages that do not need to be read if ("+8613450214963". Equals (Sender)) {mmessagelistener.onreceived (content);
     Abortbroadcast ();
 }}//callback interface public interface MessageListener {public void onreceived (String message); } public void Setonreceivedmessagelistener (MessageListener messagelistener) {This.mmessagelistener = MessageListener
 ;

 }
}

In an activity that requires the validation code to be filled in, the production Smsbroadcastreceiver instance is implemented to implement the Onreceived callback interface. To conserve system resources, we use dynamic registration to unregister the method of broadcasting.  

Package com.example.smstest;

Import Com.example.receive.SMSBroadcastReceiver;
Import Android.os.Bundle;
Import android.app.Activity;
Import Android.content.IntentFilter;
Import Android.view.Menu;

Import Android.widget.EditText;
 public class Mainactivity extends activity {private EditText Edtpassword;
 
 Private Smsbroadcastreceiver Msmsbroadcastreceiver;

 private static final String ACTION = "Android.provider.Telephony.SMS_RECEIVED";
 @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
 Setcontentview (R.layout.activity_main);
 Edtpassword = (edittext) Findviewbyid (R.id.password);
  } @Override protected void OnStart () {Super.onstart ();

  Generate broadcast processing msmsbroadcastreceiver = new Smsbroadcastreceiver ();
  Instantiate the filter and set the broadcast intentfilter intentfilter = new Intentfilter (ACTION) to be filtered;
  Intentfilter.setpriority (Integer.max_value);

  Registered broadcast This.registerreceiver (msmsbroadcastreceiver, Intentfilter); Msmsbroadcastreceiver.setonreCeivedmessagelistener (New Smsbroadcastreceiver.messagelistener () {@Override public void onreceived (String message)

   {edtpassword.settext (message);
 }
  });
 } @Override protected void OnDestroy () {Super.ondestroy ();
 Cancellation of SMS Listening broadcast this.unregisterreceiver (msmsbroadcastreceiver);


 }


}

The above provides a way to obtain a short message verification code and automatically fill in the implementation, that is, directly through the SMS broadcast listening to SMS. However, this approach has its drawbacks: when your mobile phone installed a number of other SMS applications (such as QQ newsletter) or the phone itself restricted permissions, this approach may not work, can not be automatically filled out, and even if the priority set high, it is not guaranteed not to be other applications "preemptive."

Later, check the information, you can monitor the way the SMS database to achieve. Listening to the SMS database is mainly done by contentobserver this class. Contentobserver mainly monitors a particular databases table through URIs, triggering it when the URI observed by contentobserver changes. The idea is to listen for unread text messages in a specific number in a text database. We can find a lot of demo through Baidu, but I found a lot of demo in the presence of bugs, after receiving text messages caused a crash. In another case, when the computer is connected to the PC, the computer is equipped with software such as pea pods, when the cell phone receives a message, pea pods and the like may change the status of the text message to read, which will also cause the crash.

Through debugging, finally fix the bug, layout and SMS permissions will no longer repeat. Add an internal class smscontent to the mainactivity.

  /** * Monitor SMS Database/class Smscontent extends Contentobserver {private Cursor Cursor = null;
  Public smscontent (Handler Handler) {super (Handler);
   @Override public void OnChange (Boolean selfchange) {Super.onchange (selfchange); Read SMS for the specified number in the Inbox cursor = Managedquery (Uri.parse ("Content://sms/inbox"), New string[]{"_id", "Address", "read", "Body"} , "address=?" And read=? ", New string[]{" 1065811201 "," 0 "}," _id desc ");/by ID, if ordered by date, modify the phone time, read the text is not allowed MYLOG.L ("
   Cursor.isbeforefirst () "+ cursor.isbeforefirst () +" cursor.getcount () "+ Cursor.getcount ());
    if (cursor!= null && cursor.getcount () > 0) {contentvalues values = new Contentvalues ();  Values.put ("read", "1");
    Revise SMS to read mode Cursor.movetonext ();
    int smsbodycolumn = Cursor.getcolumnindex ("Body");
    String smsbody = cursor.getstring (Smsbodycolumn);

    MYLOG.V ("smsbody =" + smsbody);

   Edtpassword.settext (Matchesutil.getdynamicpassword (smsbody));

   }When using Managedquery, the Close () method cannot be invoked voluntarily, otherwise the crash if (Build.VERSION.SDK_INT <) {Cursor.close () will occur on the Android 4.0+ system.
 

 }
  }
 }

Remember to register for SMS change monitoring in OnCreate

Smscontent content = new Smscontent (new Handler ());
  Register SMS Change Monitor
  

Remember to log off the monitor
this.getcontentresolver (). Unregistercontentobserver (content);

Among them, issued by the Verification code text message is generally a string, which contains 6 digits, we need to extract the 6 digits, we can write a regular expression of a static method.

 /**
  * Intercept consecutive 6 digits from a string *
  used to get dynamic passwords from SMS *
  @param str SMS Content
  * @return intercepted 6-bit dynamic password/public
 static String Getdynamicpassword (String str) {pattern
  Continuousnumberpattern = Pattern.compile ("[0-9\\.]" +");
  Matcher m = continuousnumberpattern.matcher (str);
  String Dynamicpassword = "";
  while (M.find ()) {
   if (M.group (). Length () = 6) {
    System.out.print (M.group ());
    Dynamicpassword = M.group ();
   }
  }

  return dynamicpassword;
 }

At this point, Android access to the SMS Verification Code and automatically fill in the function is achieved.

Supplemental: There is a direct close cursor operation (now corrected) for the above SMS database listener:cursor.close ();
However, if this closes directly, it can cause a crash. For example, when you get the SMS password, automatically fill it out, press the home key back to the desktop, and then into the application, will cause application crashes. The newspaper's mistake is:

android.database.StaleDataException:Attempted to access a cursor after it has been closed

Later, by looking at the data that is used managedquery, you can not actively call the close () method, or on the Android 4.0+ system, will occur crashes. Make a judgment of the version and then perform the action of closing the cursor.

You cannot actively invoke the close () method when using Managedquery, otherwise the crash
   if (Build.VERSION.SDK_INT <) {
    on the Android 4.0+ system Cursor.close ();
   }

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.