Android 防界面劫持方案,无视Android系统版本限制,无需操作栈
16lz
2021-01-23
Android 防界面劫持方案
Demo下载地址
http://download.csdn.net/detail/prince_wenzheng/9742068
分析
要想真正做到防劫持,就需要在我们的程序运行时,不允许启动其他应用程序。但是Android为了提高用户的用户体验,对于不同的应用程序之间的切换,基本上是无缝,如果在启动一个Activity时,给它加入一个标志位FLAG_ACTIVITY_NEW_TASK,就能使它置于栈顶并立马呈现给用户。在这种机制下,无法做到真正的防劫持
那么只能使用一种折中的方案,用户使用app的时候,如果被恶意程序劫持跳转到别的界面,这个时候我们就要做出预警提示用户,告诉用户当前界面已经不是我们的app了,有潜在的危险。
这种方案主要有一个问题需要攻克,就是监控是否有程序覆盖了我们的APP,也就是我们需要监控栈顶的变化,在Android5.0之前,可以使用ActivityManager中提供的方法操作栈,但是在Android5.0时,谷歌由于用户隐私的考虑,弱化了这个接口,ActivityManager只能管理自己APP的栈,如果想管理其他APP的栈,需要用户主动授权,而好多手机厂商又对这个权限做了进一步限制,只能为特定的APP授权(如系统捆绑应用)。这样Android5.0之后就无法通过管理栈的方式来进行防劫持。
既然只能对自己的应用进行操作,我们可以从Activity的生命周期做些文章,具体方案往下看
方案
1. 在所有Activity的onPause()方法中,弹出提示用户的警告,延迟1-2秒执行
2. 在所有Activity的onResume()方法中,取消在onPause中的提示
效果
● 当自己的应用切换页面时,触发当前页面的onPause()方法,并立刻触发要跳转页面的onResume()方法,这样就不会发出警告提示用户。
● 当用户主动切换应用程序或者主动退回到桌面时,触发当前界面的onPause()方法,1-2秒后出现警告
● 当应用界面遭到恶意程序劫持时,触发当前界面的onPause()方法,1-2秒后出现警告
注意
1. 不能使用onStop()方法来代替onPause(),因为大部分劫持界面都采用透明主题,而跳转到透明Activity时,是不触发onStop()方法的,可以使用onStart()方法来代替onResume()
2. 当程序中需要加载第三方的Activity时,防劫持机制会判断第三方的Activity是非法的,并弹出警告,项目上在使用时可自行调用onResume(),来取消警告
代码
BaseActivity.java
package com.example.test;import android.app.Activity;public class BaseActivity extends Activity { @Override protected void onResume() { Anti_hijackingUtils.getinstance().onResume(); super.onResume(); } @Override protected void onPause() { Anti_hijackingUtils.getinstance().onPause(this); super.onPause(); }}
Anti_hijackingUtils.java
package com.example.test;import java.util.ArrayList;import java.util.List;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.widget.Toast;public class Anti_hijackingUtils { /** * 用于执行定时任务 */ private Timer timer = null; /** * 用于保存当前任务 */ private List tasks = null; /** * 唯一实例 */ private static Anti_hijackingUtils anti_hijackingUtils; private Anti_hijackingUtils() { // 初始化 tasks = new ArrayList(); timer = new Timer(); } /** * 获取唯一实例 * * @return 唯一实例 */ public static Anti_hijackingUtils getinstance() { if (anti_hijackingUtils == null) { anti_hijackingUtils = new Anti_hijackingUtils(); } return anti_hijackingUtils; } /** * 在activity的onPause()方法中调用 * * @param activity */ public void onPause(final Activity activity) { MyTimerTask task = new MyTimerTask(activity); tasks.add(task); timer.schedule(task, 2000); } /** * 在activity的onResume()方法中调用 */ public void onResume() { if (tasks.size() > 0) { tasks.get(tasks.size() - 1).setCanRun(false); tasks.remove(tasks.size() - 1); } } /** * 自定义TimerTask类 */ class MyTimerTask extends TimerTask { /** * 任务是否有效 */ private boolean canRun = true; private Activity activity; public void setCanRun(boolean canRun) { this.canRun = canRun; } public MyTimerTask(Activity activity) { this.activity = activity; } @Override public void run() { activity.runOnUiThread(new Runnable() { @Override public void run() { if (canRun) { // 程序退到后台,进行风险警告 Toast.makeText(activity, "应用Test切换至后台运行", Toast.LENGTH_LONG).show(); tasks.remove(MyTimerTask.this); } } }); } }}
更多相关文章
- Android应用开发基础之数据存储和界面展现(二)
- Android VideoView设置静音,Android 设置VideoView静音,Android
- ListView去掉分割线的几种方法
- SDK Platform Tools component is missing! Please use the SDK
- android 界面布局
- Android Market google play store帐号注册方法流程 及发布应用
- Android 实现全屏显示的几种方法整理
- android 5.0多用户支持
- 【Android 界面效果12】EditText中的多行输入问题