您的位置:首页 > 移动开发 > Android开发

44.使用Service、BroadcastReceiver、CountDownTimer完成页面销毁不重新计时的验证码计时器

2016-08-11 11:10 393 查看
转载请注明出处 http://blog.csdn.net/qq_31715429/article/details/52180814

本文出自:猴菇先生的博客

接收验证码是一个公司很常见的功能,为了有效的防止验证码多次重复发送,在app要实现倒计时。在倒计时的时间里不能点击发送验证码的按钮,但是关闭这个页面再回来不处理的话会重新计时。在网上参考了那些用Service、Handler、CountDownTimer的例子,不是很好用,就自己写了一个自认为比较好用的

1.在MainActivity中写一个Button,实现点击跳转到NextActivity,在NextActivity中写一个Button,setText为”获取验证码”

public class NextActivity extends AppcompActivity implements View.OnClickListener {

public static final String CODE = "code";
private Button mCodeBtn;
private Intent mCodeTimerServiceIntent;

/**
* 验证码倒计时的广播
*/
private BroadcastReceiver mCodeTimerReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (CODE.equals(action)) {
//接收信息,改变button的点击状态和text
boolean isEnable = intent.getBooleanExtra(CodeTimer.IS_ENABLE, false);
String message = intent.getStringExtra(CodeTimer.MESSAGE);
mCodeBtn.setEnabled(isEnable);
mCodeBtn.setText(message);
}
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
mCodeBtn = (Button) findViewById(R.id.code_btn);
mCodeBtn.setOnClickListener(this);
//验证码计时器服务
mCodeTimerServiceIntent = new Intent(this, CodeTimerService.class);
mCodeTimerServiceIntent.setAction(CODE);
//注册接收验证码计时器信息的广播
IntentFilter filter = new IntentFilter(CODE);
registerReceiver(mCodeTimerReceiver, filter);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.code_btn://获取验证码
mCodeBtn.setEnabled(false);
startService(mCodeTimerServiceIntent);//启动服务
break;
}
}

@Override
protected void onDestroy() {
super.onDestroy();
stopService(mCodeTimerServiceIntent);
unregisterReceiver(mCodeTimerReceiver);
}


2.在CodeTimerService.java中:

/**
* 验证码计时服务
*/
public class CodeTimerService extends Service {

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
//启动计时器
String action = intent.getAction();
CodeTimer mCodeTimer = new CodeTimer(this, 30000, 100, action);
mCodeTimer.start();
}
}


3.在CodeTimer.java中:

/**
* 验证码计时器
*/
public class CodeTimer extends CountDownTimer {

/**
* 计时按钮能否点击
*/
public static final String IS_ENABLE = "is_enable";
/**
* 计时按钮显示的信息
*/
public static final String MESSAGE = "message";

private Context mContext;
private Intent mCodeReceiverIntent;

/**
* @param context           上下文
* @param millisInFuture    倒计时的时长
* @param countDownInterval 间隔时间
* @param action            用于区别不同广播的action,如果有多个互不影响的button点击发送验证码,就要有不同action的广播接收记时信息
*/
public CodeTimer(Context context, long millisInFuture, long countDownInterval, String action) {
super(millisInFuture, countDownInterval);
this.mContext = context;
mCodeReceiverIntent = new Intent(action);
}

@Override
public void onTick(long millisUntilFinished) {
//每过millisUntilFinished的间隔时间,就会发送广播
mCodeReceiverIntent.putExtra(IS_ENABLE, false);
mCodeReceiverIntent.putExtra(MESSAGE, (millisUntilFinished / 1000) + "s 后重发");
mContext.sendBroadcast(mCodeReceiverIntent);
}

// 结束
@Override
public void onFinish() {
mCodeReceiverIntent.putExtra(IS_ENABLE, true);
mCodeReceiverIntent.putExtra(MESSAGE, "获取验证码");
mContext.sendBroadcast(mCodeReceiverIntent);
}
}


这样,即便关闭NextActivity再进来,会发现倒计时还在计时,有点小瑕疵就是由于Button默认的text是“获取验证码”,再启动服务之前会有那么短暂的一瞬间能看到这段文字,我的办法是缩短CodeTimer的间隔时间,让它发送广播的间隔时间变短,但不知道这样会不会影响内存,不知道大家有没有更好的,可以一起交流学习!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