使用SMSvalidation设备的电话号码

我试图通过让设备向自己发送短信来validationAndroid设备的电话号码,并自动检查是否已收到短信。 我怎样才能做到这一点?

  • 如何监控每个发送的短信状态?
  • 如何阅读android中即将发布的消息中的消息内容?
  • Android:打开指定了多个收件人的SMS活动
  • Android与名称或地址进行短信对话
  • Android - 接收长短信(多部分)
  • Android:如何使用WhatsApp,WeChat以编程方式发送消息?
  • 通过adb shell服务调用isms Android 4.1.2发送短信
  • 从短信/彩信中启动Android应用程序?
  • 首先,这需要两个权限; 一个发送短信,一个发送短信。 以下内容需要在您的AndroidManifest.xml中,在标记之间,但在标记之外。

       

    这些都是危险的权限,因此如果您的应用程序要在Marshmallow(API级别23)或更高级别上运行,并且targetSdkVersion为23+,则需要相应地处理它们。 有关如何在运行时请求这些权限的信息,请访问此开发人员页面 。


    您需要的Java类位于android.telephony包中; 特别是android.telephony.SmsManagerandroid.telephony.SmsMessage 。 确保你已经为两者导入了正确的类。

    要发送传出SMS,您将使用SmsManagersendTextMessage()方法,该方法具有以下签名:

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

    此方法调用中只需要两个参数 – destinationAddresstext ; 第一个是电话号码,第二个是电话号码。 null可以传递给其余的。 例如:

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

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


    要接收和读取传入消息,您需要为"android.provider.Telephony.SMS_RECEIVED"操作注册带有IntentFilterBroadcastReceiver 。 此Receiver可以在清单中静态注册,也可以在运行时在Context上动态注册。

    • 在清单中静态注册Receiver类将允许您的应用程序接收传入消息,即使您的应用程序恰好在收到之前被杀死。 但是,可能需要一些额外的工作才能将结果输出到您想要的位置。 在标签之间:

            

      PackageManager#setComponentEnabledSetting()方法可用于根据需要启用和禁用此

    • Context上动态注册Receiver实例在代码方面可以更容易管理,因为Receiver类可以在任何组件上注册它时成为内部类,因此可以直接访问该组件的成员。 但是,这种方法可能不如静态注册那么可靠,因为一些不同的东西可能会阻止接收方进行广播; 例如,您的应用程序的进程被杀死,用户导航远离注册Activity等。

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

      请务必在适当时取消注册Receiver。


    在Receiver的onReceive()方法中,实际消息是作为额外附加到Intentbyte数组的数组。 解码详细信息取决于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()调用的number进行比较即可。 建议使用PhoneNumberUtils.compare() ,因为在Receiver中检索的数字可能与寻址的格式不同。


    笔记:

    • 这里演示的示例是使用一个单部分消息,因此消息文本应限制为相对较短的长度。 如果您确实想要发送更长的消息,出于某种原因,可以使用sendMultipartTextMessage()方法。 您需要先使用SmsManager#divideMessage()拆分文本,然后将生成的ArrayList传递给该方法,以代替消息String 。 要在Receiver中重新组合完整的消息,您必须将每个byte[]解码为SmsMessage ,并连接消息体。

    • 从KitKat(API级别19)开始,如果您的应用程序不是默认的消息传递应用程序,则此处使用的消息将由系统和默认应用程序保存到SMS提供程序,因此可供使用该应用程序的任何其他应用程序使用。供应商。 你可以做的并不多,但是如果你真的想避免它,那么同样的技术可以用于数据短信,它不会触发默认应用,也不会保存到提供商。

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

           

      并且IntentFilter类中有相应的方法可以动态设置它们。

      解码SmsMessage是相同的,但是使用getUserData()而不是getMessageBody()来检索消息byte[]

    • 在KitKat之前,应用程序负责编写自己的外发消息,因此如果您不想要任何记录,那么您就不能在这些版本上执行此操作。

      可以拦截传入的消息,并且在主消息传递应用程序可以接收和写入它们之前中止它们的广播。 为此,filter的优先级设置为最大值,并在接收器中调用abortBroadcast() 。 在static选项中, android:priority="999"属性被添加到开始的标记中。 动态地, IntentFilter#setPriority()方法也可以这样做。

      这根本不可靠,因为其他应用程序总是可以拥有比您更高的优先级。

    • 部分是为了简单和清晰,我省略了接收者在广播机构允许的情况下保护接收者,部分原因是因为事物的性质不会让你接受任何可能造成伤害的欺骗行为。 但是,如果您想要包含它,那么您只需要将android:permission="android.permission.BROADCAST_SMS"属性添加到静态选项的开始标记中。 对于动态,使用registerReceiver()方法的四参数重载,将该权限String作为第三个parameter passing,将null作为第四个parameter passing。