Sebek
Sebek

Reputation: 692

Finishing an activity from another class

I am working on an app that requires a permanent internet connection. If no internet connection is present I want the user to be logged out of the app (taken to the login screen). I have a network receiver class that detects network connectivity. I want this class to either terminate the activity on top of the stack OR to start a new login activity and delete the entire history stack.

The problem is that I can't finish the foreground activity from inside the my receiver class, and there is no way of knowing which activity the user is in when there is a network fail. And if I'm starting a new login activity from this class, when the user presses "back" he is taken back to the app(if he reconnects to a network), but the app is not logged in and crashes.

Tried using myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK || FLAG_ACTIVITY_CLEAR_TOP); when starting a new login activity from my NetworkStateReceiver class. But it doesn't work, to my understanding this creates a new task in which the only activity is the one I started (login), but the old task with all the other activities remain intact.

So I need :

-either a way to finish a foreground activity from a class

-or a way to start a new activity from a class and emptying the activity stack

Here's the receiver code for what it's worth:

public class NetworkStateReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
//     super.onReceive(context, intent);
 Log.d("app","Network connectivity change");
 if(intent.getExtras()!=null) {
     Login.apiKey = null;
    NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
    if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) {
        Log.i("app","Network "+ni.getTypeName()+" connected");
    }
 }
 if(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE) && !Login.loginActive) {
        Log.d("app","There's no network connectivity");

        Toast.makeText(context, "No internet connection. Logging out", Toast.LENGTH_LONG).show();
        //logout
        Receiver.engine(context).halt();
        Receiver.mSipdroidEngine = null;
        Receiver.reRegister(0);
        new Thread(ChatList.runnable).interrupt();
        ChatList.buddyList.clear();
        Login.apiKey = null;
        Log.i("Logout", "Logged out!");
        Login.loggedOut = true;


        Intent myIntent = new Intent(context, Login.class);
        myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
//          myIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
        context.startActivity(myIntent);



     }
   }
}

SOLUTION: Passed reference from all activities to receiver

//random user_activity
    @Override
protected void onPause() {
    super.onPause();
    NetworkStateReceiver.curActivity = null;
}


@Override
protected void onResume() {
    super.onResume();
    NetworkStateReceiver.curActivity = user_activity.this; //edited : getParent() doesn't always work
}

and in network receiver in onReceive() :

            if(curActivity != null)
        {
            curActivity.finish();
   }

Upvotes: 7

Views: 2430

Answers (1)

Geobits
Geobits

Reputation: 22342

One way is to pass the receiver a reference to the current activity(say, in onResume?). Make sure to null it in onPause, though, or you're looking at some ugly memory leaks. Then, in onReceive, you can curActivity.finish()(or do nothing if it's null) before you start the login activity.

Upvotes: 3

Related Questions