最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實(shí)現(xiàn)短信驗(yàn)證碼獲取自動(dòng)填寫功能(詳細(xì)版)

 更新時(shí)間:2016年08月03日 09:58:46   作者:灰太狼  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)短信驗(yàn)證碼獲取自動(dòng)填寫功能,很實(shí)用的功能分享給大家,感興趣的小伙伴們可以參考一下

現(xiàn)在的應(yīng)用在注冊登錄或者修改密碼中都用到了短信驗(yàn)證碼,那在android中是如何實(shí)現(xiàn)獲取短信驗(yàn)證碼并自動(dòng)填寫的呢?

首先,需要要在manifest中注冊接收和讀取短信的權(quán)限: 

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

實(shí)現(xiàn)一個(gè)廣播SMSBroadcastReceiver來監(jiān)聽短信:

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;


/**
 * 短信監(jiān)聽
 * @author 
 *
 */
public class SMSBroadcastReceiver extends BroadcastReceiver {
 
 private static MessageListener 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_ACTION)) {
    Object[] pdus = (Object[]) intent.getExtras().get("pdus");
    for(Object pdu:pdus) {
     SmsMessage smsMessage = SmsMessage.createFromPdu((byte [])pdu);
     String sender = smsMessage.getDisplayOriginatingAddress();
     //短信內(nèi)容
     String content = smsMessage.getDisplayMessageBody();
     long date = smsMessage.getTimestampMillis();
     Date tiemDate = new Date(date);
     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     String time = simpleDateFormat.format(tiemDate);

     //過濾不需要讀取的短信的發(fā)送號(hào)碼
     if ("+8613450214963".equals(sender)) {
      mMessageListener.onReceived(content);
      abortBroadcast();
     }
    }
   }
  
 }
 
 //回調(diào)接口
 public interface MessageListener {
  public void onReceived(String message);
 }
 
 public void setOnReceivedMessageListener(MessageListener messageListener) {
  this.mMessageListener = messageListener;
 }
}

在需要填寫驗(yàn)證碼的Activity中,生產(chǎn)SMSBroadcastReceiver的實(shí)例,實(shí)現(xiàn)onReceived的回調(diào)接口。為了節(jié)約系統(tǒng)資源,我們使用動(dòng)態(tài)注冊注銷廣播的方法。 

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();
  //生成廣播處理
  mSMSBroadcastReceiver = new SMSBroadcastReceiver();

  //實(shí)例化過濾器并設(shè)置要過濾的廣播
  IntentFilter intentFilter = new IntentFilter(ACTION);
  intentFilter.setPriority(Integer.MAX_VALUE);
  //注冊廣播
  this.registerReceiver(mSMSBroadcastReceiver, intentFilter);

  mSMSBroadcastReceiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.MessageListener() {
   @Override
   public void onReceived(String message) {

    edtPassword.setText(message);

   }
  });
 }
 
 @Override
 protected void onDestroy() {
 super.onDestroy();
 //注銷短信監(jiān)聽廣播
  this.unregisterReceiver(mSMSBroadcastReceiver);
 }


}


上面提供了一種獲取短信息驗(yàn)證碼并自動(dòng)填寫的實(shí)現(xiàn)方式,就是直接通過短信廣播監(jiān)聽短信。但是,這種方式有它的缺陷:當(dāng)你的手機(jī)安裝了其他一些短信應(yīng)用(例如QQ通訊錄)或者手機(jī)本身限制了權(quán)限的情況下,這種方式有可能會(huì)不起作用,無法做到自動(dòng)填寫,而且就算把優(yōu)先級(jí)設(shè)高,也不能保證不會(huì)被別的應(yīng)用“搶先”。

