Browse Source

add auto login & data sharedPreference

main
MTing 2 weeks ago
parent
commit
1d70e2a6a9
  1. 64
      app/src/main/java/com/ouxuan/oxface/MainActivity.java
  2. 76
      app/src/main/java/com/ouxuan/oxface/data/LoginDataManager.java
  3. 106
      app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java
  4. 2
      app/src/main/java/com/ouxuan/oxface/network/debug/NetworkDebugLogger.java
  5. 6
      app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java
  6. 2
      gradlew

64
app/src/main/java/com/ouxuan/oxface/MainActivity.java

@ -59,6 +59,9 @@ public class MainActivity extends AppCompatActivity {
// 初始化登录数据管理器 // 初始化登录数据管理器
loginDataManager = LoginDataManager.getInstance(this); loginDataManager = LoginDataManager.getInstance(this);
// 检查是否可以自动登录
checkAutoLogin();
// 设置登录按钮点击事件 // 设置登录按钮点击事件
setupLoginButton(); setupLoginButton();
@ -68,7 +71,10 @@ public class MainActivity extends AppCompatActivity {
// 设置密码显示/隐藏切换 // 设置密码显示/隐藏切换
setupPasswordToggle(); setupPasswordToggle();
} }
/**
* 初始化视图组件
*/
private void initViews() { private void initViews() {
editTextUsername = findViewById(R.id.editTextUsername); editTextUsername = findViewById(R.id.editTextUsername);
editTextPassword = findViewById(R.id.editTextPassword); editTextPassword = findViewById(R.id.editTextPassword);
@ -76,6 +82,36 @@ public class MainActivity extends AppCompatActivity {
imageViewPasswordToggle = findViewById(R.id.imageViewPasswordToggle); imageViewPasswordToggle = findViewById(R.id.imageViewPasswordToggle);
} }
/**
* 检查是否可以自动登录
*/
private void checkAutoLogin() {
if (loginDataManager.canAutoLogin()) {
android.util.Log.d("MainActivity", "检测到有效的本地登录数据,尝试自动登录");
// 显示自动登录提示
showToast("检测到登录信息,正在自动登录...");
// 延迟一下显示登录成功弹框给用户看到自动登录的提示
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
if (loginDataManager.isLoggedIn()) {
showToast("自动登录成功!");
showLoginSuccessDialog(loginDataManager.getLoginData());
} else {
android.util.Log.w("MainActivity", "自动登录失败,本地数据可能已失效");
showToast("自动登录失败,请手动登录");
// 清除可能已失效的登录数据
loginDataManager.clearLoginData();
}
}
}, 1000); // 延迟1秒
} else {
android.util.Log.d("MainActivity", "无有效本地登录数据,需要手动登录");
}
}
private void setupLoginButton() { private void setupLoginButton() {
buttonLogin.setOnClickListener(new View.OnClickListener() { buttonLogin.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -401,11 +437,11 @@ public class MainActivity extends AppCompatActivity {
} }
/** /**
* 获取会话ID
* @return 会话ID
* 获取认证Token统一认证方式
* @return Token字符串
*/ */
private String getSessionId() {
return loginDataManager.getSessionId();
private String getAuthToken() {
return loginDataManager.getAuthToken();
} }
/** /**
@ -438,17 +474,27 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void onSuccess(PadApiService.PadListResponse data) { public void onSuccess(PadApiService.PadListResponse data) {
// 加载成功更新下拉框数据 // 加载成功更新下拉框数据
java.util.List<PadApiService.PadInfo> padList = data.getPadList();
java.util.List<PadApiService.PadInfo> padList = data.getPads(); // 使用getPads()而不是getPadList()
java.util.List<String> padNames = new java.util.ArrayList<>(); java.util.List<String> padNames = new java.util.ArrayList<>();
padNames.add("请选择设备"); // 默认选项 padNames.add("请选择设备"); // 默认选项
if (padList != null && !padList.isEmpty()) { if (padList != null && !padList.isEmpty()) {
for (PadApiService.PadInfo padInfo : padList) { for (PadApiService.PadInfo padInfo : padList) {
padNames.add(padInfo.getPadName() + " (" + padInfo.getStatus() + ")");
// 使用hardware_name和status字段
String displayName = padInfo.getHardwareName();
if (padInfo.getStatus() != null && !padInfo.getStatus().equals("unknown")) {
displayName += " (" + padInfo.getStatus() + ")";
}
padNames.add(displayName);
} }
android.util.Log.d("MainActivity", "成功加载 " + padList.size() + " 个设备");
android.util.Log.d("MainActivity", "店铺Logo: " + data.getLogo());
android.util.Log.d("MainActivity", "店铺名称: " + data.getName());
} else { } else {
padNames.add("暂无可用设备"); padNames.add("暂无可用设备");
android.util.Log.w("MainActivity", "服务器返回的设备列表为空");
} }
// 更新Spinner数据 // 更新Spinner数据
@ -536,8 +582,8 @@ public class MainActivity extends AppCompatActivity {
// 显示loading文字 // 显示loading文字
buttonText.setText("正在进入..."); buttonText.setText("正在进入...");
// 调用Pad选择API
NetworkUtils.selectPad(selectedPad.getPadId(), getUserId(), getSessionId(),
// 调用Pad选择API使用token而不是sessionId
NetworkUtils.selectPad(selectedPad.getPadId(), getUserId(), getAuthToken(),
new NetworkCallback<PadApiService.PadSelectResponse>() { new NetworkCallback<PadApiService.PadSelectResponse>() {
@Override @Override
public void onSuccess(PadApiService.PadSelectResponse data) { public void onSuccess(PadApiService.PadSelectResponse data) {

76
app/src/main/java/com/ouxuan/oxface/data/LoginDataManager.java

@ -20,13 +20,14 @@ public class LoginDataManager {
private static final String KEY_AUTH_TOKEN = "auth_token"; private static final String KEY_AUTH_TOKEN = "auth_token";
private static final String KEY_DEVICE_ID = "device_id"; private static final String KEY_DEVICE_ID = "device_id";
private static final String KEY_USER_ID = "user_id"; private static final String KEY_USER_ID = "user_id";
private static final String KEY_SESSION_ID = "session_id";
private static final String KEY_IS_LOGGED_IN = "is_logged_in"; private static final String KEY_IS_LOGGED_IN = "is_logged_in";
private static volatile LoginDataManager instance;
private static final String KEY_TOKEN_SAVE_TIME = "token_save_time"; // token保存时间用于判断有效性
private SharedPreferences preferences; private SharedPreferences preferences;
private Gson gson; private Gson gson;
// 单例实例
private static volatile LoginDataManager instance;
// 内存缓存 // 内存缓存
private PadApiService.PadLoginResponse currentLoginData; private PadApiService.PadLoginResponse currentLoginData;
private boolean isLoggedIn = false; private boolean isLoggedIn = false;
@ -72,7 +73,7 @@ public class LoginDataManager {
editor.putString(KEY_LOGIN_DATA, gson.toJson(loginData)); editor.putString(KEY_LOGIN_DATA, gson.toJson(loginData));
editor.putString(KEY_AUTH_TOKEN, loginData.getToken()); editor.putString(KEY_AUTH_TOKEN, loginData.getToken());
editor.putString(KEY_USER_ID, String.valueOf(loginData.getStadiumId())); // 使用stadium_id作为用户标识 editor.putString(KEY_USER_ID, String.valueOf(loginData.getStadiumId())); // 使用stadium_id作为用户标识
editor.putString(KEY_SESSION_ID, loginData.getToken()); // 使用token作为session_id
editor.putLong(KEY_TOKEN_SAVE_TIME, System.currentTimeMillis()); // 保存token获取时间
editor.putBoolean(KEY_IS_LOGGED_IN, true); editor.putBoolean(KEY_IS_LOGGED_IN, true);
editor.apply(); editor.apply();
@ -89,7 +90,7 @@ public class LoginDataManager {
} }
/** /**
* 获取认证Token
* 获取认证Token统一认证方式
* @return Token字符串 * @return Token字符串
*/ */
public String getAuthToken() { public String getAuthToken() {
@ -111,17 +112,6 @@ public class LoginDataManager {
} }
/** /**
* 获取会话ID
* @return 会话ID
*/
public String getSessionId() {
if (currentLoginData != null) {
return currentLoginData.getToken();
}
return preferences.getString(KEY_SESSION_ID, "");
}
/**
* 获取场馆ID * 获取场馆ID
* @return 场馆ID * @return 场馆ID
*/ */
@ -166,11 +156,29 @@ public class LoginDataManager {
} }
/** /**
* 检查是否已登录
* @return true如果已登录false否则
* 检查是否已登录基于token有效性
* @return true如果已登录且token有效false否则
*/ */
public boolean isLoggedIn() { public boolean isLoggedIn() {
return isLoggedIn && currentLoginData != null;
return isLoggedIn && currentLoginData != null && isTokenValid();
}
/**
* 检查是否可以自动登录
* @return true如果有有效的本地登录数据可以自动登录
*/
public boolean canAutoLogin() {
boolean hasValidData = preferences.getBoolean(KEY_IS_LOGGED_IN, false)
&& !preferences.getString(KEY_AUTH_TOKEN, "").isEmpty()
&& !preferences.getString(KEY_LOGIN_DATA, "").isEmpty();
if (hasValidData) {
Log.d(TAG, "检测到本地有效登录数据,可以自动登录");
} else {
Log.d(TAG, "本地无有效登录数据,需要重新登录");
}
return hasValidData;
} }
/** /**
@ -202,7 +210,7 @@ public class LoginDataManager {
editor.remove(KEY_LOGIN_DATA); editor.remove(KEY_LOGIN_DATA);
editor.remove(KEY_AUTH_TOKEN); editor.remove(KEY_AUTH_TOKEN);
editor.remove(KEY_USER_ID); editor.remove(KEY_USER_ID);
editor.remove(KEY_SESSION_ID);
editor.remove(KEY_TOKEN_SAVE_TIME);
editor.putBoolean(KEY_IS_LOGGED_IN, false); editor.putBoolean(KEY_IS_LOGGED_IN, false);
editor.apply(); editor.apply();
@ -262,7 +270,33 @@ public class LoginDataManager {
*/ */
public boolean isTokenValid() { public boolean isTokenValid() {
String token = getAuthToken(); String token = getAuthToken();
return token != null && !token.trim().isEmpty();
boolean isValid = token != null && !token.trim().isEmpty();
if (isValid) {
// 可以在这里添加token过期时间检查逻辑
long saveTime = preferences.getLong(KEY_TOKEN_SAVE_TIME, 0);
if (saveTime > 0) {
long currentTime = System.currentTimeMillis();
// 这里可以根据实际需求设置token有效期比如7天
// long validPeriod = 7 * 24 * 60 * 60 * 1000L; // 7天
// isValid = (currentTime - saveTime) < validPeriod;
Log.d(TAG, "Token保存时间: " + new java.util.Date(saveTime));
}
}
Log.d(TAG, "Token有效性检查结果: " + isValid);
return isValid;
}
/**
* 获取Token兼容旧代码中可能使用SessionId的地方
* @deprecated 使用getAuthToken()替代项目中统一使用token认证
* @return Token字符串
*/
@Deprecated
public String getSessionId() {
Log.w(TAG, "getSessionId()方法已废弃,项目中统一使用token认证,请使用getAuthToken()");
return getAuthToken();
} }
/** /**

106
app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java

@ -197,29 +197,49 @@ public interface PadApiService {
/** /**
* Pad列表响应模型 * Pad列表响应模型
* 匹配实际API响应格式{"code":0,"data":{"logo":"...","name":"...","pads":[...]}}
*/ */
public static class PadListResponse { public static class PadListResponse {
private java.util.List<PadInfo> padList; // Pad设备列表
private int totalCount; // 总数量
private String lastUpdateTime; // 最后更新时间
@SerializedName("logo")
private String logo; // 店铺Logo
@SerializedName("name")
private String name; // 店铺名称
@SerializedName("pads")
private java.util.List<PadInfo> pads; // Pad设备列表
// Getters and Setters // Getters and Setters
public java.util.List<PadInfo> getPadList() { return padList; }
public void setPadList(java.util.List<PadInfo> padList) { this.padList = padList; }
public String getLogo() { return logo; }
public void setLogo(String logo) { this.logo = logo; }
public int getTotalCount() { return totalCount; }
public void setTotalCount(int totalCount) { this.totalCount = totalCount; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getLastUpdateTime() { return lastUpdateTime; }
public void setLastUpdateTime(String lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; }
public java.util.List<PadInfo> getPads() { return pads; }
public void setPads(java.util.List<PadInfo> pads) { this.pads = pads; }
// 兼容旧代码的方法
public java.util.List<PadInfo> getPadList() { return pads; }
public void setPadList(java.util.List<PadInfo> padList) { this.pads = padList; }
public int getTotalCount() { return pads != null ? pads.size() : 0; }
public String getLastUpdateTime() { return ""; } // 服务器未返回此字段
} }
/** /**
* Pad设备信息模型 * Pad设备信息模型
* 匹配实际API响应格式{"hardware_id":326,"hardware_name":"OX华为M5"}
*/ */
public static class PadInfo { public static class PadInfo {
private String padId; // Pad ID
private String padName; // Pad名称
@SerializedName("hardware_id")
private int hardwareId; // 硬件ID
@SerializedName("hardware_name")
private String hardwareName; // 硬件名称
// 兼容旧代码的字段
private String padType; // Pad类型 private String padType; // Pad类型
private String status; // 状态online/offline/busy private String status; // 状态online/offline/busy
private String location; // 位置 private String location; // 位置
@ -228,29 +248,51 @@ public interface PadApiService {
private String lastActiveTime; // 最后活跃时间 private String lastActiveTime; // 最后活跃时间
// Getters and Setters // Getters and Setters
public String getPadId() { return padId; }
public void setPadId(String padId) { this.padId = padId; }
public int getHardwareId() { return hardwareId; }
public void setHardwareId(int hardwareId) { this.hardwareId = hardwareId; }
public String getHardwareName() { return hardwareName; }
public void setHardwareName(String hardwareName) { this.hardwareName = hardwareName; }
// 兼容旧代码的方法
public String getPadId() { return String.valueOf(hardwareId); }
public void setPadId(String padId) {
try {
this.hardwareId = Integer.parseInt(padId);
} catch (NumberFormatException e) {
this.hardwareId = 0;
}
}
public String getPadName() { return padName; }
public void setPadName(String padName) { this.padName = padName; }
public String getPadName() { return hardwareName; }
public void setPadName(String padName) { this.hardwareName = padName; }
public String getPadType() { return padType; }
public String getPadType() { return padType != null ? padType : "默认类型"; }
public void setPadType(String padType) { this.padType = padType; } public void setPadType(String padType) { this.padType = padType; }
public String getStatus() { return status; }
public String getStatus() { return status != null ? status : "unknown"; }
public void setStatus(String status) { this.status = status; } public void setStatus(String status) { this.status = status; }
public String getLocation() { return location; }
public String getLocation() { return location != null ? location : ""; }
public void setLocation(String location) { this.location = location; } public void setLocation(String location) { this.location = location; }
public String getDescription() { return description; }
public String getDescription() { return description != null ? description : ""; }
public void setDescription(String description) { this.description = description; } public void setDescription(String description) { this.description = description; }
public boolean isSelected() { return isSelected; } public boolean isSelected() { return isSelected; }
public void setSelected(boolean selected) { isSelected = selected; } public void setSelected(boolean selected) { isSelected = selected; }
public String getLastActiveTime() { return lastActiveTime; }
public String getLastActiveTime() { return lastActiveTime != null ? lastActiveTime : ""; }
public void setLastActiveTime(String lastActiveTime) { this.lastActiveTime = lastActiveTime; } public void setLastActiveTime(String lastActiveTime) { this.lastActiveTime = lastActiveTime; }
@Override
public String toString() {
return "PadInfo{" +
"hardwareId=" + hardwareId +
", hardwareName='" + hardwareName + '\'' +
", status='" + status + '\'' +
'}';
}
} }
/** /**
@ -259,13 +301,14 @@ public interface PadApiService {
public static class PadSelectRequest { public static class PadSelectRequest {
private String padId; // 选择的Pad ID private String padId; // 选择的Pad ID
private String userId; // 用户ID private String userId; // 用户ID
private String sessionId; // 会话ID
@SerializedName("token")
private String token; // 访问令牌统一认证方式
private String selectReason; // 选择原因可选 private String selectReason; // 选择原因可选
public PadSelectRequest(String padId, String userId, String sessionId) {
public PadSelectRequest(String padId, String userId, String token) {
this.padId = padId; this.padId = padId;
this.userId = userId; this.userId = userId;
this.sessionId = sessionId;
this.token = token;
} }
// Getters and Setters // Getters and Setters
@ -275,8 +318,21 @@ public interface PadApiService {
public String getUserId() { return userId; } public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; } public void setUserId(String userId) { this.userId = userId; }
public String getSessionId() { return sessionId; }
public void setSessionId(String sessionId) { this.sessionId = sessionId; }
public String getToken() { return token; }
public void setToken(String token) { this.token = token; }
// 兼容旧代码的方法
@Deprecated
public String getSessionId() {
android.util.Log.w("PadSelectRequest", "getSessionId()方法已废弃,请使用getToken()");
return token;
}
@Deprecated
public void setSessionId(String sessionId) {
android.util.Log.w("PadSelectRequest", "setSessionId()方法已废弃,请使用setToken()");
this.token = sessionId;
}
public String getSelectReason() { return selectReason; } public String getSelectReason() { return selectReason; }
public void setSelectReason(String selectReason) { this.selectReason = selectReason; } public void setSelectReason(String selectReason) { this.selectReason = selectReason; }

2
app/src/main/java/com/ouxuan/oxface/network/debug/NetworkDebugLogger.java

@ -14,7 +14,7 @@ import java.net.URLDecoder;
*/ */
public class NetworkDebugLogger { public class NetworkDebugLogger {
private static final String TAG = "jsLog";
private static final String TAG = "OXnet";
private static final boolean ENABLE_DEBUG = true; // 调试开关 private static final boolean ENABLE_DEBUG = true; // 调试开关
/** /**

6
app/src/main/java/com/ouxuan/oxface/network/utils/NetworkUtils.java

@ -403,17 +403,17 @@ public class NetworkUtils {
* Pad选择确认 * Pad选择确认
* @param padId 选择的Pad ID * @param padId 选择的Pad ID
* @param userId 用户ID * @param userId 用户ID
* @param sessionId 会话ID
* @param token 访问令牌统一认证方式
* @param callback 回调接口 * @param callback 回调接口
*/ */
public static void selectPad(String padId, String userId, String sessionId,
public static void selectPad(String padId, String userId, String token,
NetworkCallback<PadApiService.PadSelectResponse> callback) { NetworkCallback<PadApiService.PadSelectResponse> callback) {
if (padApiService == null) { if (padApiService == null) {
callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法"); callback.onError(-1, "NetworkUtils未初始化,请先调用init()方法");
return; return;
} }
PadApiService.PadSelectRequest request = new PadApiService.PadSelectRequest(padId, userId, sessionId);
PadApiService.PadSelectRequest request = new PadApiService.PadSelectRequest(padId, userId, token);
callback.onStart(); callback.onStart();
padApiService.padSelect(request).enqueue(new Callback<ApiResponse<PadApiService.PadSelectResponse>>() { padApiService.padSelect(request).enqueue(new Callback<ApiResponse<PadApiService.PadSelectResponse>>() {

2
gradlew

@ -44,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
DEFAULT_JVM_OPTS="-Xmx1024m -Xms256m"
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"

Loading…
Cancel
Save