【问题标题】:Launch a specific Activity when the app enters foreground from background当应用从后台进入前台时启动特定的 Activity
【发布时间】:2016-07-30 05:50:30
【问题描述】:

在我正在开发的应用程序中,某些屏幕需要密码保护。因此,如果用户离开应用程序(通过按主页或其他应用程序进入前台或屏幕关闭)并在一段时间(30 秒)后返回,应用程序应该在之前询问密码(显示密码屏幕)显示他离开的屏幕。

到目前为止我尝试过的是:

  • Application 类中,我使用 ActivityLifecycleCallbacks 跟踪活动生命周期并触发 2 个事件,一个在应用程序进入后台时,另一个在返回前台时。

  • 在“后台”事件中,我跟踪当前时间戳。然后在“前台”事件中,我检查应用程序是否在后台运行了 30 秒,如果是,则告诉当前的 Activity 启动密码屏幕。

这工作正常。但问题是,这样受保护的内容/屏幕会在一段时间内可见,直到启动密码屏幕(因为密码屏幕是由内容屏幕本身启动的)。

有没有更好的方法可以让密码屏幕首先出现?

【问题讨论】:

  • 为什么不从 Application 类本身启动密码活动(带有 clear_top 标志)?
  • @Shaishav 这正是我正在做的,但它并没有解决这个问题。我将启动委托给内容活动,因为它知道是否需要密码保护。
  • 您是否在 Application 类中使用 onActivityPaused()onActivityResumed() 生命周期方法来确定应用程序是否进入前台/后台?
  • @Shaishav 使用 startstop 事件。

标签: android android-activity


【解决方案1】:

您所描述的是 java 继承的一个基本的伟大用例,可以通过从活动类继承的基类轻松解决。

首先我们创建一个基类:

public class NeedPasswordActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        //Check time stamp here
    }

    @Override
    protected void onPause() {
        super.onPause();
        //Set time step here
    }
}

然后在每个需要验证密码的活动中,我们从 NeedPasswordActivity 继承:

public class NeedToHavePassowrdActivity extends NeedPasswordActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume(); //call the code from our NeedPasswordActivity and check time stamp before loading the activity
    }

    @Override
    protected void onPause() {
        super.onPause(); //call the code from our NeedPasswordActivity and set time stamp
    }
}

重要提示:super. 必须是方法中的第一行,因此在验证时间戳之前不会调用我们的活动中的任何内容

【讨论】:

    【解决方案2】:

    这听起来像是一个 hack,主要是因为它是。您可以使您的应用程序类确定后台/前台逻辑如下:

    public class MyApplication extends Application implements ActivityLifecycleCallbacks {
    
        public boolean userLoggedOff;
        private Handler mHandler; 
    
        ... 
    
        @Override  
        public void onActivityResumed(Activity activity) {
            Log.i("Activity Resumed", activity.getLocalClassName());
    
            if (userLoggedoff) 
                 startPasswordActivity() 
            else { 
                 mHandler.cancelCallbacksAndMessages(null); 
                 userLoggedOff = false;
            } 
        }  
    
        @Override  
        public void onActivityPaused(Activity activity) {
            Log.i("Activity Paused", activity.getLocalClassName());
    
            mHandler.postDelayed(new Runnable() {
                 @Override 
                 public void run() { 
                      userLoggedOff = true;
                 } 
            }, 30000); 
        }  
    
        ... 
    
    }
    

    这将在任何活动暂停后立即注销用户,但在 30 秒内没有任何活动恢复。现在,为了解决敏感信息立即显示的情况,我们可以在每个敏感活动布局中添加一个覆盖整个屏幕的视图,以隐藏屏幕,直到我们确定用户合法性。然后,在每个这样的活动中,我们可以添加:

    @Override
    protected void onResume() {
        if (!((MyApplication) getApplicatio()).userLoggedOff))
             (findViewByID(R.id.opaqueView)).setVisibility(View.INVISIBLE);
    }
    

    这可能适用于您的用例。

    【讨论】:

    • @Shaisab 跟踪应用程序的前台/后台状态的逻辑已经存在并且正在工作。感谢您建议视图叠加,如果我无法解决相关问题,我也在考虑将敏感内容模糊掉。
    • 哦..这就是为什么我问你使用什么方法。但是,我家停电了,所以在发布我的答案之前我无法得到您的回复,我在电源恢复后立即做了。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多