Activity劫持风险与防范措施
    在Android系统问世不久,曾发生过这样的事情,用户在正常输入用户名、密码的情况,账密信息缺被盗的情况,why?
    
    我们在使用银行类app时,只要我们的银行app客户端退至后台,为啥总会提示一下我们,“***已退至后台”的字样,why?
    
    今天我们就一起来聊聊 activity被劫持的那些事。
   
Activity是我们构建app应用的基本页面,而android app activity页面的管理,是通过栈 来管理的。而在activity 启动时,“FLAG_ACTIVITY_NEW_TASK”设置,成为activity被劫持的关键因素,因为通过本标示参数设置,会使当前activity抢占栈顶,展现在用户UI层。
    
     好了,先说一下劫持的过程吧
    
    
    一般情况下,劫持程序都是通过服务来执行的,简单来说,就是一个app没有界面,只有一个后台服务,安装在手机中,用户从桌面是无法感知和发现的,只能通过系统应用管理中去查找,所以隐蔽性很好。以下简称这种劫持服务为“流氓软件”。
    
    流氓软件会预先开发好想要窃取目前app的登录界面,可能相似度非常的高,一般人发现不了问题。然后可能你不经意间在做其他操作时安装了这个流氓软件,然后他就以服务的形式一直在你后台跑,当你目前程序启动登录时,流氓软件一旦检查到是需要的目前,就会强占栈顶,这是用户所看到的其实是伪装好的登录界面,如果用户不知道真伪,直接输入了用户名密码,流氓软件后台就获取到你的账密了,是不是很吓人…关键这种问题,并没有根本的解决方法,只能听过提示性动作,提醒用户
   
    
     方法
    
    
    一旦页面被至到后台,可以::
    
    1,Toast提示用户
    
    2,通过Notification通知栏提示用户
   
这就是问啥银行类app,当你退到后台后,总会提示你的原因。好了,开始上代码…
    public abstract class BaseActivity extends AppCompatActivity{
    
    
    @Override
    
    protected void onCreate(Bundle savedInstanceState) {
    
    
    super.onCreate(savedInstanceState);
    
    ClassName = getClass().getSimpleName();
    
    MyLog.d(TAG, ClassName);
    
    …
    
    }
    
    }
    
    @Override
    
    protected void onResume() {
    
    
    BGUtils.getinstance().onResume();
    
    fingerInvalidateByRunBg();
    
    super.onResume();
   
}
@Override
protected void onStop() {
    super.onStop();
}
@Override
protected void onPause() {
    BGUtils.getinstance().onPause(this);
    super.onPause();
}
    public class BGUtils{
    
    
    /**
    
    * 获取唯一实例
    
    *
    
    * @return 唯一实例
    
    
     /
     
     public static BGUtils getinstance() {
     
     
     if (BGUtils== null) {
     
     
     bgUtils= new BGUtils();
     
     }
     
     return bgUtils;
     
     }
     
     }
     
     /
    
    *
    
    * 应用是否在前台运行
    
    *
    
    * @return true:在前台运行;false:已经被切到后台了
    
    */
    
    public boolean isAppOnForeground() {
    
    
    ActivityManager activityManager = (ActivityManager) MyApplication.getInstance().getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
    
    List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
    
    if (appProcesses != null) {
    
    
    for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
    
    
    if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
    
    
    if (appProcess.processName.equals(packageName)) {
    
    
    return true;
    
    }
    
    }
    
    }
    
    }
    
    return false;
    
    }
    
    @Override
    
    public void run() {
    
    
    activity.runOnUiThread(new Runnable() {
    
    
    @Override
    
    public void run() {
    
    
    //首先判断程序是否在运行
    
    if (canRun) {
    
    
    //其次判断程序是否在前台
    
    if (!isAppOnForeground()) {
    
    
    // 程序退到后台,进行风险警告
    
    ToastUtil.showToast(activity, MyApplication.getInstance().getResources().getString(R.string.app_run_alert));
    
    //NotificationUtils.showNotification(activity);
    
    …
    
    }
    
    tasks.remove(MyTimerTask.this);
    
    }
    
    }
    
    });
    
    }
    
    }
   
 
