使用短信验证设备的电话号码

2024-03-12

我正在尝试通过让设备向自身发送短信并自动检查是否已收到短信来验证 Android 设备的电话号码。我怎样才能做到这一点?


首先,这需要两个权限;一种用于发送短信,另一种用于接收短信。以下内容需要在您的 AndroidManifest.xml 中,在<manifest>标签,但在<application> tags.

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

这些都是危险的权限,因此如果您的应用程序要在 Marshmallow(API 级别 23)或更高版本上运行,并且具有targetSdkVersion23+。有关如何在运行时请求这些权限的信息可以在此开发者页面 https://developer.android.com/training/permissions/requesting.html.


您需要的 Java 类位于android.telephony包裹;具体来说android.telephony.SmsManager and android.telephony.SmsMessage。请确保您已为两者导入了正确的类。

要发送外发短信,您将使用SmsManager's sendTextMessage()方法,其签名如下:

sendTextMessage(String destinationAddress, String scAddress, String text,
                PendingIntent sentIntent, PendingIntent deliveryIntent)

此方法调用中只需要两个参数 -destinationAddress and text;第一个是电话号码,第二个是消息内容。null其余的都可以通过。例如:

String number = "1234567890";
String message = "Verification message.";
SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(number, null, message, null, null);

保持消息文本相对较短很重要,因为sendTextMessage()如果文本长度超过单个消息的字符限制,通常会失败。


要接收和阅读传入消息,您需要注册BroadcastReceiverIntentFilter为了"android.provider.Telephony.SMS_RECEIVED"行动。该接收器可以在清单中静态注册,也可以在清单上动态注册Context在运行时。

  • 在清单中静态注册 Receiver 类将允许您的应用程序接收传入消息,即使您的应用程序在接收之前碰巧被终止。然而,可能需要一些额外的工作才能获得您想要的结果。在。。之间<application> tags:

    <receiver
        android:name=".SmsReceiver"
        android:enabled="false">
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>
    

    The PackageManager#setComponentEnabledSetting()方法可用于启用和禁用此功能<receiver>如所须。

  • 动态注册 Receiver 实例Context从代码角度来说,管理起来会更容易一些,因为 Receiver 类可以成为注册它的任何组件上的内部类,因此可以直接访问该组件的成员。然而,这种方法可能不如静态注册那么可靠,因为一些不同的事情可能会阻止接收者获取广播;例如,您的应用程序的进程被终止,用户离开注册Activity, etc.

    SmsReceiver receiver = new SmsReceiver();
    IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
    registerReceiver(receiver, filter);
    

    请记住在适当的时候取消注册接收器。


在接收者的onReceive()方法,实际消息以数组形式出现byte数组附加到Intent作为额外的。解码细节因Android版本而异,但这里的结果是单个SmsMessage包含您要查找的电话号码和消息的对象。

class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        SmsMessage msg;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
            msg = msgs[0];
        } else {
            Object pdus[] = (Object[]) intent.getExtras().get("pdus");
            msg = SmsMessage.createFromPdu((byte[]) pdus[0]);
        }

        String number = msg.getOriginatingAddress();
        String message = msg.getMessageBody();
        ...
    }
}

此时,您只需比较number这里是传递给的那个sendTextMessage()称呼。建议使用PhoneNumberUtils.compare()为此,因为接收器中检索到的号码可能采用与寻址的格式不同的格式。


