Android端限制单设备登录的具体实现

限制单设备登录指的是同一个账户(id)不能在一个以上的设备上登录对应的用户系统(排除web端和移动端可以同时登录的情况),例如:用户m在A设备登录并保持登录状态,然后又在B设备登录,此时A应该要强制下线,m无法在A设备上继续执行用户相关的操作

服务端

服务端需要集成Token,每次在app登录时为app分配新的token,如果在某次http请求中app传递token不是最新的,则视为需要重新登录(或者根据自己需要后台设定token有效时间,过期视为Token失效,需要重新登录).在token失效的情况下,返回约定好的code

Android端监听

App如何知道已经在其他设备登录了呢,一般可以有三种方式

1.api请求中后台返回特定code

这种是最常见的方式,缺点是需要下次api请求才知道被踢下线,可以在网络层实体模型的基类BaseModel中处理,对code进行判断

        switch (code) {
        case 1:
            break;
        case 3://被踢下线
            //Do Something
            break;
        }

2.推送

后台推送给app,从而app得知该账户在其他设备登录了,进而执行下线操作,优点是可以及时响应

3.使用第三方的监听器

很多时候app会集成一些第三方的账户系统,例如在集成了环信的app中,每个用户对应一个环信的imUserName,环信自身有提供连接状态的接听,通过监听环信的用户状态,从而达到监听app自身用户系统的效果

        EMClient.getInstance().addConnectionListener(this);

Android被踢下线后的操作

不管是哪种监听方式,最后的操作都是一样的,可以根据自己的需求进行对应的操作.这里提供一种常规化的下线流程.

  • 从栈顶取到当前的前台Activity,Dialog提示用户,点击后跳转登录页

《Android端限制单设备登录的具体实现》 Screenshot_2016-08-31-17-18-33.png

首先,任意地方获取到前台Activity

public Activity getTaskTop() {
    return mActivities.get(mActivities.size() - 1);
}

然后在主线程弹出dialog

private void onConnectionConflict() {//被踢下线处理
    SPUtils.logout();
    final Activity taskTop = ActivityManager.getInstance().getTaskTop();
    if (taskTop == null) return;
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            MDdialogFactory.CreateMustOkDia(taskTop, "您的账号已在其他终端登录,请重新登录", new MDCallBack() {
                @Override
                public void onMdCall(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    Intent intent = new Intent(taskTop, LoginActivity.class);
                    intent.putExtra(ConstantKey.MUST_LOGIN_KEY, true);
                    taskTop.startActivity(intent);
                }
            }).show();
        }
    });
}

这里做一些说明

  • 由于监听到被踢下线的环境不一定在主线程,所以需要切换到主线程进行弹出Dilaog

      new Handler(Looper.getMainLooper()).post(Runnable r)
    
  • 这里的dialog是强制的,取消不了(这里dialog是自定义的,用系统的也是可以的,这不是重点)

      builder.cancelable(false);
      builder.canceledOnTouchOutside(false);
    

关于作者

    原文作者:uncochen
    原文地址: https://www.jianshu.com/p/3307b7956acf
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