前言:
  日常开发过程中,经常会遇到“连续点击两次退出应用”的需求(和“连续点击多次”的需求(如:手机从设置中进入开发者选项)。

直接上代码:
双击退出:

private long exitTime = 0;

    /**
* 连续点击2次退出
*/
public void exitAfterTwice() {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(getApplicationContext(), "再按一次退出程序",
Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
System.exit(0);
}
}

  

连续点击多次:

final static int COUNTS = 5;//点击次数
final static long DURATION = 3 * 1000;//规定有效时间
long[] mHits = new long[COUNTS]; /**
* 连续点击多次退出
*/
private void exitAfterMany() {
/**
* 实现双击方法
* src 拷贝的源数组
* srcPos 从源数组的那个位置开始拷贝.
* dst 目标数组
* dstPos 从目标数组的那个位子开始写数据
* length 拷贝的元素的个数
*/
System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
//实现左移,然后最后一个位置更新距离开机的时间,如果最后一个时间和最开始时间小于DURATION,即连续5次点击
mHits[mHits.length - 1] = SystemClock.uptimeMillis();//System.currentTimeMillis() if ((mHits[mHits.length - 1] - mHits[0] <= DURATION)) {
String tips = "您已在[" + DURATION + "]ms内连续点击【" + mHits.length + "】次了!!!";
Toast.makeText(MainActivity.this, tips, Toast.LENGTH_SHORT).show();
finish();
}
}

  

上述代码可直接拿过来使用。关于“连续多次点击”的代码原理作如下说明:

但是当要实现多次点击时,需要使用GoogleAPI提供的方法,原理就是在每次点击之后记录当前的点击时间,并通过System.arraycopy(…)方法来将数组左移,每点击一次就左移一次,当最后一次点击后,数组中从左到右刚好依次记录了每一次的点击时间,此时只要判断首尾两项的间隔时间是否小于设定的时间,如果小于则执行相应的逻辑。

原理图伪代码如下:

//实现左移,然后最后一个位置更新距离开机的时间,如果最后一个时间和最开始时间小于DURATION,即连续5次点击

 init:
[0,0,0,0,0]
Click 1:
[0,0,0,0,10004] Click 2:
[0,0,0,10004,100005] Click 3:
[0,0,10004,100005,100006] Click 4:
[0,10004,100005,100006,100007] Click 5:
[10004,100005,100006,100007,10008]

  

补充:
通过上述方法,细心的同学可能发现了我们在获取当前时间的毫秒数的时候有两种方式:

SystemClock.uptimeMillis() // 从开机到现在的毫秒数(手机睡眠的时间不包括在内);

System.currentTimeMillis() // 从1970年1月1日 UTC到现在的毫秒数;

一般使用的话,l这两种写法基本没有什么区别,唯一不一样的是:使用System.currentTimeMillis()获取的时间有被篡改的风险

System.currentTimeMillis() 获取的时间,是可以通过System.setCurrentTimeMillis修改的,那么,在某些情况下,一但被修改,时间间隔就不准了。
因此,为了保证时间的准确性,大家可以使用第二种方式。

还有一点,顺带说一下,大家在使用上述方法时,注意是点击屏幕退出和点击按键退出,这两种的event 不同(MotionEvent和KeyEvent),大家别搞混了。

  @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
//todo 在此处调用 }
return super.dispatchTouchEvent(ev);
} @Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
//todo 在此处调用 } return super.dispatchKeyEvent(event);
}

好了,至此完结。小伙伴有疑问的话,请留言。
---------------------
作者:游走的大千世界的烤腰子
来源:CSDN
原文:https://blog.csdn.net/zhangqunshuai/article/details/81938770
版权声明:本文为博主原创文章,转载请附上博文链接!

