Handling authenticated users is a very common scenario in a lot of applications. In such a scenario, you might have some activities which should be accessible to only authenticated users and there might be serveral of these activities open in the stack. How do you handle log out from an arbitrary stage in the app when you might have several activities that depend on authentication pushed on the back stack?
One way is to send the user to a “Login” activity with its flag set to FLAG_ACTIVITY_CLEAR_TOP
on log out which will clear all activities in the back stack upto the login activity. But this wouldn’t work if you can have saved sessions between app restarts where there might not even be an existing login activity when the user logs out.
Another option would be to check the log in status in onCreate
and finish()
the activity if the user is not logged in. Seems hacky, doesn’t it?
Lets think about what we want to do here. We want multiple activities to be able to be notified as soon as the user logs out. This is the task for a BroadcastReceiver
. Basically we need to brodcast a logout message to all our Activities that need to stay under a logged-in status. We can use the sendBroadcast
and install a BroadcastReceiver
in all our Actvities.
// After logging out
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_LOGOUT");
sendBroadcast(broadcastIntent);
And for all the activities that require authentication, register a receiver in onCreate. Make sure to also call LocalBroadcastManager.getInstance(this).unregisterReceiver()
in onDestroy()
so that we don’t receive any more broadcasts.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_LOGOUT");
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive","Logout in progress");
//At this point we should start the login activity and finish this one.
finish();
}
}, intentFilter);
}