实现抢票或者秒杀之类的倒计时效果,可更改倒计时格式,需求:1天5小时8分钟22秒这种,完美解决手机息屏计时不准的问题(用wekLock)
本文章借鉴于Android定时器…做天数时间倒计时
wakeLock参考与android设置屏幕禁止休眠的方法
效果图
取一个指定时间 比如抢票(开抢)时间为2020-6-9 12:00:00
获取当前时间(网络时间)
/**
*
* @return
* 这个方法获取的结果是24小时制的,月份也正确。
* 这个方法不随手机时间的变动而变动。
* 也就是说,即使手机设置成别的时区,不是东八区,这个方法返回的也照样是北京时间!!!
*/
public static String getNetTime(){
SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
return dff.format(new Date());
}
权限
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.DEVICE_POWER"
tools:ignore="ProtectedPermissions" />
完整Activity代码
/**
* 抢票
*/
public class ScrambleTicketActivity extends MyBaseActivity<ScrambleTicketPresenter> implements ScrambleTicketContract.View {
@BindView(R.id.toolbar_image_left)
ImageView toolbarImageLeft;
@BindView(R.id.toolbar_title)
TextView toolbarTitle;
@BindView(R.id.tv_day)
TextView tvDay;
@BindView(R.id.tv_hour)
TextView tvHour;
@BindView(R.id.tv_Minute)
TextView tvMinute;
@BindView(R.id.tv_Second)
TextView tvSecond;
@BindView(R.id.btn_scrambleTicket)
Button btnScrambleTicket;
private long mDay = 0;// 天
private long mHour = 0;//小时,
private long mMin = 0;//分钟,
private long mSecond = 0;//秒
private Timer mTimer;
private Handler timeHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
computeTime();
tvDay.setText(mDay+"天");//天数不用补位
tvHour.setText(getTv(mHour)+"时");
tvMinute.setText(getTv(mMin)+"分");
tvSecond.setText(getTv(mSecond)+"秒");
if (mSecond == 0 && mDay == 0 && mHour == 0 && mMin == 0 ) {
mTimer.cancel();
}
}
}
};
@Override
public int initView(@Nullable Bundle savedInstanceState) {
return R.layout.activity_scramble_ticket; //如果你不需要框架帮你设置 setContentView(id) 需要自行设置,请返回 0
}
//相当于Oncreate
@Override
public void initData(@Nullable Bundle savedInstanceState) {
acquireWakeLock();
toolbarImageLeft.setVisibility(View.VISIBLE);
toolbarTitle.setVisibility(View.VISIBLE);
toolbarTitle.setText("抢票");
mTimer = new Timer();
//计算相差时间 StringUtils.getNetTime() 获取网络时间,上面提供了
dateDiff(StringUtils.getNetTime(), "2020-6-9 12:00:00", "yyyy-MM-dd HH:mm:ss");
//开启倒计时
startRun();
}
private String getTv(long l){
if(l>=10){
return l+"";
}else{
return "0"+l;//小于10,,前面补位一个"0"
}
}
/**
* 开启倒计时
* //time为Date类型:在指定时间执行一次。
* timer.schedule(task, time);
* //firstTime为Date类型,period为long,表示从firstTime时刻开始,每隔period毫秒执行一次。
* timer.schedule(task, firstTime,period);
* //delay 为long类型:从现在起过delay毫秒执行一次。
* timer.schedule(task, delay);
* //delay为long,period为long:从现在起过delay毫秒以后,每隔period毫秒执行一次。
* timer.schedule(task, delay,period);
*/
private void startRun() {
TimerTask mTimerTask = new TimerTask() {
@Override
public void run() {
Message message = Message.obtain();
message.what = 1;
timeHandler.sendMessage(message);
}
};
mTimer.schedule(mTimerTask,0,1000);
}
/**
* 倒计时计算
*/
private void computeTime() {
mSecond--;
if (mSecond < 0) {
mMin--;
mSecond = 59;
if (mMin < 0) {
mMin = 59;
mHour--;
if (mHour < 0) {
// 倒计时结束
mHour = 23;
mDay--;
if(mDay < 0){
// 倒计时结束
mDay = 0;
mHour= 0;
mMin = 0;
mSecond = 0;
}
}
}
}
}
/**
* 计算两个日期型的时间相差多少时间
*/
public void dateDiff(String startTime, String endTime, String format) {
// 按照传入的格式生成一个simpledateformate对象
SimpleDateFormat sd = new SimpleDateFormat(format);
long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
long nh = 1000 * 60 * 60;// 一小时的毫秒数
long nm = 1000 * 60;// 一分钟的毫秒数
long ns = 1000;// 一秒钟的毫秒数
long diff;
try {
// 获得两个时间的毫秒时间差异
diff = sd.parse(endTime).getTime()
- sd.parse(startTime).getTime();
mDay = diff / nd;// 计算差多少天
mHour = diff % nd / nh;// 计算差多少小时
mMin = diff % nd % nh / nm;// 计算差多少分钟
mSecond = diff % nd % nh % nm / ns;// 计算差多少秒
// 输出结果
Timber.e("时间相差:" + mDay + "天" + mHour + "小时" + mMin
+ "分钟" + mSecond + "秒。");
} catch (ParseException e) {
e.printStackTrace();
}
}
private void acquireWakeLock() {
if (wakeLock == null) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getCanonicalName());
wakeLock.acquire();
}
}
private void releaseWakeLock() {
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
wakeLock = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mTimer.cancel();
releaseWakeLock();
mTimer = null;
timeHandler.removeMessages(1);
timeHandler = null;
}
}
last: Layout就不给了,soeasy