[Android]利用Andorid广播实现短信验证码自动填写
本帖最后由 wushaominkk 于 2018-6-5 09:21 编辑广播
安卓广播BroadCast是安卓四大组件之一,在 Android 开发中,BroadcastReceiver 的应用场景非常多,现在我们用它来做一个简单的短信验证码自动填写
准备
我们先来理一下思路(思路很重要,大家不要一开始就上来敲代码,一步一步来)
流程大概是这样,我们在第一个app点击获取验证码后,另一个app就发出一条验证码,我们在第一个app中拿到验证码并且自动填到输入框中。
两个app ,一个叫verificationcodedome,接收验证码。另一个 sendSMSdome,发送验证码信息,布局很简单,就几个按钮个几个输入框
verificationcodedome
MainActivity.java
package activitydome.ysl.com.verificationcodedome;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.CountDownTimer;
import android.provider.Telephony;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button btn;
EditText editText;
private static MainActivity mainActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainActivity = this;
editText = findViewById(R.id.edit);
btn = findViewById(R.id.btn);
//点击获取验证码按钮
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//启动倒计时
new MyCountDownTimer(60000,1000).start();
//发一条短信另一个手机,告诉它我需要一条验证码
sendSMS();
}
});
}
public static MainActivity getInstace(){
return mainActivity;
}
public void updateEditText(final String code){
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"验证码来了:"+code,Toast.LENGTH_SHORT).show();
editText.setText(code);
}
});
}
//发送信息的代码
public void sendSMS(){
SmsManager manager = SmsManager.getDefault();
PendingIntent pi = PendingIntent.getActivity(this,0,new Intent(this,Telephony.Sms.class),0);
//给5556号码发一条短信,内容为2AB25D0130C04299,内容随意,后面我们要在另一个app判断短信内容是否为这个字符串,
manager.sendTextMessage("5556",null,"2AB25D0130C04299",pi,null);
}
//实现点击按钮倒计时效果
class MyCountDownTimer extends CountDownTimer{
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
btn.setClickable(false);
btn.setText(millisUntilFinished/1000+"s");
}
@Override
public void onFinish() {
btn.setClickable(true);
btn.setText("重新获取验证码");
}
}
}
新建一个包broadcast,在里面新建一个SMSReceiver广播接收类
SMSReceiver.java
package broadcast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;
import activitydome.ysl.com.verificationcodedome.MainActivity;
/**
* Created by 10734 on 2018/5/22 0022.
*/
public class SMSReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//拿到短信对象数组
Object [] objects = (Object[]) intent.getExtras().get("pdus");
//循环遍历每个短信对象
for(Object obj : objects){
byte [] bytes = (byte[]) obj;
//短信对象转换成SmsMessage
SmsMessage message = SmsMessage.createFromPdu(bytes);
//获得发送号码
String number = message.getOriginatingAddress();
//获得短信内容
String msg = message.getMessageBody();
Log.i("信息内容:" ,number+"_"+ message.getMessageBody());
//如果号码是验证码发送者的号码,就提取验证码
if(number.equals("15555215556")){
//比如短信内容是:(你的验证码为:125314),用substring提取“ :”后面的6个数字
String code = msg.substring(msg.indexOf(":")+1);
Log.i("提取的验证码:" , message.getMessageBody());
//通过MainActivity把验证码更新到EditText中
MainActivity.getInstace().updateEditText(code);
}
}
}
}
广播和Activity一样,需要在注册 ,注册分动态注册和静态注册,我们使用静态注册,也就是在AndroidManifest.xml中注册
<receiver android:name=".broadcast.SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
这样只要你手机使用短信,这个类就会拦截它,你可以在里面做你想做的事情
还有权限,在Android6.0之后权限的管理也越加严格,我们需要配置权限
权限
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
好了,第一个应用就差不多了
sendSMSDome
MainActivity.java
package activitydome.ysl.com.sendmsmdome;
import android.app.PendingIntent;
import android.content.Intent;
import android.provider.Telephony;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
EditText phonenumber_edit,context_edit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
phonenumber_edit = findViewById(R.id.phonenumber_edit);
context_edit = findViewById(R.id.context_edit);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String phonenumber = phonenumber_edit.getText().toString();
String context = context_edit.getText().toString();
if("".equals(phonenumber) || "".equals(context)){
Toast.makeText(MainActivity.this,"号码和内容不能为空",Toast.LENGTH_SHORT).show();
}else {
sendSMS(phonenumber,context);
}
}
});
}
//发送验证码
public void sendSMS(String phonenumber,String context){
SmsManager manager = SmsManager.getDefault();
String message = "你的验证码为:"+context;
PendingIntent pi = PendingIntent.getActivity(this,0,new Intent(this,Telephony.Sms.class),0);
manager.sendTextMessage(phonenumber,null,message,pi,null);
Toast.makeText(MainActivity.this,"发送成功",Toast.LENGTH_SHORT).show();
}
}
SMSReceiver.java
package activitydome.ysl.com.sendmsmdome.broadcast;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Telephony;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
import java.util.Random;
/**
* Created by 10734 on 2018/5/22 0022.
*/
public class SMSReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
SmsManager manager = SmsManager.getDefault();
Object [] objects = (Object[]) intent.getExtras().get("pdus");
for(Object obj : objects){
byte [] bytes = (byte[]) obj;
SmsMessage message = SmsMessage.createFromPdu(bytes);
String str = message.getMessageBody();
String number = message.getOriginatingAddress();
Log.i("收到请求号码:" ,number);
//如果短信内容是2AB25D0130C04299,就给这个号码发一条验证码
if(str.equals("2AB25D0130C04299")){
PendingIntent pi = PendingIntent.getActivity(context,0,new Intent(context,Telephony.Sms.class),0);
Random random= new Random();
int code = random.nextInt(999999);
if(code < 100000){
code = code + 100000;
}
String msg = "您的验证码为:"+code;
Log.i("sendSMS", "给号码"+number+"发送验证码="+code);
Toast.makeText(context,"自动发送验证码", Toast.LENGTH_SHORT).show();
manager.sendTextMessage(number,null,code+msg,pi,null);
}
}
}
}
同样的要注册和配置权限
注册
<receiver android:name=".broadcast.SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
权限
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
这样第二个应用也OK了
效果
注意
android系统版有可能不弹出授权管理,那我们手动给权限
拖动app,应用信息->权限->允许短信
不怎么会写教程,感觉很啰嗦,大家有什么问题可以问我,也许有个好的代码可以 实现,大家有建议可以一起讨论,最后祝大家好好学习天天向上!!!
我用的AndroidStudio是3.0的,导入的时候修改一下gradle文件Model sendsmsdome是发送短信的APP,verificationcodedome是接收验证码的APP
等我把工程打包好再上传
学习感谢分享 图片不能直接粘贴,需要上传才可以,看这个帮助学习修改下:https://www.52pojie.cn/misc.php?mod=faq&action=faq&id=29&messageid=36 写得不错,thx:
总结下,学到的知识点:
1.如何发送短信。(权限+SmsManager)
2.倒计时的实现。(CountDownTimer)
3.如何接受短信并解析内容。(aciton为Telephony.SMS_RECEIVED广播) Hmily 发表于 2018-5-23 14:39
图片不能直接粘贴,需要上传才可以,看这个帮助学习修改下:https://www.52pojie.cn/misc.php?mod=faq&acti ...
嗯 谢啦。我重新编辑 验证码能不能发送文字,求楼主教 wangjin52748232 发表于 2018-5-27 04:47
验证码能不能发送文字,求楼主教
也可以不过你要在代码里修改提取验证码的规则 766616786扣 你有软件成型的吗?求 wangjin52748232 发表于 2018-5-28 14:47
你有软件成型的吗?求
有 我有源码的 等我打包上传上来 wangjin52748232 发表于 2018-5-28 14:47
你有软件成型的吗?求
我源码上传好了
页:
[1]
2