写在开头

google官方介绍
如果在没有读写短信权限的情况下获取用户的短信验证码呢?google为我们提供了SMSRetrieverAPI这个Api。解决了我们在用户收到短信后自动回填界面的需求。但是google为了安全性,短信格式需要时固定的,那么我们先来看下短信的固定格式!

短信格式

短信固定格式(#号可以不要,sha256一定需要)
<#> Your ExampleApp code is: 123ABC78
FA+9qCX9VSu

google要求我们的短信:

  • 不能超过140个字节
  • 包含一个11个字符的哈希字符串来标识您的应用(也就是上文的sha256)

sha256如何生成

网上通用的生成方式,总结了一个工具类AppSignatureHashHelper

 public class AppSignatureHashHelper extends ContextWrapper {public static final String TAG = AppSignatureHashHelper.class.getSimpleName();private static final String HASH_TYPE = "SHA-256";public static final int NUM_HASHED_BYTES = 9;public static final int NUM_BASE64_CHAR = 11;public AppSignatureHashHelper(Context context) {super(context);}public ArrayList<String> getAppSignatures() {ArrayList<String> appSignaturesHashs = new ArrayList<>();try {String packageName = getPackageName();PackageManager packageManager = getPackageManager();Signature[] signatures = packageManager.getPackageInfo(packageName,PackageManager.GET_SIGNATURES).signatures;for (Signature signature : signatures) {String hash = hash(packageName, signature.toCharsString());if (hash != null) {appSignaturesHashs.add(String.format("%s", hash));}}} catch (Exception e) {Log.e(TAG, "Package not found", e);}return appSignaturesHashs;}@TargetApi(19)private static String hash(String packageName, String signature) {String appInfo = packageName + " " + signature;try {MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));byte[] hashSignature = messageDigest.digest();hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES);String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);return base64Hash;} catch (NoSuchAlgorithmException e) {Log.e(TAG, "No Such Algorithm Exception", e);}return null;}
}

接下来我们要开始集成SMSRetrieverAPI了

首先我们要依赖google的两个库才能使用这个功能

dependencies {implementation 'com.google.android.gms:play-services-auth:19.2.0'implementation 'com.google.android.gms:play-services-auth-api-phone:17.5.1'
}

然后要通过google的系统广播的action–SmsRetriever.SMS_RETRIEVED_ACTION和SmsRetriever实现监听的需求

接下来第一步
先创建SMSReceiver这个BroadcastReceiver接收系统给我推送的SMS广播,并创建OTPReceiveListener接口来实现监听结果的返回,代码如下:

 public class SMSReceiver extends BroadcastReceiver {private OTPReceiveListener otpListener;public void setOTPListener(OTPReceiveListener otpListener) {this.otpListener = otpListener;}@Overridepublic void onReceive(Context context, Intent intent) {if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {Bundle extras = intent.getExtras();Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);switch (status.getStatusCode()) {case CommonStatusCodes.SUCCESS:String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);if (otpListener != null) {otpListener.onOTPReceived(message);}break;case CommonStatusCodes.TIMEOUT:if (otpListener != null) {otpListener.onOTPTimeOut();}break;case CommonStatusCodes.API_NOT_CONNECTED:if (otpListener != null) {otpListener.onOTPReceivedError("API NOT CONNECTED");}break;case CommonStatusCodes.NETWORK_ERROR:if (otpListener != null) {otpListener.onOTPReceivedError("NETWORK ERROR");}break;case CommonStatusCodes.ERROR:if (otpListener != null) {otpListener.onOTPReceivedError("SOME THING WENT WRONG");}break;}}}public interface SMSReceiveListener {void onSMSReceived(String otp);void onSMSTimeOut();void onSMSReceivedError(String error);}
}

第二步的话我们要主动开启这个监听:

