验证码倒计时如图
activity_register_next.xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_back"
android:layout_width="27dp"
android:layout_height="27dp"
android:layout_marginLeft="12dp"
android:layout_marginTop="11dp"
android:src="@drawable/back" />
<TextView
android:id="@+id/tv_dx_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:layout_marginTop="11dp"
android:text="下一步"
android:textColor="@color/Qblue"
android:textSize="16sp" />
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="验证短信"
android:textColor="#080808"
android:textSize="26sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="验证码"
android:textColor="@color/black"
android:textSize="22sp" />
<EditText
android:id="@+id/et_yzm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:background="@color/touming"
android:hint="短信验证码"
android:inputType="number" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:background="@drawable/shape_btn"
android:padding="5dp"
android:text="获取验证码"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.05dp"
android:layout_marginTop="10dp"
android:background="@color/view_color"></View>
</LinearLayout>
package com.fb.hckjfb.utils;
import android.graphics.Color;
import android.os.CountDownTimer;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.widget.TextView;
/**
*验证码倒计时类
*/
public class CountDownTimerUtils extends CountDownTimer {
private TextView mTextView;
public CountDownTimerUtils(TextView textView, long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
this.mTextView = textView;
}
@Override
public void onTick(long millisUntilFinished) {
mTextView.setClickable(false); //设置不可点击
mTextView.setText(millisUntilFinished / 1000 + "秒后重新发送"); //设置倒计时时间
SpannableString spannableString = new SpannableString(mTextView.getText().toString()); //获取按钮上的文字
ForegroundColorSpan span = new ForegroundColorSpan(Color.WHITE);
spannableString.setSpan(span, 0, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);//将倒计时的时间设置为红色
mTextView.setText(spannableString);
}
@Override
public void onFinish() {
mTextView.setText("重新获取");
mTextView.setClickable(true);//重新获得点击
}
}
点击按钮后调用并请求服务器(请求服务器发验证码这里用的GET请求):
//获取验证码倒计时60秒
CountDownTimerUtils mCountDownTimerUtils = new CountDownTimerUtils(tv_time, 60000, 1000);
mCountDownTimerUtils.start();
//向服务器发送获取验证码的请求
new Thread(new Runnable() {
@Override
public void run() {
try {
@SuppressWarnings("deprecation")
String PATH = "这里是你请求服务器的url" + URLEncoder.encode(phone);
URL url = new URL(PATH);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//配置参数
connection.setRequestMethod("GET");
connection.setConnectTimeout(TIME_OUT);
connection.setReadTimeout(TIME_OUT);
//打开链接
connection.connect();
//获取状态码
int responseCode = connection.getResponseCode();
if (200 == responseCode) {
//获取返回值
InputStream inputStream = connection.getInputStream();
//将字节流输入流转换为字符串
data = StreamUtils.inputSteam2String(inputStream);
Log.d(data, "请求服务器获取验证码");
handler.obtainMessage(RESULT_OK, data).sendToTarget();
} else {
handler.obtainMessage(RESULT_CANCELED, responseCode).sendToTarget();
}
} catch (MalformedURLException e) {
e.printStackTrace();
handler.obtainMessage(RESULT_CANCELED, e.getMessage()).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
handler.obtainMessage(RESULT_CANCELED, e.getMessage()).sendToTarget();
}
}
}).start();
下面是解析服务器返回的数据并通知用户:
private final static int TIME_OUT = 1000;//超时时间
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RESULT_OK:
JSONObject obj = null;
try {
obj = new JSONObject(data);
int code = obj.getInt("code");
if (code == 1) {
Toast.makeText(getBaseContext(), "该手机号已被注册", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(), "验证码已发送……", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
break;
case RESULT_CANCELED:
Toast.makeText(getBaseContext(), "服务器繁忙……", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
下面是注册时的POST请求(因为向服务器提交的有密码所以用POST方式)
if (!TextUtils.isEmpty(yzm)) {
//请求服务器
new Thread(new Runnable() {
@Override
public void run() {
String PATH = "这里是发送给服务器的url";
URL url;
try {
url = new URL(PATH);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//配置参数
connection.setRequestMethod("POST");
/*
* 设置该参数,才能以流的形式提交数据 150. * 需要将要提交的数据转换为字节输出流
* */
connection.setDoInput(true);
connection.setConnectTimeout(TIME_OUT);
connection.setReadTimeout(TIME_OUT);
//将提交的参数进行URL编码
String param = "phone=" + URLEncoder.encode(phone) + "&password=" + URLEncoder.encode(pwd) + "&phoneCode=" + URLEncoder.encode(yzm);
Log.d("手机号:" + phone + " 密码:" + pwd + " 验证码:" + yzm, "run: ");
//设置请求体的长度
connection.setRequestProperty("Content-Length", param.length() + "");
//设置请求属性,相当于封装http的请求头参数
connection.setRequestProperty("Context-Type", "application/x-www-form-urlencoded");
connection.connect();
//获取输出流
OutputStream os = connection.getOutputStream();
//通过输出流把数据交出去
os.write(param.getBytes());
//关闭输出流
os.close();
//获取状态码
int responseCode = connection.getResponseCode();
if (200 == responseCode) {
//获取返回值
InputStream inputStream = connection.getInputStream();
//将字节流输入流转换为字符串
String data = StreamUtils.inputSteam2String(inputStream);
Log.d(data, "请求服务器注册");
handler2.obtainMessage(RESULT_OK, data).sendToTarget();
} else {
handler2.obtainMessage(RESULT_CANCELED, responseCode).sendToTarget();
}
} catch (MalformedURLException e) {
handler2.obtainMessage(RESULT_CANCELED, e.getMessage()).sendToTarget();
e.printStackTrace();
} catch (IOException e) {
handler2.obtainMessage(RESULT_CANCELED, e.getMessage()).sendToTarget();
e.printStackTrace();
}
}
}).start();
对返回信息进行处理:
private Handler handler2 = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RESULT_OK:
JSONObject obj = null;
try {
obj = new JSONObject(data);
int code = obj.getInt("code");
if (code == 1) {
Toast.makeText(getBaseContext(), "账号已存在", Toast.LENGTH_SHORT).show();
} else if (code == 0) {
Toast.makeText(getBaseContext(), "注册完成,请登录", Toast.LENGTH_SHORT).show();
//验证成功后跳转到登录页面
startActivity(new Intent(getBaseContext(), LoginActivity.class));
finish();
} else if (code == -1) {
Toast.makeText(getBaseContext(), "系统错误", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
break;
case RESULT_CANCELED:
Toast.makeText(getBaseContext(), "服务器繁忙……", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
其中还有个StreamUtils 读取返回值得类
package com.fb.hckjfb.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 连接服务器读取输出流的类
*/
public class StreamUtils {
public static String inputSteam2String(InputStream inputStream) {
BufferedReader read = new BufferedReader(new InputStreamReader(inputStream));
String data = null;
try {
data = read.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
}