Notes:

  • 此处演示的示例使用单部分消息,因此应将消息文本限制为相对较短的长度。如果您确实想发送更长的消息,出于某种原因,sendMultipartTextMessage()可以用方法代替。您需要首先使用分割文本SmsManager#divideMessage(),并传递结果ArrayList到该方法,代替消息String。要在接收器中重新组装完整的消息,您必须对每个消息进行解码byte[]进入一个SmsMessage,并连接消息体。

  • 从 KitKat(API 级别 19)开始,如果您的应用程序不是默认消息应用程序,则此处使用的消息将由系统和默认应用程序保存到 SMS 提供程序,因此可供使用该消息的任何其他应用程序使用。提供者。您对此无能为力,但如果您确实想避免这种情况,可以将相同的技术用于数据短信,它不会触发默认应用程序,也不会保存到提供程序。

    为此,sendDataMessage()使用方法,这需要额外的short(任意)端口号的参数,并且消息作为byte[],而不是一个String。要过滤的操作是"android.intent.action.DATA_SMS_RECEIVED",并且过滤器将需要数据方案和权限(主机和端口)集。在清单中,它看起来像:

    <intent-filter>
        <action android:name="android.intent.action.DATA_SMS_RECEIVED" /> 
        <data
            android:scheme="sms"
            android:host="localhost"
            android:port="1234" /> 
    </intent-filter>
    

    并且里面有相应的方法IntentFilter类来动态设置它们。

    解码SmsMessage是一样的,但是消息byte[]检索到getUserData(), 而不是getMessageBody().

  • 在 KitKat 之前,应用程序负责编写自己的传出消息,因此如果您不希望有任何记录,则可以不在这些版本上执行此操作。

    传入的消息可能会被拦截,并且在主消息传递应用程序可以接收和写入它们之前,它们的广播就会中止。为了实现这一点,过滤器的优先级设置为最大,并且abortBroadcast()在接收器中被调用。在静态选项中,android:priority="999"属性被添加到开头<intent-filter>标签。动态地,IntentFilter#setPriority()方法也可以做同样的事情。

    这一点也不可靠,因为另一个应用程序总是有可能比您的应用程序具有更高的优先级。

  • 在这些示例中,我省略了在获得广播公司许可的情况下保护接收器的安全,部分是为了简单明了,部分是因为事情的本质不会让您受到任何可能造成伤害的欺骗。但是,如果您想包含此内容,那么您只需添加android:permission="android.permission.BROADCAST_SMS"归因于开口<receiver>静态选项的标签。对于动态,使用四参数过载registerReceiver()方法,通过该许可String作为第三个参数,并且null作为第四个。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用短信验证设备的电话号码 的相关文章

  • JKS、BKS 和 PKCS12 文件格式

    我正在设置一个无头服务器 该服务器使用用户提供的数据 JS CSS HTML 密钥库 为 Android 构建 Phonegap 混合应用程序 我想进行一些基本的客户端检查 以确保上传的密钥库有效 对于 JKS 文件 我发现可以通过确保提供
  • GCM 通知的自定义 UI

    In GCM Docs http developer android com google gcm gcm html其给定 它不提供任何内置用户界面或其他处理 消息数据 GCM 只是将收到的原始消息数据直接传递给 Android 应用程序
  • 如何在 Android 中以编程方式配置启动器活动?

    我正在开发一个具有两项活动的应用程序 LoginActivity and MainActivity 当用户首次打开应用程序时 他将登录并且他的凭据 用户名和令牌 保存在Preferences 现在 如果用户再次打开应用程序MainActiv
  • Android 视图展开动画

    我正在尝试编辑这些来源 https github com gabrielemariotti androiddev tree master AnimationTest创建一个适用于我所有视图的简单函数 Override public void
  • 要在进程中运行 dex,Gradle 守护进程需要更大的堆。目前有 910 MB

    实际上主要错误是 java exe完成非零退出值 1 首先我告诉你安装 studio 后遇到的每个问题 三天前 我刚刚安装了 android studio 并创建了新项目 1 首先它抛出错误 插件太旧 请更新到更新的版本 在谷歌上搜索后我改
  • 检查 Firebase 邀请是否引导至 Play 商店

    当在 Android 上使用 Firebase 邀请并在应用程序启动时访问动态链接时 有没有办法知道用户是通过邀请刚刚安装了该应用程序还是已经安装了该应用程序 非常感谢 Borja 编辑 感谢 Catalin Morosan 的回答 事实证
  • Android Activity 和 Service 关系 - 暂停后、停止后

    假设创建了 Activity A 然后 A 启动了一个 Service S 并将其自身绑定到 S S 通知 A 更新 这将导致 A 的状态发生变化 Android 暂停或停止 A 后 A 和 S 会发生什么 例如 暂停 A 是否会自动解除它
  • 如何使用RecyclerView.State保存RecyclerView滚动位置?

    我有一个关于 Android 的问题RecyclerView State http developer android com reference android support v7 widget RecyclerView State h
  • Android 可检查子菜单选项

    所以我有一个用于选项菜单项的子菜单 我想要一个可检查条目的列表 用户可以根据需要选择 取消选择多个条目 我无法解决的唯一问题是如何防止单击其中一个复选框时关闭选项菜单 我看到 PerformShortcut 有一个 FLAG PERFORM
  • 如何设置上拉刷新SwipeRefreshLayout

    我看到很多 ListView 下拉刷新的库 但是当从上到下拉动时它们是工作的 但是从下到上拉动时我如何刷新 我可以用这个做吗滑动刷新布局 http developer android com reference android suppor
  • EditText 不显示当前输入(Android 4)

    我的 Android 应用程序包含一个EditText http developer android com reference android widget EditText html查看可以在其中键入一些短消息 单行 按键盘的DONE键
  • 为什么设置 MediaRecorder 时显示错误 IllegalStateException?

    我的代码设置 MediaRecorder 它显示行集质量错误 mMediaRecorder new MediaRecorder Step 1 Unlock and set camera to MediaRecorder mCamera st
  • android sqlite 如果不存在则创建表

    创建新表时遇到一点问题 当我使用 CREATE TABLE 命令时 我的新表按应有的方式形成 但是当我退出活动时 应用程序崩溃 并且我在 logcat 中得到一个表已存在 如果我使用 CREATE TABLE IF NOT EXISTS 则
  • 从 Activity 调用选项卡式片段方法

    我有一项活动由三个片段组成 这些片段使用使用 PagerAdapter 的操作栏选项卡 我想要做的是从主活动访问活动选项卡式片段中的方法 我已经尝试了下面的代码 但这只是将片段返回为空 所以我猜它无法在选项卡中找到它 NPListFragm
  • RecyclerView 适配器的 Kotlin 泛型

    我正在尝试编写一个通用的 recyclerview 适配器 我找到了几个例子 然而 仍然无法弄清楚如何实现通用适配器 我写的代码是 open abstract class BaseAdapter
  • 如何在对话框中配置自定义按钮?

    这里我有一个自定义对话框 里面有背景 2 ImageButton 问题是 当我尝试为该按钮设置 onclick 侦听器时 程序将返回 NullPointerException 我不知道为什么会发生这种情况 无论如何如何将操作分配给对话框内的
  • 更改 Android 中突出显示文本的颜色

    我不确定这是否可能 也许有人可以纠正我 我在 Android 应用程序中有一个 EditText 视图 该视图在蓝色背景上有白色文本 当选择文本时 通过长按和编辑对话框 我希望突出显示为白色并将文本颜色更改为黑色 令人烦恼的是 似乎没有办法
  • Android VideoView 中纵向视频方向错误

    我在 Android 设备上以肖像方向拍摄新视频 如下所示 Intent intent new Intent android provider MediaStore ACTION VIDEO CAPTURE startActivityFor
  • 同时有两个操作栏(底部和向上)?

    我需要制作两个操作栏 顺便说一下我正在使用actionBarSherlock 所以我真正需要的是在正常操作栏上放置一个 欢迎屏幕 开关 并添加两个正常的 ActionBar 操作选项 与我需要的类似的是 Gmail 和地图 如下所示 htt
  • 如何检测文本是否可读?

    我想知道是否有一种方法可以告诉给定的文本是人类可读的 我所说的人类可读的意思是 它有一些含义 格式就像某人写的文章 或者至少是由软件翻译器生成的供人类阅读的文章 这是背景故事 最近我正在制作一个应用程序 允许用户将短文本上传到数据库 在部署

