タイトルの通りログインしていないとアクセスできないActivityの実装とログアウト処理について試行錯誤したので共有します。前提としてActivityの設定において都度破棄・生成をする設定になっていないといけないです。
ログイン状態の定義
- SharedPreferenceにuserIdがセットされている (またはAccessToken)
実装
AppCompatActivityを継承したBaseActivityを作成し、利用するActivityは全てBaseActivityを継承します。
BaseActivityはそのActivityが認証が必要かどうかを決めるフラグ (isAuthorizationRequired) を持ちます。子Activityは #allowGuestAccess
を呼ぶことによりログインしていないユーザによるアクセスを許可できます。
ログインしていないとアクセスできないようにするにはそのフラグをチェックするだけです。
ログアウト処理は、IntentをBroadcastできる仕組みを使います。BaseActivityの #logout
を実行すると全体に "ログアウトしたよ" というイベントを発行し、存在するActivityはそれを受け (ActivityはすべてBaseActivityを継承しているからレシーブできる) 自身の生命を絶ちます。
認証に関するさまざまなアクションを発行できるようになっているので、ログインした瞬間に各Activityに何かさせたいってケースにも対応できますね。
BaseActivity
public class BaseActivity extends AppCompatActivity implements AuthEventsReceiver.Receivable {
private boolean isAuthorizationRequired = true;
private int userId;
private BroadcastReceiver broadcastReceiver;
// readable setter
public void allowGuestAccess() {
this.isAuthorizationRequired = false;
}
// define getter for isAuthorizationRequired
// define accessor for userId
// set null if the userId is a negative number
protected void onCreate(Bundle savedInstanceState) {
// 略
if (getIsAuhorizationRequired()) {
registerReceivers();
ensureAuthorized();
}
}
private void ensureAuthorized() {
setUserId(getDefaultSharedPreferences(this).getInt(USER_ID, -1));
if (getUserId == null) {
// do that what you want to do with unauthorized user
}
}
protected void logout() {
// ensure nullify the userId on the shared preferences
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(AuthEventsReceiver.ACTION_LOGOUT);
sendBroadcast(broadcastIntent);
startLoginActivity();
}
@Override
protected void onLogout() {
finish();
}
protected void startLoginActivity() {
// start your activity
}
private void registerReceivers() {
IntentFilter intentFilter = new IntentFilter(AuthEventsReceiver.ACTION_LOGOUT);
broadcastReceiver = new AuthEventsReceiver(this);
registerReceiver(broadcastReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}
public class AuthEventsReceiver extends BroadCastReceiver {
public static final String ACTION_LOGOUT = "com.example.sozu.hoge.action_logout";
private Activity activity;
public AuthEventsReceiver(Activity activity) { this.activity = activity; }
@Override
public void onReceive(Context context, Intent intent) {
try {
AuthReceiver receiver = (Receivable) activity;
switch (intent.getAction()) {
case ACTION_LOGOUT:
receivable.onLogout();
break;
case default:
break;
}
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement AuthEventsReceiver.AuthReceivable");
}
}
public interface Receivable {
void onLogout();
}
}