package com.gh.common.util; import android.app.Dialog; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.text.TextUtils; import com.gh.gamecenter.entity.LoginResponseEntity; import com.gh.gamecenter.entity.UserInfoEntity; import com.gh.gamecenter.retrofit.JSONObjectResponse; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.lightgame.utils.Utils; import org.json.JSONException; import org.json.JSONObject; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.HttpException; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; /** * Created by khy on 7/07/17. */ public class LoginUtils { public enum LoginTag { qq, wechat, weibo, phone, refresh, oldUserPhone } public static void checkPhoneNum(final Context context, final String phoneName, final onCaptchaCallBackListener listener) { // 老用户登录检查手机是否登录过 RetrofitManager.getApi() .checkPhoneNum(phoneName) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onResponse(ResponseBody response) { super.onResponse(response); try { JSONObject content = new JSONObject(response.string()); String status = content.getString("status"); if ("ok".equals(status)) { getPhoneCaptcha(context, phoneName, listener); } else { DialogUtils.showWarningDialog(context, null, "手机号已存在,请使用未登录过的手机号,以保证数据正常同步到新账号上" , null, "我知道了", null, null); } } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(HttpException e) { super.onFailure(e); if (e == null) { Utils.toast(context, "请检查网络是否可用"); return; } try { ResponseBody responseBody = e.response().errorBody(); String string = responseBody.string(); JSONObject content = new JSONObject(string); int code = content.getInt("code"); outputErrorHint(context, code); } catch (Exception e1) { e1.printStackTrace(); } } }); } // 获取验证码 public static void getPhoneCaptcha(final Context context, String phoneNum, final onCaptchaCallBackListener listener) { Map params = new HashMap<>(); params.put("mobile", phoneNum); RequestBody body = RequestBody.create(MediaType.parse("application/json"), new JSONObject(params).toString()); RetrofitManager .getUsersea() .loginByCaptcha(body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new JSONObjectResponse() { @Override public void onResponse(JSONObject response) { super.onResponse(response); try { listener.onCaptcha(response.getString("service_id")); } catch (JSONException e) { e.printStackTrace(); } } @Override public void onFailure(HttpException e) { super.onFailure(e); if (e == null) { Utils.toast(context, "请检查网络是否可用"); return; } try { ResponseBody responseBody = e.response().errorBody(); String string = responseBody.string(); JSONObject content = new JSONObject(string); int code = content.getInt("code"); outputErrorHint(context, code); } catch (Exception e1) { e1.printStackTrace(); } } }); } // 登录前,做好body判断 public static void login(final Context context, final JSONObject content, final LoginTag loginTag, final onLoginCallBackListener listener) { try { JSONObject device = DeviceUtils.getLoginDevice(context.getApplicationContext()); content.put("device", device); } catch (JSONException e) { e.printStackTrace(); } RequestBody body = RequestBody.create(MediaType.parse("application/json"), content.toString()); Observable observable; if (loginTag == LoginTag.weibo) { observable = RetrofitManager.getUsersea().loginByWeibo(body); } else if (loginTag == LoginTag.qq) { observable = RetrofitManager.getUsersea().loginByQQ(body); } else if (loginTag == LoginTag.wechat) { observable = RetrofitManager.getUsersea().loginByWechat(body); } else if (loginTag == LoginTag.phone || loginTag == LoginTag.oldUserPhone) { observable = RetrofitManager.getUsersea().loginByMobile(body); } else if (loginTag == LoginTag.refresh) { observable = RetrofitManager.getUsersea().refreshToken(body); } else { return; } observable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onResponse(LoginResponseEntity response) { super.onResponse(response); if (loginTag.equals(LoginTag.refresh)) { LoginResponseEntity loginToken = getLoginToken(context); if (loginToken != null) { response.setLoginType(loginToken.getLoginType()); } } else { if (loginTag.equals(LoginTag.phone) || loginTag.equals(LoginTag.oldUserPhone)) { try { response.setLoginType(content.getString("mobile")); } catch (JSONException e) { e.printStackTrace(); } } else { response.setLoginType(loginTag.name()); } } saveLoginToken(context, response); String token = response.getAccessToken().getValue(); if (loginTag == LoginTag.oldUserPhone) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); String syncDeviceID = sp.getString("syncDeviceID", null); if (!TextUtils.isEmpty(syncDeviceID)) { syncUserData(context, syncDeviceID, token, listener, loginTag); return; } } getUserData(context, token, listener, loginTag); } @Override public void onFailure(HttpException e) { super.onFailure(e); if (e == null) { Utils.toast(context, "请检查网络是否可用"); return; } try { ResponseBody responseBody = e.response().errorBody(); String string = responseBody.string(); JSONObject content = new JSONObject(string); int code = content.getInt("code"); if (loginTag == LoginTag.refresh && code == 40802) { Utils.log("=======40802::" + string); JSONObject device = content.getJSONObject("device"); String manufacturer = device.getString("manufacturer"); String model = device.getString("model"); DialogUtils.showAlertDialog(context, "你的账号已在另外一台设备登录" , StringUtils.buildString("(", manufacturer, "-", model, ")") , "知道了", null, null, null); LoginUtils.cleanUserData(context); // TODO 要不要调用退出登录接口 } else { outputErrorHint(context, code); } } catch (Exception e1) { e1.printStackTrace(); } cleanUserData(context); } }); } private static void syncUserData(final Context context, String syncDeviceID, final String token , final onLoginCallBackListener listener, final LoginTag loginTag) { HashMap map = new HashMap<>(); map.put("device_id", syncDeviceID); RequestBody body = RequestBody.create(MediaType.parse("application/json"), new JSONObject(map).toString()); RetrofitManager.getApi().syncUserData(token, body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onResponse(ResponseBody response) { super.onResponse(response); getUserData(context, token, listener, loginTag); } @Override public void onFailure(HttpException e) { super.onFailure(e); if (e == null) { Utils.toast(context, "请检查网络是否可用"); return; } try { ResponseBody responseBody = e.response().errorBody(); String string = responseBody.string(); JSONObject content = new JSONObject(string); int code = content.getInt("code"); outputErrorHint(context, code); } catch (Exception e1) { e1.printStackTrace(); } getUserData(context, token, listener, loginTag); } }); } // 注销登录 public static void logout(final Context context) { LoginResponseEntity loginToken = getLoginToken(context); if (loginToken == null || loginToken.getAccessToken() == null) return; RetrofitManager .getUsersea() .logout(loginToken.getAccessToken().getValue()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onFailure(HttpException e) { super.onFailure(e); if (e == null) { Utils.toast(context, "请检查网络是否可用"); return; } try { ResponseBody responseBody = e.response().errorBody(); String string = responseBody.string(); JSONObject content = new JSONObject(string); int code = content.getInt("code"); outputErrorHint(context, code); } catch (Exception e1) { e1.printStackTrace(); } } }); cleanUserData(context); } // 清除本地用户相关信息 public static void cleanUserData(Context context) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor edit = sp.edit(); edit.putString("user_info", null); edit.putString("login_token", null); edit.apply(); GetLoginDataUtils.getInstance(context).QQLogout(); } // 检查本地是否有缓存token,有则马上登录 public static void checkLogin(Context context, onLoginCallBackListener listener) { LoginResponseEntity loginToken = getLoginToken(context); if (loginToken != null && loginToken.getAccessToken() != null) { LoginResponseEntity.AccessToken accessToken = loginToken.getAccessToken(); Long accessExpire = accessToken.getExpire(); if (accessExpire != null && accessExpire > Utils.getTime(context)) { getUserData(context, accessToken.getValue(), listener, null); } else { LoginResponseEntity.RefreshToken refreshToken = loginToken.getRefreshToken(); Long refreshExpire = refreshToken.getExpire(); if (refreshExpire != null && refreshExpire > Utils.getTime(context)) { Map params = new HashMap<>(); params.put("refresh_token", refreshToken.getValue()); login(context, new JSONObject(params), LoginTag.refresh, listener); // 刷新accessToken } else { // 重新登录 cleanUserData(context); } } } } // 获取用户信息 public static void getUserData(final Context context, String token, final onLoginCallBackListener listener, final LoginTag loginTag) { RetrofitManager .getApi() .getUserInfo(token) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onResponse(UserInfoEntity response) { super.onResponse(response); saveUserInfo(context, response); if (listener != null) { listener.onLogin(response, loginTag); } } @Override public void onFailure(HttpException e) { super.onFailure(e); if (e == null) { Utils.toast(context, "请检查网络是否可用"); return; } try { ResponseBody responseBody = e.response().errorBody(); String string = responseBody.string(); JSONObject content = new JSONObject(string); int code = content.getInt("code"); outputErrorHint(context, code); } catch (Exception e1) { e1.printStackTrace(); } } }); } // 获取本地缓存用户信息 public static UserInfoEntity getUserInfo(Context context) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); String loginData = sp.getString("user_info", null); if (!TextUtils.isEmpty(loginData)) { Type listType = new TypeToken() { }.getType(); return new Gson().fromJson(loginData, listType); } return null; } // 在本地缓存用户信息 public static void saveUserInfo(Context context, UserInfoEntity entity) { if (entity != null) { String s = new Gson().toJson(entity); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor edit = sp.edit(); edit.putString("user_info", s); edit.apply(); } } //获取本地缓存用户token public static LoginResponseEntity getLoginToken(Context context) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); String loginData = sp.getString("login_token", null); if (!TextUtils.isEmpty(loginData)) { Type listType = new TypeToken() { }.getType(); return new Gson().fromJson(loginData, listType); } return null; } //获取本地缓存用户token public static String getToken(Context context) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); String loginData = sp.getString("login_token", null); if (!TextUtils.isEmpty(loginData)) { Type listType = new TypeToken() { }.getType(); LoginResponseEntity entity = new Gson().fromJson(loginData, listType); if (entity != null && entity.getAccessToken() != null) { return entity.getAccessToken().getValue(); } } return null; } // 在本地缓存用户token public static void saveLoginToken(Context context, LoginResponseEntity entity) { if (entity != null) { if (TextUtils.isEmpty(entity.getLoginType())) { LoginResponseEntity loginToken = getLoginToken(context); if (loginToken != null) { entity.setLoginType(loginToken.getLoginType()); } } String s = new Gson().toJson(entity); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor edit = sp.edit(); edit.putString("login_token", s); edit.apply(); } } //更改用户信息 public static void changeUserInfo(final onChangeUserInfoListener listener, final Context context, String content, String editType) { final UserInfoEntity entity = getUserInfo(context); if (entity == null) { return; } switch (editType) { case "nickName": entity.setName(content); break; case "contact": entity.setContact(content); break; case "sex": entity.setGender(content); break; case "area": entity.setRegion(content); break; case "userIcon": entity.setIcon(content); break; default: return; } final Dialog loadingDialog = DialogUtils.showWaitDialog(context, "正在修改信息..."); LoginResponseEntity loginToken = getLoginToken(context); if (loginToken == null || loginToken.getAccessToken() == null) return; RequestBody body = RequestBody.create(MediaType.parse("application/json"), new Gson().toJson(entity)); RetrofitManager .getUsersea() .changeUserInfo(loginToken.getAccessToken().getValue(), body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onResponse(ResponseBody response) { super.onResponse(response); if (loadingDialog != null) { loadingDialog.dismiss(); } saveUserInfo(context, entity); listener.onChange(); } @Override public void onFailure(HttpException e) { super.onFailure(e); if (loadingDialog != null) { loadingDialog.dismiss(); } Utils.toast(context, "修改失败"); if (e == null) { Utils.toast(context, "请检查网络是否可用"); return; } try { ResponseBody responseBody = e.response().errorBody(); String string = responseBody.string(); JSONObject content = new JSONObject(string); int code = content.getInt("code"); outputErrorHint(context, code); } catch (Exception e1) { e1.printStackTrace(); } } }); } private static void outputErrorHint(Context context, int code) { switch (code) { case 40000: Utils.toast(context, "参数不全"); break; case 40001: Utils.toast(context, "已经发送过短信"); break; case 40002: Utils.toast(context, "请求第三方开放平台时发生错误"); break; case 40003: Utils.toast(context, "上传用户头像时发生错误"); break; case 40101: Utils.toast(context, "缺少参数 app_id"); break; case 40102: Utils.toast(context, "缺少签名验证的头信息"); break; case 40104: Utils.toast(context, "缺少token"); break; case 40105: Utils.toast(context, "缺少手机号码"); break; case 40106: Utils.toast(context, "缺少用户名"); break; case 40107: Utils.toast(context, "缺少密码参数"); break; case 40202: Utils.toast(context, "无效的手机号码"); break; case 40203: Utils.toast(context, "无效的用户名"); break; case 40204: Utils.toast(context, "无效的头像地址"); break; case 40205: Utils.toast(context, "无效的性别参数"); break; case 40206: Utils.toast(context, "无效的地区参数"); break; case 40208: Utils.toast(context, "无效的密码"); break; case 40209: Utils.toast(context, "无效的URL 地址"); break; case 42000: Utils.toast(context, "无效的app_id"); break; case 42001: Utils.toast(context, "无效的app_secret"); break; case 42002: Utils.toast(context, "无效的Union_id"); break; case 42003: Utils.toast(context, "无效的设备信息"); break; case 42004: Utils.toast(context, "无效的请求"); break; case 40301: Utils.toast(context, "签名验证失败"); break; case 40302: Utils.toast(context, "验证码错误"); break; case 40303: Utils.toast(context, "密码错误"); break; case 40304: Utils.toast(context, "不支持该种方式登录"); break; case 40305: Utils.toast(context, "错误的状态值(应用只有两种状态: working / stop)"); break; case 40306: Utils.toast(context, "传递了无法识别的参数"); break; case 40401: Utils.toast(context, "token过期"); break; case 40402: Utils.toast(context, "Service_id过期,主要原因是:收到手机短信验证码后长时间没有进行登录操作"); break; case 40403: Utils.toast(context, "验证码已过期"); break; case 40501: Utils.toast(context, "同名应用已经存在"); break; case 40502: Utils.toast(context, "用户名已存在"); break; case 40503: Utils.toast(context, "名称已经存在"); break; case 40601: Utils.toast(context, "应用不存在"); break; case 40602: Utils.toast(context, "用户不存在"); break; case 40603: Utils.toast(context, "用户系统不存在"); break; case 40604: Utils.toast(context, "用户已被冻结"); break; case 40605: Utils.toast(context, "用户没有冻结"); break; case 40606: Utils.toast(context, "该应用被停止运行了"); break; case 40801: Utils.toast(context, "访问过于频繁"); break; default: Utils.toast(context, "未知错误"); break; } } // 更改用户信息回调 public interface onChangeUserInfoListener { void onChange(); } // 获取验证码回调 public interface onCaptchaCallBackListener { void onCaptcha(String serviceId); } // 登录回调 public interface onLoginCallBackListener { void onLogin(UserInfoEntity entity, LoginTag loginTag); } }