private void startSMSListener() {try {smsReceiver = new SMSReceiver();smsReceiver.setOTPListener(this);//this指的是要在这个activity实现这个接口IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION);this.registerReceiver(smsReceiver, intentFilter);SmsRetrieverClient client = SmsRetriever.getClient(this);Task<Void> task = client.startSmsRetriever();task.addOnSuccessListener(new OnSuccessListener<Void>() {@Overridepublic void onSuccess(Void aVoid) {//代表监听成功开始了}});task.addOnFailureListener(new OnFailureListener() {@Overridepublic void onFailure(@NonNull Exception e) {//代表监听失败了,后续也不会收到系统推送的SMS通知}});} catch (Exception e) {e.printStackTrace();}}

实现接口的方法获取结果:

 @Overridepublic void onSMSReceived(String otp) {//成功接收到结果}@Overridepublic void onSMSTimeOut() {//接收结果超时}@Overridepublic void onSMSReceivedError(String error) {//接收结果报错}

写在最后

这种方式不是一定会成功的,google告诉我们可以检测广播意图是使用短信API通过添加com.google.android.gms.auth.api.phone.permission.SEND允许你的接收SMS。此权限设置在 Google Play 服务 19.8.31 或更高版本中可用。也就是低于Google Play 服务 19.8.31 的手机是不能使用的,不过作为辅助功能,也可以了。。

Android使用Google SMSRetrieverAPI监听短信相关推荐

  1. Android实时监听短信并上传服务器

    短信监听 Android监听手机短信的方法有两种,分别为: 1.接受系统的短信广播:当手机收到新消息时,会发送一条广播,通过该广播就可以获取短信内容: 2.监听短信数据库:利用观察者模式监听短信数据库 ...

  2. Android 监听短信数据库过滤获取短信内容上传至服务器

    前言 Android 监听短信的方式有两种 1.监听短信数据库,数据库发生改变时回调. 2.监听短信广播 其中第二种方式由于国内各厂家的定制Android 可能导致无响应 目前测试 魅族 无法监听到短 ...

  3. android 发送彩信监听,在Android中发送短信和彩信,监听短信并显示

    发送短信: String body="this is sms demo"; Intent mmsintent = new Intent(Intent.ACTION_SENDTO, ...

  4. android 监听短信并获取验证码

    最近想给 app 添加自动获取短信验证码的功能,让注册流程更加友好,在网上搜索了一些资料,主要的实现方法有两种. 第一:实现广播 BroadCastReceiver 来监听收件箱,在需要监听的地方注册 ...

  5. Android实战简易教程-第三十六枪(监听短信-实现短信验证码自动填入)

    一般用户喜欢用手机号作为用户名注册APP账号,这时一般都是通过手机验证码的方式进行验证,下面我们就研究一个非常实用的方法,通过监听短信-实现短信验证码的自动填入,提高用户体验. 首先我们看一下如何监听 ...

  6. android 监听短信并发送到服务器

    1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. 2. 应用观察者模式,监听短信数据库,操作短信内容.   实例如下: SystemE ...

  7. 小米(MIUI)手机监听短信的两种解决方案

    测试的系统为MIUI10和模拟器(Pixel 2 API 26) 应用场景:短信验证码自动填写等 方法1为监听系统短信数据库,但是存在一个问题,就是收到短信之后需要点击短信进入短信详情页面,才会触发广 ...

  8. android 监听 短信,Android短信验证码监听解决onChange多次调用的方法

    先说一句:MIUI请放弃治疗!这里给个传送门: 识别短信验证码并提取还是挺常见的一个需求.所要解决的问题主要有: 1.如何监听 2.如何提取短信中的验证码 3.监听多次调用问题 直接看下面代码吧,很明 ...

  9. android广播监听短信并显示内容

    still直接代码啦- <receiver android:name=".receive"> <intent-filter> <action andr ...

最新文章

  1. java中json重复数据结构_JS实现去除数组中重复json的方法示例
  2. 《一个操作系统的实现》——pmtest1.asm详解
  3. 关于Unity游戏开发方向找工作方面的一些个人看法
  4. Fiori应用的花瓣动画效果是怎么画出来的
  5. C# SQLite 数据库操作语句与文件视图管理器
  6. 作为程序员,你怎么看待16岁女生产子?
  7. python特征工程意义_python数据挖掘--特征工程篇(附代码)
  8. AI PRO I 第4章 译文 Behavior Selection Algorithms An Overview
  9. HDFS的Java操作
  10. bzoj1010: [HNOI2008]玩具装箱toy
  11. 【智慧城市】GIS数据获取-获取道路/水路数据
  12. CI520读卡芯片 软硬件兼容替换CV520
  13. 廊坊金彩教育:拼多多运营方案
  14. php 处理eml,php读取eml范例、php解析eml、eml解析成网页
  15. 各个城市对应的code码
  16. 控件库中的Botton控件简述
  17. 【Camera】通过查看位置方向的平面进行灵活的相机校准
  18. Flutter高德地图系列——开篇
  19. 3D城市模型、实景城市图...航测无人机轻松构建另一个世界
  20. 关于深信服面试的经历反省

热门文章

  1. java判断经纬度是否在扇形内_地图学复习 (题) (带答案)
  2. 密码学基础(二)单表---置换密码 凯撒密码 棋盘密码 乘法密码 仿射密码 多表---vigenere方阵
  3. 国内地理信息系统公司及招聘岗位要求
  4. 七万字,151张图,通宵整理消息队列核心知识点总结!这次彻底掌握MQ!
  5. 广东省谷歌地球高程DEM等高线下载
  6. 表字段的处理(Sql Server)
  7. Python Eric7+PyQt6环境配置,GUI程序开发
  8. 干货| 乐队的混音应该如何改善?职业混音师的建议 MZD Studios
  9. ROS path [0]=/opt/ros/melodic/share/rosROS path [1]=/home/huanyu-pc/robot_ws/srcROS path [2]=/opt/
  10. Python单词反写、单词倒排