修改登录判断以及数据保存( 简易音乐 四)
关于
本篇主要是解决上一篇的登录接口返回判断(服务异常判断、无网络判断、账号信息判断以及用户信息的文件存储等)上一篇文章Retrofit+okhtp3实现登录功能( 简易音乐 三 )
效果图
断网下登录效果:
成功登录效果:
成功登陆后再次登录效果:
第一步,添加请求失败处理共同方法
修改StaticMethodUtils.java
(静态方法帮助类),因为增加了几个方法就直接全部贴上去吧:
public class StaticMethodUtils {
//权限组
public static final String[] ARR_NEED_PERMISSIONS = new ArrayList<String>() {
{
add(Manifest.permission.READ_PHONE_STATE);
add(Manifest.permission.READ_EXTERNAL_STORAGE);
add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}.toArray(new String[0]);
/**
* 验证手机号
*
* @param str 手机号
* @return 是否合法
*/
public static boolean checkMobile(String str) {
Pattern p = Pattern.compile("^[1][3,4,5,7,8,9][0-9]{9}$");
Matcher m = p.matcher(str);
return m.matches();
}
/**
* 判断是否无网络
*
* @param context
* @return 是否断网
*/
public static boolean isNetWorkActive(Context context){
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= 23){
//获取网络属性
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
if (networkCapabilities != null){
Log.e("Avalible","NetworkCapalbilities:"+networkCapabilities.toString());
return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
}else {
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
return info !=null && info.isConnected();
}
return false;
}
/**
* 新增方法实现onError方法的返回提示(通用接口返回)
*/
public static class OnCallback<T> implements Observer<T> {
public OnCallback() {
super();
}
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(T t) {
}
@Override
public void onError(Throwable e) {
if (!isNetWorkActive(App.getInstance())){
ToastUtils.show("网络不给力,请检查网络");
return;
}
if(e instanceof ConnectException){
ToastUtils.show("服务器连接失败,请稍后再试");
}else if(e instanceof SocketTimeoutException){
ToastUtils.show("服务器连接超时,请稍后再试");
}else{
ToastUtils.show("系统繁忙,请稍后再试");
}
}
@Override
public void onComplete() {
}
}
}
修改LoginContract.java
:
public interface LoginContract {
interface View extends BaseView{
void onLoginSuccess(Login_Bean bean);
//仅作为弹窗关闭的方法入口
void onLoginFail();
}
interface Model extends BaseModel{
Observable<Login_Bean> login(String phone,String password);
}
abstract class Presenter extends BasePresenter<View,Model>{
public abstract void login(String phone, String password);
}
}
修改LoginPresenter.java
:
public class LoginPresenter extends LoginContract.Presenter {
public LoginPresenter(LoginContract.View view){
this.mView = view;
this.mModel = new LoginModel();
}
@Override
public void login(String phone, String password) {
mModel.login(phone, password)
.compose(RXHelper.observableIO2Main(App.getInstance()))
.subscribe(new StaticMethodUtils.OnCallback<Login_Bean>(){
@Override
public void onNext(Login_Bean bean) {
mView.onLoginSuccess(bean);
}
@Override
public void onError(Throwable e) {
super.onError(e);
mView.onLoginFail();
}
});
}
}
新增用户信息文件存储
修改Config 类,添加用户信息定义:
interface SpKey {
String TAG_LANGUAGE = "languageSelect";
String AUTH_TOKEN = "authToken";
String USER_INFO = "userInfo";
String PHONE_NUMBER = "phoneNumber";
String LATEST_SONG = "latestSong";
String DAILY_UPDATE_TIME = "dailyUpdateTime";
String DAILY_RECOMMEND = "dailyRecommend";
String LIKE_LIST = "likeList";
}
新增GsonUtil.java
用于json字符转换:
/**
* 字符串和Java类的转换工具
*/
public class GsonUtil {
public static String toJson(Object obj){
String js = createGson().toJson(obj);
return js;
}
private static Gson createGson() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.serializeNulls();
return gsonBuilder.create();
}
/**
* 将字符串转换成对应的Java对象
*/
public static <T> T fromJSON(String json, Class<T> cls) {
try {
return createGson().fromJson(json, cls);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
新增SharePreferenceUtil.java
实现用户token、手机号等存储:
public class SharePreferenceUtil {
private static SharedPreferences sp;
private static SharedPreferences.Editor editor;
private static SharePreferenceUtil mInstance;
private SharePreferenceUtil() {
}
@SuppressLint("CommitPrefEdits")
private static void init(Context context){
if (sp == null){
sp = context.getSharedPreferences(PERERNCE_FILE_NAME,Context.MODE_PRIVATE);
}
editor = sp.edit();
}
public static SharePreferenceUtil getInstance(Context context){
if (mInstance == null){
synchronized (SharePreferenceUtil.class){
if (mInstance == null){
init(context);
mInstance = new SharePreferenceUtil();
}
}
}
return mInstance;
}
/**
* 获取AuthToken
*
* @param defaultValue
* @return
*/
public String getAuthToken(String defaultValue) {
return getString(Config.SpKey.AUTH_TOKEN, defaultValue);
}
private String getString(String key, String defaultValue) {
return sp.getString(key, defaultValue);
}
/**
* 保存用户的信息以及电话号码
*
* @param bean
*/
public void saveUserInfo(Login_Bean bean, String phoneNumber) {
if (bean.getBindings().size() > 1) {
saveAuthToken(bean.getBindings().get(1).getTokenJsonStr());
}
saveAccountNum(phoneNumber);
saveString(Config.SpKey.USER_INFO, GsonUtil.toJson(bean));
}
private void saveAccountNum(String phoneNumber) {
saveString(Config.SpKey.PHONE_NUMBER, phoneNumber);
}
private void saveAuthToken(String token) {
saveString(Config.SpKey.AUTH_TOKEN, token);
}
private void saveString(String key, String value) {
editor.putString(key, value).apply();
}
}
修改SplashActivity.java
,通过getAuthToken(context)方法获取用户aauthToken数据,来作为是否需要登录的判断依据:
String authToken = SharePreferenceUtil.getInstance(SplashActivity.this)
.getAuthToken("");
Log.e("数据",authToken);
if (!TextUtils.isEmpty(authToken)){
//进入主界面
ARouter.getInstance()
.build(Config.ROUTE_HOME)//跳转到选择按钮页面
.withFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.navigation(SplashActivity.this);
overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);
return;
}
ARouter.getInstance()
.build(Config.ROUTE_LOGINSELECT)//跳转到选择按钮页面
.withFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.navigation(SplashActivity.this);
overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out);
修改LoginActivity.java
添加加载框引用,实现登录手机号、密码是否输入、手机号格式是否正确、账号是否存在、密码是否正确等判断。
加载框可以参考我的第一个开源库-DialogLoading弹出加载框
//加载框
implementation 'com.github.Tobeyr1:DialogLoading:1.0.2'
修改LoginActivity.java
:
@Route(path = Config.ROUTE_LOGIN)
public class LoginActivity extends BaseActivity<LoginPresenter> implements LoginContract.View {
@BindView(R.id.edit_usercode)
EditText editText_phone;
@BindView(R.id.edit_userpwd)
EditText editText_psw;
@BindView(R.id.btn_login)
Button button_login;
@BindView(R.id.tv_title)
TextView textView_title;
private String phoneNumber;
private String password;
private AlertDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}
@Override
protected LoginPresenter onCreatePresenter() {
return new LoginPresenter(this);
}
@Override
protected void initData() {
button_login.setOnClickListener(v -> {
phoneNumber = editText_phone.getText().toString().trim();
password = editText_psw.getText().toString().trim();
if (TextUtils.isEmpty(phoneNumber)||TextUtils.isEmpty(password)){
ToastUtils.show("手机号或密码不能为空!");
return;
}
if (!StaticMethodUtils.checkMobile(phoneNumber)){
ToastUtils.show("手机号码格式有误!");
return;
}
//避免快速点击
if (fastClick()){
dialog = AlertDialogUtils.loadingDialog(this,"登录中");
mPresenter.login(phoneNumber,password);
}
});
}
@Override
protected void initModule() {
StatusBarUtil.setTranslucent(this,0);
}
@Override
public void onLoginSuccess(Login_Bean bean) {
AlertDialogUtils.closeDialog(dialog);
if (bean.getCode() == 502){
ToastUtils.show("密码错误");
return;
}
if (bean.getCode() == 501){
ToastUtils.show("帐号不存在");
return;
}
SharePreferenceUtil.getInstance(this).saveUserInfo(bean,phoneNumber);
ToastUtils.show("登录成功");
ARouter.getInstance().build(Config.ROUTE_HOME)
.navigation(this);
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (dialog != null){
AlertDialogUtils.closeDialog(dialog);
dialog = null;
}
}
@Override
public void onLoginFail() {
AlertDialogUtils.closeDialog(dialog);
}
}
修改BaseActivity
基类,添加防多次点击功能:
/**
* 快速点击初始时间戳
* 快速点击,快速点击不响应,否则相应事件
*/
private long lastClick = 0;
/**
* 避免快速点击
*
* @return
*/
public boolean fastClick() {
if (System.currentTimeMillis() - lastClick <= 1000) {
return false;
}
lastClick = System.currentTimeMillis();
return true;
}
下一篇主界面绘制、加载轮播图、减少apk体积( 简易音乐 五)
好了,本篇内容到此解决,有问题欢迎批评指正,觉得不错的也请点个赞奥