1. 程序锁原理

1.1 实现效果:

在用户打开一个应用时,若此应用是我们业务内的逻辑拦截目标,那就在开启应用之后,弹出一个输入密码的界面,输入密码正确则进入目标应用。若不输入直接按返回键,则直接返回桌面。

1.2 实现原理:

实时检测栈顶Activity的包名,如果和我们预置的包名相符(可用SQLite数据库对要进行匹配的包名进行信息存储),则新开一个Activity任务栈,将拦截画面置于用户面前。只有在用户输入密码,并且验证成功后,才“放行”。本文原创,转载请注明出处:Android开发——程序锁的实现(可用于开发钓鱼登录界面)_SEU_Calvin的博客-CSDN博客

2. 程序锁实现

1. 代码实现比较简单,获取到topActivity的包名即可进行程序锁的逻辑判断。

注意,当判断某个应用需要保护时,因为服务是没有任务栈信息的,所以在服务里开启Activity,需要指定这个Activity运行的任务栈。这里指定Flag为Intent.FLAG_ACTIVITY_NEW_TASK。这时候就会有一个Activity挡在被打开的应用前面,完成程序锁的功能。

当然,监听到用户开启QQ时,跳出一个我们“自定义”的登录界面,这就是所谓的钓鱼了,可以拿到用户的用户名和密码。实现起来还是比较简单的。不过需要申请这个权限<uses-permission android:name="android.permission.GET_TASKS" />

                    while (flag){List<ActivityManager.RunningTaskInfo> runningTasks = am.getRunningTasks(1);//最近操作的任务栈runningTasks.get(0)//topActivity栈顶 baseActivity栈底String packageName = runningTasks.get(0).topActivity.getPackageName();if(protectPacknames.contains(packageName)){//判断应用是否需要临时停止保护if(packageName.equals(tempStopEnterPwPackageName)){}else{ Intent intent = new Intent(getApplicationContext(),EnterAppLockPwActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.putExtra("packageName",packageName);//用户在拦截界面展示被保护的应用信息startActivity(intent);}}try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}

2. tempStopEnterPwPackageName的概念。

为了防止用户验证成功,进入被锁应用后,继续弹出登录验证界面,(因为我们做了死循环),那么就该在合适的时机跳出循环,在本例中肯定是当用户验证成功时,我们采用发送自定义广播的方式来解决,在服务里代码动态注册此广播的Broadcast Receiver,从而使该应用成为tempStopEnterPwPackageName,暂时处于不被锁的状态即可。自定义广播发送时,将该应用的包名放入Extra中进行传递即可。

                    Intent intent = new Intent();intent.setAction("com.example.user.mobilesafe.tempstop");intent.putExtra("packageName",packageName);sendBroadcast(intent);finish();

3.最后需要处理的是,在EnterAppLockPwActivity界面进行Back键的屏蔽操作,原因很简单,就不用多说了。这里实现Back键回桌面,因为不会执行OnDestroy方法,但是会执行onStop方法,因此我们把finish()放在onStop方法中实现。

    @Overridepublic void onBackPressed() {Intent intent = new Intent();intent.setAction("android.intent.action.MAIN");intent.addCategory("android.intent.category.HOME");intent.addCategory("android.intent.category.DEFAULT");intent.addCategory("android.intent.category.MONKEY");startActivity(intent);}@Overrideprotected void onStop() {super.onStop();finish();}

3. BUG处理

(1)由于任务栈的原因,有可能出现的BUG为,打开程序锁所在应用的其他界面A,按Home键,返回桌面,再打开被保护的应用,验证通过后,会进入A界面,这是因为我们没有给EnterAppLockPwActivity指定一个新的任务栈。可以通过指定Activity启动模式来解决该问题。

(2)再一个BUG是用户打开程序锁所在应用的其他界面A,按Home键返回桌面,再打开被保护的应用,在不输入密码直接按Back键返回桌面,长按Home键,弹出用户最近打开过的Activity列表。用户认为从该列表点开进入的就应该是应用,那么用户想再次打开程序锁应用时,很显然,会弹出我们的EnterAppLockPwActivity界面(因为这个界面本身就属于我们的程序,从Activity列表里看起来就像是程序锁本身这个应用),这就给用户带来了困扰。针对上述两个BUG,可以通过屏蔽应用在Activity列表里显示来解决。

<activity android:name=".EnterAppLockPwActivity"
android:launchMode="singleInstance"
android:excludeFromRecents="true"/>

(3)我们有时需要方便用户开启和关闭服务,而设置一个开关,为了防止开关显示开启但服务实际上没有Alive,无论什么时候需要展示这个开关设置界面时,我们都进行此服务“是死是活”的判断。再修改界面控件显示即可。

public class IsServiceAliveUtils {public static boolean isServiceRunning(Context context,String serviceName){ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List<RunningServiceInfo> infos =  am.getRunningServices(100);for(RunningServiceInfo info : infos){String name = info.service.getClassName();if(serviceName.equals(name)){return true;}}return false;}
}

4.  防护措施

如果自己的应用的登录界面被一个恶意应用的拦截Activity给劫持了,就会存在用户帐号密码被盗的风险。目前,还没有什么专门针对Activity劫持的防护方法,因为这种攻击是用户层面上的,目前还无法从代码层面上根除。但是我们可以合适的时机给用户一些警示信息,提示用户其登陆界面已经被覆盖,并且给出到底是被什么应用给覆盖了,在onPause()方法里执行提醒逻辑就是最好的时机。实现如下:

    @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {//判断程序进入后台是否是用户自身造成的(触摸返回键或HOME键),是则无需弹出警示。if((keyCode==KeyEvent.KEYCODE_BACK || keyCode==KeyEvent.KEYCODE_HOME) && event.getRepeatCount()==0){needAlarm = false;}return super.onKeyDown(keyCode, event);}@Overrideprotected void onPause() {//若程序进入后台不是用户自身造成的,则需要弹出警示if(needAlarm) {//弹出警示信息Toast.makeText(getApplicationContext(), "您的登陆界面被覆盖,请确认登陆环境是否安全", Toast.LENGTH_SHORT).show();//启动我们的AlarmService,用于给出覆盖了正常Activity的类名Intent intent = new Intent(this, AlarmService.class);startService(intent);}super.onPause();}
public class AlarmService extends Service{boolean isStart = false;Handler handler = new Handler();Runnable alarmRunnable = new Runnable() {@Overridepublic void run() {ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);//getRunningTasks会返回一个List,List的大小等于传入的参数。//get(0)可获得List中的第一个元素,即栈顶的taskActivityManager.RunningTaskInfo info = activityManager.getRunningTasks(1).get(0);//得到当前栈顶的包名String shortClassName = info.topActivity.getShortClassName();//完整类名//String className = info.topActivity.getClassName();//包名//String packageName = info.topActivity.getPackageName();Toast.makeText(getApplicationContext(), "当前运行的程序为"+shortClassName, Toast.LENGTH_LONG).show();}};@Overridepublic int onStartCommand(Intent intent, int flag, int startId) {super.onStartCommand(intent, flag, startId);if(!isStart) {isStart = true;//启动alarmRunnablehandler.postDelayed(alarmRunnable, 1000);stopSelf();}return START_STICKY;}@Overridepublic IBinder onBind(Intent intent) {return null;}
}

5.  关于程序锁和1像素包活

由于部分应用采用1像素保护机制,在锁屏时开启1像素的Activity,使应用在锁屏期间保持较高的进程优先级,但是如果该应用被程序锁监控,则会出现解锁手机后出现输入密码的提示界面,给用户带来很大困扰,在我们现在的实际项目中就遇到了这个问题,因为有的手机,比如小米手机,系统自带了程序锁功能。最终将1像素保活方案遗弃。

Android开发——程序锁的实现(可用于开发钓鱼登录界面)相关推荐

  1. android解锁界面分析,Android 7.0 锁屏解锁之向上滑动显示解锁界面分析

    Android 7.0 锁屏解锁之向上滑动显示解锁界面分析 by jing.chen 锁屏的解锁操作是在锁屏界面向上滑动实现的,通过向上滑动调出解锁界面(如图案.PIN.密码解锁界面),在解锁界面输入 ...

  2. android应用程序 多少钱_关于APP开发你最想了解的事,开发一个APP多少钱?

    当我们在进行APP开发,最关注的问题一定是APP开发的价格问题,而作为软件开发行业的从业人员,经常会遇到这样的情况:"别说这么多,你只要告诉我开发一个软件多少钱就行了". 郑州AP ...

  3. Android菜鸟的成长笔记(3)——给QQ登录界面说So Easy

    上一篇:Android菜鸟的成长笔记(2)--第一个Android应用 我们前面已经做了第一个Android应用程序,虽然有点像QQ的登录界面,但是很多地方还是很难看,这一篇咱们来将这个界面做成一个标 ...

  4. 如何编写 android go 程序,轻松搭建基于go1.5开发Android应用的环境 | Go语言中文网 | Golang中文社区 | Golang中国...

    go1.5beta2已经发布,正式版将在8月份发布.而早在go1.4就已发布了golang/mobile项目用以实现Android应用的开发.当前gomobile的环境部署已经相对成熟了.但项目声明必 ...

  5. linux平板 开发程序,嵌入式Linux工业平板电脑开发详解

    硬件规格 产品特性 液 晶 屏:7"TFT真彩液晶屏(16:9比例),分辨率 800×480 触摸规格: 100万次以上(笔尖0.8m㎡打键荷重250克力,打键速度2次/秒) 中央处理器:C ...

  6. 开发程序实现nginx代理节点状态检查及WEB界面展示

    实现功能介绍: 利用shell程序及http服务巧妙的实现监控nginx代理节点状态检查,然后通过web界面实时刷新显示结果,是不是有些吃惊这样高大上的程序?那就赶紧看看吧! to用人单位:此课程可以 ...

  7. 2021年用于开发构建本机原生Windows应用程序软件的6大C ++ IDE开发工具简介

    集成软件开发环境(IDE)是一种软件应用程序,为应用程序开发提供了完整的功能集.代码通常以文本格式编写,您可以使用记事本,Word,Wordpad等文本编辑器轻松地编辑或修改代码.但是,对于开发人员( ...

  8. 使用 Amazon Amplify快速创建简单的 Android 应用程序

    背景: 亚马逊云科技提供了100余种产品免费套餐.其中,计算资源Amazon EC2首年12个月免费,750小时/月:存储资源 Amazon S3 首年12个月免费,5GB标准存储容量. 大家好,我是 ...

  9. Android应用程序和其设计思想--转载----做记录

    转载一篇Android 的先关文章,无论什么时候看都觉得有收获 文章来源地址 http://www.open-open.com/lib/view/open1466070376316.html 以下是正 ...

最新文章

  1. 大数据处理——Hadoop解析(一)
  2. 5、Java Swing JButton:按钮组件
  3. gradle配置_Gradle配置
  4. C++ 11 深度学习(六)智能指针综述
  5. 拿到大厂Offer了!
  6. 已有项目要不要迁移到Addressable系统?
  7. sicily 1345. 能量项链
  8. 2016河北省职称计算机考试试题及答案,2016年最新河北省职称计算机考试试题及答案..doc...
  9. Chrome历史版本安装包下载
  10. 光伏逆变器设计资料,原理图,PCB,源代码 DC-DC采用Boost升压,DCAC采用全桥逆变电路结构
  11. idea隐藏菜单栏Main Menu 恢复方法
  12. java pptx,使用Java将文件.pptx转换为.ppt
  13. python语言例子_第一个Python实例
  14. springboot运行出现 错误: 找不到或无法加载主类 com.xxxx.xxxx.Application
  15. 4位格雷码的顺序编码_格雷码编码规则_格雷码有什么规律
  16. 自适应滤波器——LMS算法
  17. (一)什么是Mybatis?Mybatis的优点是什么?
  18. 攒机笔记二(cpu)
  19. RedisInsight :Redis 官方可视化工具来啦
  20. 近三年浙大MBA/EMBA/IMBA/MPA/MEM提面录取占比,报考难易度窥测

热门文章

  1. mysql 的数据类型
  2. 使用iTunes与iTools导出微信聊天记录
  3. 通过Amazon SageMaker与Amazon Step Functions实现机器学习的CI/CD 方案
  4. 建模simulink - xpc函数参数处理
  5. java swing 跳转窗口_java swing 怎么实现点击按钮或者某个组件,跳转到另一个页面或者窗体?...
  6. Linux 关闭交换内存
  7. python中合法的赋值语句y=y+1_关于Python赋值语句,以下选项中不合法的是 _________ 。_学小易找答案...
  8. 伦敦同业拆借利率(LIBOR)
  9. 15年计算机考研大纲,2015计算机考研大纲
  10. matlab 三维图 输出,MATLAB三维曲线图绘制并输出到指定文件夹(突出几组不同数据)...