Android程序由后台切换到前台

上篇文章中提到,安全测试的一个需求是每次由后台切换到前台的时候都要走一遍登录界面,登录界面就是我的启动页,讲的是只要在配置文件中设置启动页activity的启动模式为singleTask就可以了,之后好像对这个效果不满意(是我解决的太快,感觉太简单了么??),所以给出了另外一种方案。

每次进到后台,从后台切换到前台的时候,只要不是在登录界面,就给弹一个dialog,提示用户输入密码验证身份,验证成功进入,点击取消的话进入到登录界面重新登录。

1、首先要解决的问题就是判断程序在前台还是在后台。

因为要监听所有的activity状态,所以判断应该写在BaseActivity中

/**

* 应用是否在前台运行

*

* @return true:在前台运行;false:已经被切到后台了

*/

private boolean isAppOnForeground() {

ActivityManager mActivityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);

    List appProcesses = mActivityManager.getRunningAppProcesses();

    if (appProcesses !=null) {

for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {

if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {

if (appProcess.processName.equals("cn.bzzy.com.bzzy_app")) {

//以下两句话是保存是否在后台的布尔值,判断是否显示dialog会用到

//editor.putBoolean("comefromback", false);

                  //editor.apply();

return true;

                }

}

}

}

Toast.makeText(getApplicationContext(), "注意,标准作业已进入后台运行", Toast.LENGTH_SHORT).show();

    //editor.putBoolean("comefromback", true);

    //editor.apply();

return false;

}

值得注意的是,这个方法应该写在哪里,一开始我是写在onPause()方法里面的,发现怎么都不可以,后来换到onStop()方法中就可以了。

想想为什么要在onStop中检测,而不是onPause?这是由于A启动B时,生命周期的执行顺序如下:A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop,也就是说,在A的onPause方法中,B的生命周期还没有执行,进程没有进入前台,当然是检测不到的。

好了第一步已经完成了,接下来第二步。

2、第二步是显示dialog。

private AlertDialog passwordDialog ;

private void showDialog() {

final EditText editText =new EditText(BaseActivity.this);

        passwordDialog =

new AlertDialog.Builder(BaseActivity.this).

setTitle("请重新输入密码验证身份").setView(editText)

.setPositiveButton("确定", null)

.setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override

                            public void onClick(DialogInterface dialog, int which) {

Intent intent =new Intent(getApplicationContext(), LoginActivity.class);

                                startActivity(intent);

                                finish();

                            }

}).setCancelable(false).create();

//        if(passwordDialog!=null && !passwordDialog.isShowing()){

            passwordDialog.show();

//        }

        passwordDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {

@Override

            public void onClick(View v) {

final String password =editText.getText().toString().trim();

                if (!password.equals("")) {

if (!CipherUtils.sm2DecryptHex(passwordPref.getString("password", "")).equals(password)) {

ToastUtil.showShort(getApplicationContext(), "密码错误");

                    }else {

ToastUtil.showShort(getApplicationContext(), "验证成功");

                        passwordDialog.dismiss();

                    }

}else {

ToastUtil.showShort(getApplicationContext(), "请输入密码");急

                }

}

});

    }


一开始在实现的时候以为就是简单的show出来一个dialog,后来发现默认的dialog是在点击确定的时候自己就消失了,这可不符合我们的需求啊,想想,就算你验证了密码不符合,给出toast出来说验证不通过,但是你的dialog消失了,用户照样可以使用。

所以要解决这个问题,方法就是,在setPositiveButton的点击事件中先设置为null,dialog.show()出来,然后获取PositiveButton的点击,通过验证之后才让dialog消失。

还有一点就是,只有在验证成功的条件下dialog才会消失,所以要设置点击屏幕空白部分和返回键dialog都不能消失,使用.setCancelable(false)。

另外setCanceledOnTouchOutside(false)的作用是点击屏幕空白部分不消失,点击返回键消失。


3、完成以上两个步骤我以为完成了需求,但之后在测试的时候发现,从后台切换到前台的时候,显示dialog没错,这时候再退回到后台,之后进入前台发现又弹出一个dialog,你会发现你在填写密码验证成功之后还有一个没有填写东西的dialog。

解决思路:肯定要在showDialog()方法执行之前进行判断。

怎么判断,想到showDialog的时候实例化dialog的对象,所以在没执行showDialog方法之前肯定是空的

if (passwordDialog ==null){

showDialog();

}

这样弹出一个dialog之后,对象就不为空,就不会执行showDialog方法,确实也是这样,不过经过测试发现,第一次可以达到效果,之后从后台到前台的时候就不会有dialog弹出,看看代码,想一下,是啊,执行过一次之后对象就不为空了啊,以后也不会执行就不会显示dialog了,要想一个办法让它进入到if里面执行showDialog,后来想到dialog.isShowing()这个方法,如果它没在显示的话就让他执行,进入到if了,没毛病,试试看

if (passwordDialog ==null || !passwordDialog.isShowing()) {

showDialog();

}

可以了,到这里目的就达到了。


PS. 本人写在这里的文章是记录自己解决问题的过程,以便日后查看,可能会有些啰嗦,也没有排版,之前也没有写过。如果有幸被你看到引起不适,勿喷。

以上。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容