随机推荐

  • ViewPager 使用视图而不是片段

    I ve a ViewPager现在使用Views代替Fragments显示每个选项卡 每个选项卡都会扩展相同的布局文件 Overview In this ViewPager 我应该将地雷添加为选项卡 因此基本上每个选项卡都对应于一个特定的
  • 如何不使用gopath导入本地包

    我用过GOPATH但对于我当前面临的这个问题 它没有帮助 我希望能够创建特定于项目的包 myproject binary1 go binary2 go package1 go package2 go 我尝试了多种方法 但如何得到packag
  • 无法在 Electron 应用程序中使用 Discord OAuth2

    我正在尝试创建一个 Electron 应用程序 使用 Electron net 和 MVC 并使用 Discord 的 OAuth2 进行用户登录 然而 当加载 OAuth2 页面时 Discord 认为我使用的 Discord 安装已损坏
  • 如何捕获远程系统网络流量?

    我一直在使用wire shark来分析socket程序的数据包 现在我想看看其他主机的流量 因为我发现我需要使用只有Linux平台支持的监控模式 所以我尝试了但我无法捕获在我的网络中传输的任何数据包 列为捕获的 0 个数据包 设想 我有一个
  • 升级到 flutter 3.0.1 后更新 CocoaPods 时出错

    我在用MacBook Pro M1 芯片 OS is MacOS 蒙特利 12 3 1 今天我将flutter从2 5 4升级到3 0 1 我可以在 Android 中完美运行我的项目 但是在 iOS 中我收到以下错误 Launching
  • 关闭 seeds.rb 中的验证

    如何关闭验证Rails 3 2 3 in seeds rb 我做了这个 u1 User create email email protected cdn cgi l email protection password 123 validat
  • 如何使用 pyminizip 在 Python 3.x 中创建临时 ZIP?

    我需要创建一个临时 zip 文件来存储文件 该 ZIP 文件需要加密 所以zipfile不会在这里做的伎俩 该文件将被进一步加密 ZIP 将再次加密为另一个文件 因此压缩文件被用作减小其大小以实现更快的互联网传输以及第一层加密的一种方法 这
  • 使用 setjmp / longjmp 的通信协议和本地环回

    我使用共享内存和共享互斥体编写了一些相对简单的通信协议 但后来我想扩展支持以在使用不同运行时的两个 dll 之间进行通信 很明显 如果你有一些std vector lt int64 gt 和两个 dll 一个 vs2010 一个 vs201
  • Hive “alter table <表名称> 连接”如何工作?

    I have n large 我想要合并的小尺寸 orc 文件的数量k small 大型 orc 文件的数量 这是使用完成的alter table table name concatenateHive 中的命令 我想了解 Hive 是如何实
  • 如何在JSP页面中迭代session?

    如何迭代会话并将每个提交值保留在同一页面直到会话结束
  • GPU 上的高效全对集交集

    I have n集合 有限宇宙的子集 我想计算n n矩阵 其中 I J 条目包含集合交集的基数I并设置J n的顺序是50000 我的想法是将矩阵分割成足够小的块 以便每个条目都有一个线程 每个线程都应该使用以下方法计算交集bitwise a
  • 为什么 UIElement.MoveFocus() 不将焦点移动到 ListBox 中的下一个同级元素?

    我有以下视觉树
  • 访问 Android Stock 浏览器设置

    我想通过代码访问 和更改 库存 Android 浏览器的设置 这可能吗 如果可能的话 如何 是的 这是编程问题 我想通过代码更改它 而不是通过手动单击 对 root 设备执行此操作怎么样 Android 的操作系统级安全模型基本上可以防止这
  • PyQt 允许枚举值和字符串

    在 PySide 中 我可以通过使用获取具有可能 允许的枚举值及其字符串表示形式的字典values属性 例如 QtWidgets QMessageBox StandardButton values items 如何在 PyQt4 PyQt5
  • 为什么禁用的 JavaFX TextArea 的颜色与 TextField 不同

    我正在重新设计 JavaFX 应用程序 但我有一个问题 disabled风格 当我尝试改变 fx text fill and fx opacity settings 文本区域的文本颜色仍然比文本字段稍浅 这是我现在得到的风格 Text Fi
  • AppDelegate.m 用于 FBSDK 和 LinkingManager

    要使用 FBSDK 我需要在应用程序委托中使用此代码片段 BOOL application UIApplication application openURL NSURL url sourceApplication NSString sou
  • 使用学习的人工神经网络来解决输入

    我最近再次深入研究人工神经网络 包括进化和训练 我有一个问题 关于什么方法 如果有的话 可以解决导致目标输出集的输入 这个有名字吗 我试图寻找的一切都会导致我进行反向传播 但这不一定是我所需要的 在我的搜索中 我最接近表达我的问题的是 是否
  • 为什么 tailwind css 类名中有一个反斜杠?

    我正在尝试学习和使用最近非常流行的新实用程序框架 顺风CSS https tailwindcss com 当我使用文档中的说明编译 css 时 我看到很多 css 类名都有冒号 其中 前面有一个反斜杠 这是为什么 是为了让CSS明白有一个
  • Vagrant + Xdebug + Atom

    我有一个安装了 xdebug 的 vagrant box 在 OSX 上运行 但我很难获取 Atom xdebug 插件 php debug 连接到它 我粘贴了phpinfo 将数据输入 xdebug 验证站点 结果显示一切正常 并且您可以
  • 使用短信验证设备的电话号码

    我正在尝试通过让设备向自身发送短信并自动检查是否已收到短信来验证 Android 设备的电话号码 我怎样才能做到这一点 首先 这需要两个权限 一种用于发送短信 另一种用于接收短信 以下内容需要在您的 AndroidManifest xml