后來查資料知道,可以通過監(jiān)聽短信數(shù)據(jù)庫的方式實(shí)現(xiàn)。監(jiān)聽短信數(shù)據(jù)庫主要是通過ContentObserver這個(gè)類來完成。ContentObserver主要是通過Uri來監(jiān)測特定的Databases的表,當(dāng)ContentObserver所觀察的Uri發(fā)生變化時(shí),便會(huì)觸發(fā)它。思路就是監(jiān)聽短信數(shù)據(jù)庫中特定號(hào)碼的未讀短信。我們可以通過百度找到許多demo,但是我發(fā)現(xiàn)很多demo中存在著Bug,在接收到短信后引起崩潰。還有一種情況,當(dāng)真機(jī)連接著電腦,電腦裝有類似豌豆莢之類的軟件的時(shí)候,手機(jī)收到短信后,豌豆莢之類的可能會(huì)把該短信的狀態(tài)改成“已讀”,這樣也會(huì)導(dǎo)致崩潰。

通過調(diào)試,終于把Bug修復(fù)了,布局和短信權(quán)限就不再贅述。在MainActivity中增加一個(gè)內(nèi)部類SmsContent。

  /**
  * 監(jiān)聽短信數(shù)據(jù)庫
  */
 class SmsContent extends ContentObserver {

  private Cursor cursor = null;

  public SmsContent(Handler handler) {
   super(handler);
  }

  @Override
  public void onChange(boolean selfChange) {

   super.onChange(selfChange);
   //讀取收件箱中指定號(hào)碼的短信
   cursor = managedQuery(Uri.parse("content://sms/inbox"), new String[]{"_id", "address", "read", "body"},
     " address=? and read=?", new String[]{"1065811201", "0"}, "_id desc");//按id排序,如果按date排序的話,修改手機(jī)時(shí)間后,讀取的短信就不準(zhǔn)了
   MyLog.l("cursor.isBeforeFirst() " + cursor.isBeforeFirst() + " cursor.getCount() " + cursor.getCount());
   if (cursor != null && cursor.getCount() > 0) {
    ContentValues values = new ContentValues();
    values.put("read", "1");  //修改短信為已讀模式
    cursor.moveToNext();
    int smsbodyColumn = cursor.getColumnIndex("body");
    String smsBody = cursor.getString(smsbodyColumn);
    MyLog.v("smsBody = " + smsBody);

    edtPassword.setText(MatchesUtil.getDynamicPassword(smsBody));

   }

   //在用managedQuery的時(shí)候,不能主動(dòng)調(diào)用close()方法, 否則在Android 4.0+的系統(tǒng)上, 會(huì)發(fā)生崩潰
   if(Build.VERSION.SDK_INT < 14) {
    cursor.close();
   }
  }
 }
 

記得在onCreate中注冊短信變化監(jiān)聽 

SmsContent content = new SmsContent(new Handler());
  //注冊短信變化監(jiān)聽
  this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content); 

記得注銷監(jiān)聽
 this.getContentResolver().unregisterContentObserver(content);

其中,下發(fā)的驗(yàn)證碼短信一般都是一個(gè)字符串,其中包含6位數(shù)字,我們需要把這6位數(shù)字提取出來,我們可以用正則表達(dá)式寫一個(gè)靜態(tài)方法。 

 /**
  * 從字符串中截取連續(xù)6位數(shù)字
  * 用于從短信中獲取動(dòng)態(tài)密碼
  * @param str 短信內(nèi)容
  * @return 截取得到的6位動(dòng)態(tài)密碼
  */
 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;
 }

至此,android獲取短信驗(yàn)證碼并自動(dòng)填寫的功能就實(shí)現(xiàn)了。

補(bǔ)充:對于上面短信數(shù)據(jù)庫監(jiān)聽中有個(gè)直接關(guān)閉游標(biāo)的操作(現(xiàn)在已經(jīng)更正):cursor.close();  
但是,如果這樣直接關(guān)閉的話,會(huì)引起崩潰。例如,當(dāng)獲取了短信密碼,自動(dòng)填寫上了之后,按home鍵返回桌面,然后再進(jìn)入應(yīng)用,會(huì)引起應(yīng)用崩潰。報(bào)的錯(cuò)是:

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

后來通過查資料得知,是用managedQuery的時(shí)候, 不能主動(dòng)調(diào)用close()方法, 否則在Android 4.0+的系統(tǒng)上, 會(huì)發(fā)生崩潰。對版本進(jìn)行一個(gè)判斷再執(zhí)行關(guān)閉游標(biāo)的操作。 

