How to check if activity is in foreground or in vi

2020-01-23 02:32发布

I have a splash screen on a timer. My problem is that before I finish() my activity I need to check that the next activity has started because a system dialogue box pops-up and I only want to finish(); once the user has selected an option from the dialogue box?

I know that there are many questions on how to see if your activity is in the foreground but I do not know if this allows for dialogue boxes on top of the activity too.

Here is the problem, the red is my activity which is in the background while the dialogue is in the foreground:

the red is my activity which is in the background while the dialogue is in the foreground

EDIT: I have tried just not using finish() but then my activity can be gone back to in the stack of applications which I am trying to avoid.

22条回答
贪生不怕死
2楼-- · 2020-01-23 03:17

One possible solution might be setting a flag while showing the system-dialog and then in the onStop method of the activity life-cycle, check for the flag, if true, finish the activity.

For example, if the system dialog is triggered by some buttonclick, then the onclick listener might be like

private OnClickListener btnClickListener = new OnClickListener() {

    @Override
    public void onClick(View v) {           
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.setType("text/plain");
        CheckActivity.this.startActivity(Intent.createChooser(intent, "Complete action using"));
        checkFlag = true;  //flag used to check

    }
};

and in onstop of activity:

@Override
protected void onStop() {
    if(checkFlag){
        finish();
    }
    super.onStop();
}
查看更多
劳资没心,怎么记你
3楼-- · 2020-01-23 03:17

If you use finish() just to avoid new app to starts in the stack (task) of you app, you can use Intent.FLAG_ACTIVITY_NEW_TASK flag, when starting new application and do not call finish() at all. According to the documentation, this is the flag to be used to implement a "launcher" style behavior.

// just add this line before you start an activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
查看更多
Root(大扎)
4楼-- · 2020-01-23 03:17

Here is a solution using Application class.

public class AppSingleton extends Application implements Application.ActivityLifecycleCallbacks {

private WeakReference<Context> foregroundActivity;


@Override
public void onActivityResumed(Activity activity) {
    foregroundActivity=new WeakReference<Context>(activity);
}

@Override
public void onActivityPaused(Activity activity) {
    String class_name_activity=activity.getClass().getCanonicalName();
    if (foregroundActivity != null && 
            foregroundActivity.get().getClass().getCanonicalName().equals(class_name_activity)) {
        foregroundActivity = null;
    }
}

//............................

public boolean isOnForeground(@NonNull Context activity_cntxt) {
    return isOnForeground(activity_cntxt.getClass().getCanonicalName());
}

public boolean isOnForeground(@NonNull String activity_canonical_name) {
    if (foregroundActivity != null && foregroundActivity.get() != null) {
        return foregroundActivity.get().getClass().getCanonicalName().equals(activity_canonical_name);
    }
    return false;
}
}

You can simply use it like follows,

((AppSingleton)context.getApplicationContext()).isOnForeground(context_activity);

If you have a reference to the required Activity or using the canonical name of the Activity, you can find out whether it's in the foreground or not. This solution may not be foolproof. Therefore your comments are really welcome.

查看更多
Root(大扎)
5楼-- · 2020-01-23 03:20

I don't know why nobody talked about sharedPreferences, for Activity A,setting a SharedPreference like that (for example in onPause() ) :

SharedPreferences pref = context.getSharedPreferences(SHARED_PREF, 0);
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("is_activity_paused_a", true);
editor.commit();

I think this is the reliable way to track activities visibilty.

查看更多
看我几分像从前
6楼-- · 2020-01-23 03:20

Would Activity.onWindowFocusChanged(boolean hasFocus) be useful here? That, plus a class-level flag, something like isFocused that onWindowFocusChanged sets, would be an easy way to tell at any point in your activity if it is focused or not. From reading the docs, it looks like it would properly set "false" in any situation where the activity isn't directly in the physical "foreground", like if a dialog is being displayed or the notification tray is pulled down.

Example:

boolean isFocused;
@Override
void onWindowFocusChanged (boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    isFocused = hasFocus;
}

void someMethod() {
    if (isFocused) {
        // The activity is the foremost object on the screen
    } else {
        // The activity is obscured or otherwise not visible
    }
}
查看更多
贼婆χ
7楼-- · 2020-01-23 03:21

Why not use broadcasts for this? the second activity (the one that needs to be up) can send a local broadcast like this:

//put this in onCreate(..) or any other lifecycle method that suits you best
//notice the string sent to the intent, it will be used to register a receiver!
Intent result = new Intent("broadcast identifier");
result.putString("some message");//this is optional
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(result);

then write a simple receiver within the splash activity:

//this goes on the class level (like a class/instance variable, not in a method) of your splash activity:
private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        //kill activity here!!!
        //mission accomplished!
    }
};

and register your new receiver with the LocalBroadcastManager to listen to the broadcast from your second activity:

//notice the string sent to the intent filter, this is where you tell the BroadcastManager which broadcasts you want to listen to!
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(receiver, new IntentFilter("broadcast identifier"));

NOTE that you could use a constant or a string resource for the "broadcast identifier" string.

查看更多
登录 后发表回答