Android 实现连续两次点击或连续多次点击退出应用的更多相关文章

  1. React Native 适配Android物理返回键,实现连续两次点击退出

    一直使用iPhone作为测试机开发,提交给测试同事Android版本后发现很多适配问题,其中一个非常明显的是,弹出一个modal后,点击Android的返回键,modal不会消失,直接navigati ...

  2. MonkeyRunner 连续两次点击报“Error sending touch event”

    最近用monkeyrunner做自动化测试,遇到连续两次点击,第二次点击就会报错“Error sending touch event”. 具体做法如下: device.touch(234,112, ' ...

  3. Android中实现两次点击返回键退出本程序

    1,当用户使用我们的app的时候,有时候无意的或者不是有心的按下了我们的返回键,这时候为了更好的用体验,我们需要让用户再一次确定一下,以便判断用户的真实意图 代码如下: //该功能实现退出时提示的功能 ...

  4. 关于android app两次点击返回键退出的处理

    现在的android app在开发时,引入了两次点击返回键退出app的设计 为了避免用户误触,这个设计很人性化 中文网上社区有些同学贴了一些实现的例子,我觉得不是很好 代码如下 public bool ...

  5. Android防止按钮快速重复点击

    在用户使用 Android 应用的时候,经常会出现过快且多次点击同一按钮的情况,一方面这是因为应用或手机当前有些卡顿,另一方面也可能是由于很多应用并没有设置按钮点击时的 selector 或者其它按钮 ...

  6. 【转】在Android Studio中下载Android SDK的两种方式(Android Studio3.0、windows)

    在Android Studio中下载Android SDK的两种方式(Android Studio3.0.windows) 方式一.设置HTTP Proxy1. 打开Settings2. 点击HTTP ...

  7. android去掉button默认的点击阴影

    查了资料,发现别人都是说加一个style属性. style="?android:attr/borderlessButtonStyle" 加上了确实管用,但是我绝不是不求甚解的人.追 ...

  8. Android学习—下载Android SDK的两种方式

    在Android Studio中下载Android SDK的两种方式 Android studio下载地址:http://www.android-studio.org/ 方式一.设置HTTP Prox ...

  9. android环境下两种md5加密方式

    在平时开发过程中,MD5加密是一个比较常用的算法,最常见的使用场景就是在帐号注册时,用户输入的密码经md5加密后,传输至服务器保存起来.虽然md5加密经常用,但是md5的加密原理我还真说不上来,对md ...

随机推荐

  1. sublime修改侧边栏字体

    安装了sublime的material主题后,侧边栏的字体特别小,设置方法如下: 安装插件 用上面的插件打开 Material-Theme.sublime-theme 如下 { "class ...

  2. Spring MVC全局异常处理

    继承HandlerExceptionResolver接口实现自己的处理方法,如: public class MyHandlerExceptionResolver implements HandlerE ...

  3. MySQL--表操作(innodb表字段数据类型、约束条件)、sql_mode操作

    一.创建表的完整语法 #[]内的可有可无,即创建表时字段名和类型是必须填写的,宽度与约束条件是可选择填写的.create table 表名(字段名1 类型[(宽度) 约束条件],字段名2 类型[(宽度 ...

  4. mybatis打印SQL日志

    在配置的log4j输出时,不能打印SQL信息,在mybatis-config.xml中添加如下配置即可 <settings> <setting name="logImpl& ...

  5. gdb 调试程序步骤

    在程序a.c编译过程中加入调试信息: g++ -g -o a.debug a.c 启动gdb,在终端下输入:gdb 此时启动了gdb,在gdb中加载需要调试的程序,在终端输入命令: file a.de ...

  6. ASP.NET MVC5入门3之登录验证

    参考: HTML页面模版: http://www.ui.cn/detail/70262.html(第38个) MVC后台代码参考: http://www.oschina.net/p/nfine 开发环 ...

  7. CF 489C 暴力处理

    题意: 给你 数的长度 m, 数的每个数的和 Sum: 输出 这个数最小值 和最大值 #include<bits/stdc++.h> using namespace std; int ma ...

  8. oracle数据库链路和同义词

    Oracle数据库链路的建立和使用 先来一个例子: --创建数据库链路create   public   database link xaffdblink connect to zdcl identi ...

  9. Confluence 6 警告的类型

    有下面的一些类型的警告. 警告和知识库(Alert and KB) 级别(Level) 默认阈值(Default threshold) 可配置(Configurable) Low free disk ...

  10. Confluence 6 数据库表-系统信息(System information)

    这些表格有存储数据相关的状态和 Confluence 站点的相关配置信息. confversion 被用来在升级系统的时候确定那个数据库的版本应该使用,这个表格只对数据库升级有影响. pluginda ...