前言
作业需要用到:短信验证码推送(用于注册)。了解到一个免费的手机短信推送平台,就去官网看了看相关API怎么用。
文档的无GUI调用示例,好像不是很复杂,就是有点说不清楚。自己摸索和测试了一番,也费了不少时间。
该怎么用?我不太想直接将示例复制到Activity中,跟页面的交互逻辑混杂在一起。这样很容易乱。于是想尽量把这个推送逻辑尽量抽离、独立出来。这样减少代码耦合,阅读方便,以后也方便复用。
测试我自己简单写了个界面(说实话,自己真的烦做界面,这辈子没有艺术思维。。。),主要是测试是否真的能推送功能。
效果图
MsgVerifyView
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.mob.MobSDK;
import cn.smssdk.EventHandler;
import cn.smssdk.SMSSDK;
/**
* AppCompatActivity可以改成自定义的基类
* @author passerbyYSQ
* @create 2020-05-01 14:56
*/
public abstract class MsgVerifyView extends AppCompatActivity {
private String phone;
private EventHandler eventHandler;
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
int event = message.arg1;
int result = message.arg2;
Object data = message.obj;
if (result == SMSSDK.RESULT_COMPLETE) { //回调完成
//View view = MsgVerifyHelper.this.view;
switch (event) {
case SMSSDK.EVENT_GET_VERIFICATION_CODE: {
// 发送验证码成功
onSendCodeSucceeded();
break;
}
case SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE: {
// 验证成功
onVerifySucceeded();
break;
}
case SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES: {
//返回支持发送验证码的国家列表
// 可能是号码填写错误,导致发送失败
// 前端验证把这个给排除掉了
onSendCodeFailed();
break;
}
}
}else{
//((Throwable)data).printStackTrace();
// 验证码错误
onVerifyFailed();
}
return true;
}
});
// 使用MobTech的短信推送,需要同意隐私授权。在前端界面需要强制用户同意
// 不同意不能注册
static {
MobSDK.submitPolicyGrantResult(true, null);
}
// 获取验证码
public void getCode(String phone) {
if (checkPhoneNum(phone)) {
// 请求验证码,其中country表示国家代码,如“86”;phone表示手机号码,如“13800138000”
SMSSDK.getVerificationCode("86", phone);
// 将手机号存起来
this.phone = phone;
}
}
// 验证
public void verifyCode(String code) {
if (!TextUtils.isEmpty(this.phone)) {
SMSSDK.submitVerificationCode("86", this.phone, code);
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
eventHandler=new EventHandler(){
@Override
public void afterEvent(int event, int result, Object data) {
Message msg = new Message();
msg.arg1 = event;
msg.arg2 = result;
msg.obj = data;
mHandler.sendMessage(msg);
}
};
//注册一个事件回调监听,用于处理SMSSDK接口请求的结果
SMSSDK.registerEventHandler(eventHandler);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 注销实践监听,防止内存泄漏
SMSSDK.unregisterEventHandler(eventHandler);
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
// 先检查手机号码是否正确。界面检查手机号时怎么给提示我不管,只需最后给我返回boolean
protected abstract boolean checkPhoneNum(String phone);
// 发送验证码成功
protected abstract void onSendCodeSucceeded();
// 发送失败(手机号不支持。一般不会发生)
protected abstract void onSendCodeFailed();
// 验证成功
protected abstract void onVerifySucceeded();
// 验证失败
protected abstract void onVerifyFailed();
}
MainActivity
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.ysq.app3.util.MsgVerifyView;
public class MainActivity extends MsgVerifyView {
private EditText mPhone;
private Button mGetCode; // 60s倒计时就不做了,简单测试
private EditText mCode;
private Button mVerify;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWidgets();
}
private void initWidgets() {
mPhone = findViewById(R.id.edit_phone);
mGetCode = findViewById(R.id.btn_get_code);
mCode = findViewById(R.id.edit_code);
mVerify = findViewById(R.id.btn_verify);
mGetCode.setEnabled(false);
mPhone.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
String content = editable.toString();
if (!TextUtils.isEmpty(content) &&
content.matches("^1[3|4|5|7|8][0-9]\\d{4,8}$")) {
mGetCode.setEnabled(true);
} else {
mGetCode.setEnabled(false);
}
}
});
mGetCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 获取验证码
getCode(mPhone.getText().toString());
}
});
mVerify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String code = mCode.getText().toString().trim();
if (TextUtils.isEmpty(code)) {
Toast.makeText(MainActivity.this, "请填写验证码", Toast.LENGTH_SHORT).show();
return;
}
// 验证 验证码是否正确
verifyCode(code);
}
});
}
// 虽然已经在TextChangedListener中检验过了
// 但是防止用户不填写手机号,只填写了验证码,直接点验证按钮
@Override
protected boolean checkPhoneNum(String phone) {
if (!TextUtils.isEmpty(phone) &&
phone.matches("^1[3|4|5|7|8][0-9]\\d{4,8}$")) {
return true;
} else {
Toast.makeText(this, "请输入正确的手机号", Toast.LENGTH_SHORT).show();
return false;
}
}
@Override
protected void onSendCodeSucceeded() {
Toast.makeText(this, "已成功发送验证码", Toast.LENGTH_SHORT).show();
}
@Override
protected void onSendCodeFailed() {
Toast.makeText(this, "发送验证码失败", Toast.LENGTH_SHORT).show();
}
@Override
protected void onVerifySucceeded() {
Toast.makeText(this, "验证成功", Toast.LENGTH_SHORT).show();
// 跳转页面
FirstActivity.show(this);
finish();
}
@Override
protected void onVerifyFailed() {
Toast.makeText(this, "验证码错误", Toast.LENGTH_SHORT).show();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="12dp"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/edit_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="手机号"
android:inputType="phone"
android:layout_weight="1"/>
<Button
android:id="@+id/btn_get_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取验证码"/>
</LinearLayout>
<EditText
android:id="@+id/edit_code"
android:hint="验证码"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_verify"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="验证" />
</LinearLayout>