//在用managedQuery的時(shí)候,不能主動(dòng)調(diào)用close()方法, 否則在Android 4.0+的系統(tǒng)上, 會(huì)發(fā)生崩潰
   if(Build.VERSION.SDK_INT < 14) {
    cursor.close();
   }

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android Studio搜索功能(查找功能)及快捷鍵圖文詳解

    Android Studio搜索功能(查找功能)及快捷鍵圖文詳解

    這篇文章主要介紹了Android Studio搜索功能(查找功能)及快捷鍵圖文詳解,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2017-12-12
  • Android自定義評(píng)分控件的完整實(shí)例

    Android自定義評(píng)分控件的完整實(shí)例

    在Android開發(fā)中,我們經(jīng)常會(huì)用到對商家或者商品的評(píng)價(jià),運(yùn)用星星進(jìn)行打分,下面這篇文章主要給大家介紹了關(guān)于Android自定義評(píng)分控件的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • Android使用元數(shù)據(jù)實(shí)現(xiàn)配置信息的傳遞方法詳細(xì)介紹

    Android使用元數(shù)據(jù)實(shí)現(xiàn)配置信息的傳遞方法詳細(xì)介紹

    這篇文章主要介紹了Android使用元數(shù)據(jù)實(shí)現(xiàn)配置信息的傳遞方法,也就是實(shí)現(xiàn)配置快捷菜單功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • Android第三方開源下拉框NiceSpinner使用詳解

    Android第三方開源下拉框NiceSpinner使用詳解

    這篇文章主要為大家詳細(xì)介紹了Android第三方開源下拉框NiceSpinner的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 詳解 WebView 與 JS 交互傳值問題

    詳解 WebView 與 JS 交互傳值問題

    這篇文章主要介紹了詳解 WebView 與 JS 交互傳值問題的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Android如何集成極光短信驗(yàn)證

    Android如何集成極光短信驗(yàn)證

    這篇文章主要為大家詳細(xì)介紹了Android如何集成極光短信驗(yàn)證,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Android積分簽到上移消失動(dòng)畫效果

    Android積分簽到上移消失動(dòng)畫效果

    這篇文章主要介紹了Android積分簽到上移消失動(dòng)畫效果大致思路:動(dòng)畫部分,由一個(gè)垂直的平移和一個(gè)透明度變化的兩個(gè)動(dòng)畫組成。然后通過AnimationSet將兩個(gè)動(dòng)畫添加到集合,然后開始播放動(dòng)畫。
    2018-05-05
  • Android ToggleButton 詳解及實(shí)例代碼

    Android ToggleButton 詳解及實(shí)例代碼

    這篇文章主要介紹了Android ToggleButton 詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Android實(shí)現(xiàn)Activity水平和垂直滾動(dòng)條的方法

    Android實(shí)現(xiàn)Activity水平和垂直滾動(dòng)條的方法

    這篇文章主要介紹了Android實(shí)現(xiàn)Activity水平和垂直滾動(dòng)條的方法,涉及Activity的ScrollView設(shè)置相關(guān)技巧,需要的朋友可以參考下
    2016-07-07
  • Android列表動(dòng)圖展示的實(shí)現(xiàn)策略

    Android列表動(dòng)圖展示的實(shí)現(xiàn)策略

    這篇文章主要給大家介紹了關(guān)于Android列表動(dòng)圖展示的實(shí)現(xiàn)策略的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11

最新評(píng)論

洪洞县| 阿城市| 文安县| 海盐县| 阿拉善左旗| 淄博市| 金门县| 巴彦淖尔市| 兴海县| 许昌市| 新晃| 大同县| 固原市| 莱芜市| 米脂县| 浦城县| 池州市| 陆川县| 武邑县| 新源县| 怀柔区| 翼城县| 澄迈县| 安塞县| 荥经县| 万宁市| 修水县| 马边| 仪征市| 三明市| 林口县| 内丘县| 宜兰县| 乌恰县| 蓬莱市| 泾源县| 驻马店市| 普洱| 镇平县| 什邡市| 九台市|