公司的APP有个需求为他添加类似于支付宝的手势密码验证功能效果图如下

首先我们要分析三个问题:
1.手势密码的作用是什么?
2.在什么时候启动?
3.启动之后干什么?


1.手势密码的作用是什么?
这里很容易解答,为了APP二次启动进入进行验证是否正常授权的用户。
2.在什么时候启动?
如果是对安全性比较高的应用这里推荐应用处于后台运行状态下马上进入安全验证状态(也就是需要输入手势密码才能回到之前的Activity
另一种安全性能要求是不那么高的用户在锁屏之后再次回到应用启动验证即可。
3.启动之后干什么?
手势验证成功就进入打开APP,验证失败就不让动~
关于手势验证代码网上一大堆,我这里主要讲解如何集成到我们的app中,毕竟在app开发中会用就行:orz

首先我们要获取APP的状态是否进入后台等,这里有几种思路:
1.监听HOME键power键跟返回键操作
2.监听锁屏解锁广播
3.自定义广播实现监听
由于软件需求的安全性不高,我选择了第二种:监听解锁广播
android.intent.action.USER_PRESENT 用户操作进行解锁时会触发
我们首先编写一个CustomReceiver代码如下

public class CustomReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (intent.getAction().equals("android.intent.action.USER_PRESENT") && SPUtils.getGestureCode(context) == HAS_GESTURE) {Logger.e("存在锁屏密码");SPUtils.put(context, "isLock", true);Intent intent1 = new Intent(context, SignUserGestureActivity.class);intent1.setFlags(FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent1);} else {Logger.e("不存在锁屏密码" + SPUtils.getGestureCode(context));SPUtils.put(context, "isLock", false);}
}

然后在清单文件申明

 <receiver android:name=".broadcast.CustomReceiver"><intent-filter><action android:name="android.intent.action.USER_PRESENT"/></intent-filter>
</receiver>

监听广播并且判断当前手势密码是否存在,存在跳转到验证Activity。注意这里的setFlags在广播中启动activity必须设置flag为FLAG_ACTIVITY_NEW_TASK
否则报错如下

Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

锁屏后启动验证解决了。现在的问题,启动后干什么?两种情况
1.APP未启动过,处于非运行状态,跳转至启动动画即可
2.运行时,恢复到原来的Activity
第一种情况直接启动Intent的跳转就好了
第二种情况怎么记录处于栈顶的Activity?
我这里提供一个办法在每个activity的onResume方法中添加当前的Activity

    //全局静态集合保留所有的activitypublic static List<Activity> activitys=new ArrayList<>();

当手势密码验证通过取得最后一个activity的名字去启动,代码如下

//程序处于运行状态只要取出最后一个运行的activity就好了if(activitys.size()!=0){lastactivityname = activitys.get(activitys.size()-1).getComponentName();Logger.e(activitys.size()+"");Intent intent = new Intent();intent.setComponent(lastactivityname);intent.setFlags(FLAG_ACTIVITY_CLEAR_TOP);//清除当前activity,让之前启动的Activity处于栈顶startActivity(intent);}else {//程序此时没有运行启动欢迎页面即可Intent intent = new Intent(this,ShowFirstActivity.class);startActivity(intent);}

注意这里的FLAG_ACTIVITY_CLEAR_TOP


这里贴上Intent 的常见Flag

先首先简单介绍下Task和Activity的关系

Task就像一个容器,而Activity就相当与填充这个容器的东西,第一个东西(Activity)则会处于最下面,最后添加的东西(Activity)则会在最上面。从Task中取出东西(Activity)是从最顶端取出,也就是说最先取出的是最后添加的东西(Activity),以此类推,最后取出的是第一次添加的Activity,而Activity在Task中的顺序是可以控制的,在Activity跳转时用到Intent Flag可以设置新建activity的创建方式;

FLAG_ACTIVITY_NEW_TASK

默认的跳转类型,它会重新创建一个新的Activity,不过与这种情况,比如说Task1中有A,B,C三个Activity,此时在C中启动D的话,如果在AndroidManifest.xml文件中给D添加了Affinity的值和Task中的不一样的话,则会在新标记的Affinity所存在的Task中压入这个Activity。如果是默认的或者指定的Affinity和Task一样的话,就和标准模式一样了启动一个新的Activity.

FLAG_ACTIVITY_SINGLE_TOP

这个FLAG就相当于加载模式中的singletop,比如说原来栈中情况是A,B,C,D在D中启动D,栈中的情况还是A,B,C,D

FLAG_ACTIVITY_CLEAR_TOP

这个FLAG就相当于加载模式中的SingleTask,这种FLAG启动的Activity会把要启动的Activity之上的Activity全部弹出栈空间。类如:原来栈中的情况是A,B,C,D这个时候从D中跳转到B,这个时候栈中的情况就是A,B了

FLAG_ACTIVITY_BROUGHT_TO_FRONT

这个网上很多人是这样写的。如果activity在task存在,拿到最顶端,不会启动新的Activity。这个有可能会误导大家! 他这个FLAG其实是这个意思!比如说我现在有A,在A中启动B,此时在A中Intent中加上这个标记。此时B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT方式启动,此时在B中再启动C,D(正常启动C,D),如果这个时候在D中再启动B,这个时候最后的栈的情况是 A,C,D,B。如果在A,B,C,D正常启动的话,不管B有没有用FLAG_ACTIVITY_BROUGHT_TO_FRONT启动,此时在D中启动B的话,还是会变成A,C,D,B的。

FLAG_ACTIVITY_NO_USER_ACTION

onUserLeaveHint()作为activity周期的一部分,它在activity因为用户要跳转到别的activity而要退到background时使用。比如,在用户按下Home键,它将被调用。比如有电话进来(不属于用户的选择),它就不会被调用。
那么系统如何区分让当前activity退到background时使用是用户的选择?

它是根据促使当前activity退到background的那个新启动的Activity的Intent里是否有FLAG_ACTIVITY_NO_USER_ACTION来确定的。

注意:调用finish()使该activity销毁时不会调用该函数

FLAG_ACTIVITY_NO_HISTORY

意思就是说用这个FLAG启动的Activity,一旦退出,它不会存在于栈中,比方说!原来是A,B,C这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。

至此为应用添加手势密码功能的逻辑就完成了。欢迎留言更好的方法。

为安卓应用添加手势密码功能,遇到的一些问题以及解决方法相关推荐

  1. Chrome浏览器自带翻译功能不能使用了?看我的解决方法

    Chrome浏览器自带翻译功能不能使用了?看我的解决方法 问题 这几天,想使用Chrome浏览器自带的翻译功能时突然无法使用了!(如下图所示)一搜才知道谷歌暂停的翻译功能对中国的支持,要重新换一个翻译 ...

  2. android usb win7,安卓手机USB数据线连接不上win7系统电脑的解决方法

    许多用户都喜欢将手机连接电脑来解决一些问题或者上传一些图片到电脑中存储,不过近日有使用安卓手机的用户在将usb数据线连接电脑的时候,发现无法连接,导致无法上传手机照片图片到电脑上和传送apk手机软件到 ...

  3. mysql 5.7 1054_MySQL5.7更改密码时出现ERROR 1054 (42S22)的解决方法

    MySQL5.7更改密码时出现ERROR 1054 (42S22)的解决方法 发布时间:2020-10-14 16:01:38 来源:脚本之家 阅读:81 作者:剑侠365 新安装的MySQL5.7, ...

  4. centos配置ssh免密码登录后仍要输入密码的解决方法

    From: https://blog.csdn.net/zwbill/article/details/80448939 前言 在搭建Linux集群服务的时候,主服务器需要启动从服务器的服务,如果通过手 ...

  5. sql服务器文件夹共享,sqlserver2017共享功能目录路径不可改的解决方法

    注意:什么路径不可改就搜索该路径进行删除注册表记录,然后重启电脑 按 win键盘+R输入 regedit 进去注册表,点击计算机按"编辑"-->查找下一个 需要等一些时间 结 ...

  6. XP添加权限时提示:无法显示用户选项对话框的解决方法!

    症状: 打开共享权限添加用户无法打开 出现" 安全:无法显示用户选项对话(null)" 如图: 解决方法: 第一种方法是: 将别人WINDOWS SYSTEM32 文件夹下的ric ...

  7. Xshell连接linux(deepin)时提示ssh服务器拒绝了密码,请再试一次解决方法

    Xshell连接linux(deepin)时提示ssh服务器拒绝了密码,请再试一次解决方法 参考文章: (1)Xshell连接linux(deepin)时提示ssh服务器拒绝了密码,请再试一次解决方法 ...

  8. 使用 ADOX 将 Table 添加到 Catalog 时报“类型无效”的原因和解决方法

    http://blog.csdn.net/kfhzy/article/details/6020283 http://blog.csdn.net/kfhzy/article/details/602054 ...

  9. 安卓手机USB无法共享、上网或卡顿的解决方法

    安卓手机USB无法共享.上网或卡顿的解决方法 参考文章: (1)安卓手机USB无法共享.上网或卡顿的解决方法 (2)https://www.cnblogs.com/tmdsleep/p/9190898 ...

最新文章

  1. 疑问:undistortPoints()与remap()畸变校正后,结果相差很大
  2. 构建空列表的两种法是_Python 基础3之列表
  3. react 动态路 嵌套动子路由_2020年,我是如何从一名Vueer转岗到React阵营
  4. CSS实现垂直居中的方法
  5. Linux 101 Hacks __To be continued
  6. 文件上传控件 自定义样式
  7. Coin3d用vs2010编译
  8. Java Web之EL表达式和JSTL
  9. 每个人都能 DIY 的 苹果电脑
  10. win10c盘扩容_Win10磁盘分区工具-无损分区助手
  11. 设计模式:委托和代理
  12. MR-GMMapping:基于高斯混合模型的通信高效多机器人映射系统
  13. h2o.ai源码解析(1)—项目简介
  14. 数学分析第一型曲面积分2021.6.5
  15. 利用单片机最小系统外接DS12C887 在LCD1602上显示实时时钟
  16. MT4如何设置手机app通知
  17. 对计算机会计上机课的心得,会计电算化的心得体会
  18. 1688、淘宝、拼多多的商品类目包、上传类目包
  19. Linux部署iwebshop
  20. dx12 龙书第十九章学习笔记 -- 法线贴图

热门文章

  1. 开源自制6通道航模遥控器,Arduino Pro Mini NRF24L01模块
  2. canvas使用技巧大全
  3. TalkingData:用好大数据,为企业转型赋能
  4. 象SaaS一样用亚马逊Kinesis Analytics做大数据分析
  5. so 问题来了,你现在值多少钱?
  6. MySQL Study案例之--快速了解MySQL服务器
  7. 中介者模式小记【原创】
  8. 从零开始学习OpenGL ES之五 – 材质
  9. SQL Server之日期和时间函数
  10. 二、用FTP同步服务器