zhibo/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java
2026-01-07 18:34:31 +08:00

1459 lines
64 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.example.livestreaming;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.GridLayoutManager;
import com.bumptech.glide.Glide;
import com.example.livestreaming.BuildConfig;
import com.example.livestreaming.databinding.ActivityProfileBinding;
import com.example.livestreaming.ShareUtils;
import com.example.livestreaming.location.TianDiTuLocationService;
import com.example.livestreaming.net.ApiClient;
import com.example.livestreaming.net.ApiResponse;
import com.example.livestreaming.net.PageResponse;
import com.example.livestreaming.net.UserInfoResponse;
import com.example.livestreaming.net.WorksResponse;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import java.util.List;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class ProfileActivity extends AppCompatActivity {
private static final String TAG = "ProfileActivity";
private ActivityProfileBinding binding;
private TianDiTuLocationService locationService;
private ActivityResultLauncher<String[]> requestLocationPermissionLauncher;
private static final String PREFS_NAME = "profile_prefs";
private static final String KEY_NAME = "profile_name";
private static final String KEY_BIO = "profile_bio";
private static final String KEY_LEVEL = "profile_level";
private static final String KEY_FANS_BADGE = "profile_fans_badge";
private static final String KEY_BADGE = "profile_badge";
private static final String KEY_AVATAR_RES = "profile_avatar_res";
private static final String KEY_AVATAR_URI = "profile_avatar_uri";
private static final String KEY_BIRTHDAY = "profile_birthday";
private static final String KEY_GENDER = "profile_gender";
private static final String KEY_LOCATION = "profile_location";
private static final String BIO_HINT_TEXT = "填写个人签名更容易获得关注,点击此处添加";
private ActivityResultLauncher<Intent> editProfileLauncher;
private UserWorksAdapter worksAdapter;
private WorksAdapter myWorksAdapter;
public static void start(Context context) {
Intent intent = new Intent(context, ProfileActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityProfileBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// 初始化定位服务
locationService = new TianDiTuLocationService(this);
// 注册位置权限请求
requestLocationPermissionLauncher = registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(),
result -> {
Boolean fineLocation = result.get(Manifest.permission.ACCESS_FINE_LOCATION);
Boolean coarseLocation = result.get(Manifest.permission.ACCESS_COARSE_LOCATION);
if ((fineLocation != null && fineLocation) || (coarseLocation != null && coarseLocation)) {
// 权限已授予,开始定位
startLocationUpdate();
}
}
);
// 注册编辑资料页面的结果监听
editProfileLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
// 当从EditProfileActivity返回时立即刷新所有数据
loadProfileFromPrefs();
loadAndDisplayTags();
loadProfileInfo();
}
);
loadProfileFromPrefs();
loadUserInfoFromServer(); // 从服务器加载用户信息
loadAndDisplayTags();
loadProfileInfo();
loadFollowStats(); // 加载关注统计
setupEditableAreas();
setupAvatarClick();
setupNavigationClicks();
setupWorksRecycler();
setupProfileTabs();
// 自动获取用户位置并更新IP归属地
requestLocationAndUpdate();
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_profile);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNavigation);
bottomNavigation.setOnItemSelectedListener(item -> {
int id = item.getItemId();
if (id == R.id.nav_home) {
startActivity(new Intent(this, MainActivity.class));
finish();
return true;
}
if (id == R.id.nav_friends) {
startActivity(new Intent(this, FishPondWebViewActivity.class));
finish();
return true;
}
if (id == R.id.nav_wish_tree) {
WishTreeWebViewActivity.start(this);
finish();
return true;
}
if (id == R.id.nav_messages) {
MessagesActivity.start(this);
finish();
return true;
}
if (id == R.id.nav_profile) {
return true;
}
return true;
});
}
private void loadProfileFromPrefs() {
// TODO: 接入后端接口 - 获取用户资料
// 接口路径: GET /api/users/{userId}/profile
// 请求参数:
// - userId: 用户ID路径参数当前用户从token中获取
// 返回数据格式: ApiResponse<UserProfile>
// UserProfile对象应包含: id, name, avatarUrl, bio, level, badge, birthday, gender, location,
// followingCount, fansCount, likesCount等字段
// 首次加载时从接口获取,后续可从本地缓存读取
String n = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_NAME, null);
if (!TextUtils.isEmpty(n)) binding.name.setText(n);
String bio = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIO, null);
if (!TextUtils.isEmpty(bio) && !BIO_HINT_TEXT.equals(bio)) {
binding.bioText.setText(bio);
binding.bioText.setTextColor(0xFF111111);
} else {
binding.bioText.setText(BIO_HINT_TEXT);
binding.bioText.setTextColor(0xFF999999);
}
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
if (!TextUtils.isEmpty(avatarUri)) {
Uri uri = Uri.parse(avatarUri);
// 如果是 file:// 协议,尝试转换为 FileProvider URI
if ("file".equals(uri.getScheme())) {
try {
java.io.File file = new java.io.File(uri.getPath());
if (file.exists()) {
uri = FileProvider.getUriForFile(
this,
getPackageName() + ".fileprovider",
file
);
}
} catch (Exception e) {
// 如果转换失败,使用原始 URI
}
}
Glide.with(this)
.load(uri)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.placeholder(R.drawable.ic_account_circle_24)
.into(binding.avatar);
} else {
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
if (avatarRes != 0) {
Glide.with(this)
.load(avatarRes)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.into(binding.avatar);
} else {
binding.avatar.setImageResource(R.drawable.ic_account_circle_24);
}
}
// 等级/称号/徽章:保持固定显示(例如“月亮/星耀/至尊”),不从本地缓存覆盖。
}
/**
* 从服务器加载用户信息并同步到本地
*/
private void loadUserInfoFromServer() {
if (!AuthHelper.isLoggedIn(this)) {
return;
}
ApiClient.getService(this).getUserInfo().enqueue(new Callback<ApiResponse<UserInfoResponse>>() {
@Override
public void onResponse(Call<ApiResponse<UserInfoResponse>> call, Response<ApiResponse<UserInfoResponse>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
UserInfoResponse userInfo = response.body().getData();
if (userInfo != null) {
syncUserInfoToLocal(userInfo);
}
}
}
@Override
public void onFailure(Call<ApiResponse<UserInfoResponse>> call, Throwable t) {
Log.e(TAG, "加载用户信息失败: " + t.getMessage());
}
});
}
/**
* 同步服务器用户信息到本地并更新UI
*/
private void syncUserInfoToLocal(UserInfoResponse userInfo) {
android.content.SharedPreferences.Editor editor = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit();
// 同步昵称
if (!TextUtils.isEmpty(userInfo.getNickname())) {
editor.putString(KEY_NAME, userInfo.getNickname());
binding.name.setText(userInfo.getNickname());
}
// 同步个性签名
if (!TextUtils.isEmpty(userInfo.getMark())) {
editor.putString(KEY_BIO, userInfo.getMark());
binding.bioText.setText(userInfo.getMark());
binding.bioText.setTextColor(0xFF111111);
}
// 同步头像
if (!TextUtils.isEmpty(userInfo.getAvatar())) {
String avatarUrl = userInfo.getAvatar();
String baseUrl = ApiClient.getCurrentBaseUrl(ProfileActivity.this);
// 处理相对路径
if (!avatarUrl.startsWith("http://") && !avatarUrl.startsWith("https://")) {
if (avatarUrl.startsWith("crmebimage/")) {
avatarUrl = baseUrl.replace("/api/", "/") + avatarUrl;
}
}
editor.putString(KEY_AVATAR_URI, avatarUrl);
Glide.with(ProfileActivity.this)
.load(avatarUrl)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.placeholder(R.drawable.ic_account_circle_24)
.into(binding.avatar);
}
// 同步生日
if (!TextUtils.isEmpty(userInfo.getBirthday())) {
editor.putString(KEY_BIRTHDAY, userInfo.getBirthday());
}
// 同步性别
if (userInfo.getSex() != null) {
String gender = "";
switch (userInfo.getSex()) {
case 1: gender = ""; break;
case 2: gender = ""; break;
case 3: gender = "保密"; break;
}
if (!TextUtils.isEmpty(gender)) {
editor.putString(KEY_GENDER, gender);
}
}
// 同步地址
if (!TextUtils.isEmpty(userInfo.getAddres())) {
editor.putString(KEY_LOCATION, userInfo.getAddres());
}
editor.apply();
// 刷新标签显示
loadAndDisplayTags();
loadProfileInfo();
}
private void setupEditableAreas() {
// TODO: 接入后端接口 - 更新用户资料
// 接口路径: PUT /api/users/{userId}/profile
// 请求参数:
// - userId: 用户ID路径参数从token中获取
// - name (可选): 昵称
// - bio (可选): 个人签名
// - avatarUrl (可选): 头像URL
// - birthday (可选): 生日
// - gender (可选): 性别
// - location (可选): 所在地
// 返回数据格式: ApiResponse<UserProfile>
// 更新成功后,同步更新本地缓存和界面显示
binding.name.setOnClickListener(v -> showEditDialog("编辑昵称", binding.name.getText() != null ? binding.name.getText().toString() : "", text -> {
binding.name.setText(text);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_NAME, text).apply();
}));
binding.bioText.setOnClickListener(v -> {
String current = binding.bioText.getText() != null ? binding.bioText.getText().toString() : "";
String initial = BIO_HINT_TEXT.equals(current) ? "" : current;
showEditDialog("编辑签名", initial, text -> {
if (TextUtils.isEmpty(text) || BIO_HINT_TEXT.equals(text)) {
binding.bioText.setText(BIO_HINT_TEXT);
binding.bioText.setTextColor(0xFF999999);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().remove(KEY_BIO).apply();
} else {
binding.bioText.setText(text);
binding.bioText.setTextColor(0xFF111111);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_BIO, text).apply();
}
});
});
}
private void setupAvatarClick() {
binding.avatar.setOnClickListener(v -> {
AvatarViewerDialog dialog = AvatarViewerDialog.create(this);
// 优先从SharedPreferences读取最新的头像信息因为ImageView可能还在加载中
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
if (!TextUtils.isEmpty(avatarUri)) {
// 使用URI加载确保能正确显示
dialog.setAvatarUri(Uri.parse(avatarUri));
} else if (avatarRes != 0) {
dialog.setAvatarResId(avatarRes);
} else {
// 如果都没有尝试从ImageView获取Drawable
Drawable drawable = binding.avatar.getDrawable();
if (drawable != null) {
dialog.setAvatarDrawable(drawable);
} else {
dialog.setAvatarResId(R.drawable.ic_account_circle_24);
}
}
dialog.show();
});
}
private void setupNavigationClicks() {
binding.topActionSearch.setOnClickListener(v -> TabPlaceholderActivity.start(this, "定位/发现"));
binding.topActionClock.setOnClickListener(v -> {
// 检查登录状态,观看历史需要登录
if (!AuthHelper.requireLogin(this, "查看观看历史需要登录")) {
return;
}
MyRecordsActivity.start(this);
});
binding.topActionMore.setOnClickListener(v -> showMoreOptionsMenu());
binding.copyIdBtn.setOnClickListener(v -> {
String idText = binding.idLine.getText() != null ? binding.idLine.getText().toString() : "";
if (TextUtils.isEmpty(idText)) return;
String digits = idText.replaceAll("\\D+", "");
if (TextUtils.isEmpty(digits)) return;
ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
if (cm != null) {
cm.setPrimaryClip(ClipData.newPlainText("id", digits));
Toast.makeText(this, "已复制:" + digits, Toast.LENGTH_SHORT).show();
}
});
// TODO: 接入后端接口 - 获取关注/粉丝/获赞数量
// 接口路径: GET /api/users/{userId}/stats
// 请求参数:
// - userId: 用户ID路径参数
// 返回数据格式: ApiResponse<{followingCount: number, fansCount: number, likesCount: number}>
// 在ProfileActivity加载时调用更新关注、粉丝、获赞数量显示
binding.following.setOnClickListener(v -> {
// 检查登录状态,查看关注列表需要登录
if (!AuthHelper.requireLogin(this, "查看关注列表需要登录")) {
return;
}
FollowingListActivity.start(this);
});
binding.followers.setOnClickListener(v -> {
// 检查登录状态,查看粉丝列表需要登录
if (!AuthHelper.requireLogin(this, "查看粉丝列表需要登录")) {
return;
}
FansListActivity.start(this);
});
binding.likes.setOnClickListener(v -> {
// 检查登录状态,查看获赞列表需要登录
if (!AuthHelper.requireLogin(this, "查看获赞列表需要登录")) {
return;
}
LikesListActivity.start(this);
});
binding.action1.setOnClickListener(v -> {
// 我的关注
if (!AuthHelper.requireLogin(this, "查看关注列表需要登录")) {
return;
}
startActivity(new Intent(this, FollowingActivity.class));
});
binding.action2.setOnClickListener(v -> {
// 我的点赞(作品+直播间)
if (!AuthHelper.requireLogin(this, "查看点赞需要登录")) {
return;
}
MyLikesActivity.start(this);
});
binding.action3.setOnClickListener(v -> {
// 我的收藏(作品+直播间)
if (!AuthHelper.requireLogin(this, "查看收藏需要登录")) {
return;
}
MyCollectionsActivity.start(this);
});
binding.action4.setOnClickListener(v -> {
// 我的记录 - 跳转到统一记录页面
if (!AuthHelper.requireLogin(this, "查看记录需要登录")) {
return;
}
MyRecordsActivity.start(this);
});
binding.editProfile.setOnClickListener(v -> {
// 检查登录状态,编辑资料需要登录
if (!AuthHelper.requireLogin(this, "编辑资料需要登录")) {
return;
}
Intent intent = new Intent(this, EditProfileActivity.class);
editProfileLauncher.launch(intent);
});
binding.shareHome.setOnClickListener(v -> {
// 检查登录状态,分享个人主页需要登录
if (!AuthHelper.requireLogin(this, "分享个人主页需要登录")) {
return;
}
showShareProfileDialog();
});
// 主播中心按钮点击事件
binding.streamerCenterBtn.setOnClickListener(v -> {
StreamerCenterActivity.start(this);
});
binding.addFriendBtn.setOnClickListener(v -> {
// 我的挚友(原添加好友功能已在挚友页面内)
if (!AuthHelper.requireLogin(this, "查看挚友需要登录")) {
return;
}
startActivity(new Intent(this, MyFriendsActivity.class));
});
// 我的钱包按钮点击事件
binding.walletButton.setOnClickListener(v -> {
// 检查登录状态,查看钱包需要登录
if (!AuthHelper.requireLogin(this, "查看钱包需要登录")) {
return;
}
startActivity(new Intent(this, WalletActivity.class));
});
}
private void setupProfileTabs() {
showTab(0);
binding.profileTabs.addOnTabSelectedListener(new com.google.android.material.tabs.TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(com.google.android.material.tabs.TabLayout.Tab tab) {
if (tab == null) return;
showTab(tab.getPosition());
}
@Override
public void onTabUnselected(com.google.android.material.tabs.TabLayout.Tab tab) {
}
@Override
public void onTabReselected(com.google.android.material.tabs.TabLayout.Tab tab) {
if (tab == null) return;
showTab(tab.getPosition());
}
});
// TODO: 接入后端接口 - 发布作品
// 接口路径: POST /api/works
// 请求参数:
// - userId: 用户ID从token中获取
// - title: 作品标题
// - description: 作品描述(可选)
// - coverUrl: 封面图片URL必填需要先上传图片
// - videoUrl (可选): 视频URL如果是视频作品
// - images (可选): 图片URL列表如果是图片作品
// 返回数据格式: ApiResponse<WorkItem>
// WorkItem对象应包含: id, title, coverUrl, likeCount, viewCount, publishTime等字段
// 发布成功后,刷新作品列表显示
// 空状态的发布按钮
binding.worksPublishBtn.setOnClickListener(v -> {
// 检查登录状态,发布作品需要登录
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
return;
}
PublishWorkActivity.start(this);
});
// 悬浮按钮(固定显示)
binding.fabPublishWork.setOnClickListener(v -> {
// 检查登录状态,发布作品需要登录
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
return;
}
PublishWorkActivity.start(this);
});
binding.likedGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
binding.favGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
binding.profileEditFromTab.setOnClickListener(v -> {
// 检查登录状态,编辑资料需要登录
if (!AuthHelper.requireLogin(this, "编辑资料需要登录")) {
return;
}
Intent intent = new Intent(this, EditProfileActivity.class);
editProfileLauncher.launch(intent);
});
}
private void setupWorksRecycler() {
// 设置我的作品区域
myWorksAdapter = new WorksAdapter(work -> {
if (work != null && work.getId() != null) {
// 从"我"页面进入,显示编辑删除菜单
WorkDetailActivity.start(this, String.valueOf(work.getId()), true);
}
});
binding.myWorksRecycler.setLayoutManager(new GridLayoutManager(this, 2));
binding.myWorksRecycler.setAdapter(myWorksAdapter);
// 发布按钮点击事件
binding.myWorksPublishBtn.setOnClickListener(v -> {
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
return;
}
PublishWorkActivity.start(this);
});
loadMyWorks();
}
private void loadMyWorks() {
if (!AuthHelper.isLoggedIn(this)) {
// 未登录时显示空状态
binding.myWorksRecycler.setVisibility(View.GONE);
binding.myWorksEmptyState.setVisibility(View.VISIBLE);
binding.myWorksCount.setText("0个作品");
return;
}
// 获取当前用户ID
String userIdStr = com.example.livestreaming.net.AuthStore.getUserId(this);
if (userIdStr == null || userIdStr.isEmpty()) {
Log.e(TAG, "无法获取用户ID");
showMyWorksEmpty();
return;
}
int userId;
try {
userId = Integer.parseInt(userIdStr);
} catch (NumberFormatException e) {
Log.e(TAG, "用户ID格式错误: " + userIdStr);
showMyWorksEmpty();
return;
}
ApiClient.getService(this).getUserWorks(userId, 1, 50)
.enqueue(new Callback<ApiResponse<PageResponse<WorksResponse>>>() {
@Override
public void onResponse(Call<ApiResponse<PageResponse<WorksResponse>>> call,
Response<ApiResponse<PageResponse<WorksResponse>>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
PageResponse<WorksResponse> pageData = response.body().getData();
if (pageData != null && pageData.getList() != null && !pageData.getList().isEmpty()) {
List<WorksResponse> works = pageData.getList();
binding.myWorksRecycler.setVisibility(View.VISIBLE);
binding.myWorksEmptyState.setVisibility(View.GONE);
binding.myWorksCount.setText(works.size() + "个作品");
myWorksAdapter.submitList(works);
} else {
showMyWorksEmpty();
}
} else {
Log.e(TAG, "加载我的作品失败: " + (response.body() != null ? response.body().getMessage() : "未知错误"));
showMyWorksEmpty();
}
}
@Override
public void onFailure(Call<ApiResponse<PageResponse<WorksResponse>>> call, Throwable t) {
Log.e(TAG, "加载我的作品失败: " + t.getMessage());
showMyWorksEmpty();
}
});
}
private void showMyWorksEmpty() {
binding.myWorksRecycler.setVisibility(View.GONE);
binding.myWorksEmptyState.setVisibility(View.VISIBLE);
binding.myWorksCount.setText("0个作品");
}
private void loadWorks() {
// 旧方法保留兼容实际使用loadMyWorks
loadMyWorks();
}
private void showTab(int index) {
// TODO: 接入后端接口 - 获取用户作品列表
// 接口路径: GET /api/users/{userId}/works
// 请求参数:
// - userId: 用户ID从token中获取
// - page (可选): 页码
// - pageSize (可选): 每页数量
// 返回数据格式: ApiResponse<List<WorkItem>>
// WorkItem对象应包含: id, title, coverUrl, likeCount, viewCount, publishTime等字段
// TODO: 接入后端接口 - 获取用户收藏列表
// 接口路径: GET /api/users/{userId}/favorites
// 请求参数:
// - userId: 用户ID从token中获取
// - page (可选): 页码
// - pageSize (可选): 每页数量
// 返回数据格式: ApiResponse<List<WorkItem>>
// TODO: 接入后端接口 - 获取用户赞过的作品列表
// 接口路径: GET /api/users/{userId}/liked
// 请求参数:
// - userId: 用户ID从token中获取
// - page (可选): 页码
// - pageSize (可选): 每页数量
// 返回数据格式: ApiResponse<List<WorkItem>>
// 标签页顺序0-作品, 1-收藏, 2-赞过
binding.tabWorks.setVisibility(index == 0 ? View.VISIBLE : View.GONE);
binding.tabFavorites.setVisibility(index == 1 ? View.VISIBLE : View.GONE);
binding.tabLiked.setVisibility(index == 2 ? View.VISIBLE : View.GONE);
// 当切换到作品标签页时,重新加载作品列表
if (index == 0) {
loadWorks();
}
// "资料"标签页已移除
}
private interface OnTextSaved {
void onSaved(String text);
}
private void showEditDialog(String title, String initialValue, OnTextSaved onSaved) {
EditText editText = new EditText(this);
editText.setText(initialValue != null ? initialValue : "");
editText.setSelection(editText.getText() != null ? editText.getText().length() : 0);
editText.setTextColor(0xFF111111);
editText.setHintTextColor(0xFF999999);
if ("编辑签名".equals(title)) {
editText.setHint(BIO_HINT_TEXT);
}
int pad = (int) (16 * getResources().getDisplayMetrics().density);
editText.setPadding(pad, pad, pad, pad);
new AlertDialog.Builder(this)
.setTitle(title)
.setView(editText)
.setNegativeButton("取消", null)
.setPositiveButton("保存", (d, w) -> {
String t = editText.getText() != null ? editText.getText().toString().trim() : "";
if (onSaved != null) onSaved.onSaved(t);
})
.show();
}
@Override
protected void onResume() {
super.onResume();
if (binding != null) {
loadProfileFromPrefs();
loadAndDisplayTags();
loadProfileInfo();
loadFollowStats(); // 刷新关注统计
loadWalletBalance(); // 刷新钱包余额
loadWorks(); // 重新加载作品列表
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_profile);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav);
// 检查主播状态并显示/隐藏主播中心按钮
checkAndUpdateStreamerButton();
// 自动更新位置信息(每次进入页面时)
autoUpdateLocation();
}
}
/**
* 检查主播状态并更新主播中心按钮的显示
*/
private void checkAndUpdateStreamerButton() {
// 如果用户未登录,隐藏主播中心按钮
if (!AuthHelper.isLoggedIn(this)) {
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
return;
}
// 检查主播资格
ApiClient.getService(getApplicationContext()).checkStreamerStatus()
.enqueue(new Callback<ApiResponse<java.util.Map<String, Object>>>() {
@Override
public void onResponse(Call<ApiResponse<java.util.Map<String, Object>>> call,
Response<ApiResponse<java.util.Map<String, Object>>> response) {
if (!response.isSuccessful() || response.body() == null) {
// 接口调用失败,隐藏按钮
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
return;
}
ApiResponse<java.util.Map<String, Object>> body = response.body();
if (body.getCode() != 200 || body.getData() == null) {
// 接口返回错误,隐藏按钮
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
return;
}
java.util.Map<String, Object> data = body.getData();
Boolean isStreamer = data.get("isStreamer") != null && (Boolean) data.get("isStreamer");
Boolean isBanned = data.get("isBanned") != null && (Boolean) data.get("isBanned");
// 只有认证主播且未被封禁才显示主播中心按钮
if (isStreamer && !isBanned && binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.VISIBLE);
} else if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
}
@Override
public void onFailure(Call<ApiResponse<java.util.Map<String, Object>>> call, Throwable t) {
// 网络错误,隐藏按钮
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
}
});
}
private void loadAndDisplayTags() {
String location = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_LOCATION, "");
String gender = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_GENDER, "");
String birthday = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIRTHDAY, "");
// 设置所在地标签 - 支持"省份-城市"格式
if (!TextUtils.isEmpty(location)) {
// 将"省份-城市"格式转换为"省份·城市"显示
String displayLocation = location.replace("-", "·");
binding.tagLocation.setText("IP" + displayLocation);
binding.tagLocation.setVisibility(View.VISIBLE);
} else {
binding.tagLocation.setText("IP广西");
binding.tagLocation.setVisibility(View.VISIBLE);
}
// 设置性别标签
if (!TextUtils.isEmpty(gender)) {
if (gender.contains("")) {
binding.tagGender.setText("");
} else if (gender.contains("")) {
binding.tagGender.setText("");
} else {
binding.tagGender.setText("H");
}
binding.tagGender.setVisibility(View.VISIBLE);
} else {
binding.tagGender.setText("H");
binding.tagGender.setVisibility(View.VISIBLE);
}
// 计算并设置年龄标签
if (!TextUtils.isEmpty(birthday)) {
int age = calculateAge(birthday);
if (age > 0) {
binding.tagAge.setText(age + "");
binding.tagAge.setVisibility(View.VISIBLE);
} else {
binding.tagAge.setVisibility(View.GONE);
}
} else {
binding.tagAge.setVisibility(View.GONE);
}
// 计算并设置星座标签
if (!TextUtils.isEmpty(birthday)) {
String constellation = calculateConstellation(birthday);
if (!TextUtils.isEmpty(constellation)) {
binding.tagConstellation.setText(constellation);
binding.tagConstellation.setVisibility(View.VISIBLE);
} else {
binding.tagConstellation.setVisibility(View.GONE);
}
} else {
binding.tagConstellation.setVisibility(View.GONE);
}
}
private void loadProfileInfo() {
String name = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_NAME, "爱你");
String location = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_LOCATION, "广西");
String bio = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIO, null);
if (binding.profileInfoLine1 != null) {
binding.profileInfoLine1.setText("昵称:" + name);
}
if (binding.profileInfoLine2 != null) {
String locationText = !TextUtils.isEmpty(location) ? location : "广西";
binding.profileInfoLine2.setText("地区:" + locationText);
}
if (binding.profileInfoLine3 != null) {
String bioText = (!TextUtils.isEmpty(bio) && !BIO_HINT_TEXT.equals(bio)) ? bio : "填写个人签名更容易获得关注";
binding.profileInfoLine3.setText("签名:" + bioText);
}
}
private int calculateAge(String birthdayStr) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
Date birthDate = sdf.parse(birthdayStr);
if (birthDate == null) return 0;
Calendar birth = Calendar.getInstance();
birth.setTime(birthDate);
Calendar now = Calendar.getInstance();
int age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR);
if (now.get(Calendar.DAY_OF_YEAR) < birth.get(Calendar.DAY_OF_YEAR)) {
age--;
}
return age;
} catch (ParseException e) {
return 0;
}
}
private String calculateConstellation(String birthdayStr) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
Date birthDate = sdf.parse(birthdayStr);
if (birthDate == null) return "";
Calendar cal = Calendar.getInstance();
cal.setTime(birthDate);
int month = cal.get(Calendar.MONTH) + 1; // Calendar.MONTH 从0开始
int day = cal.get(Calendar.DAY_OF_MONTH);
// 星座计算
if ((month == 3 && day >= 21) || (month == 4 && day <= 19)) {
return "白羊座";
} else if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) {
return "金牛座";
} else if ((month == 5 && day >= 21) || (month == 6 && day <= 21)) {
return "双子座";
} else if ((month == 6 && day >= 22) || (month == 7 && day <= 22)) {
return "巨蟹座";
} else if ((month == 7 && day >= 23) || (month == 8 && day <= 22)) {
return "狮子座";
} else if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) {
return "处女座";
} else if ((month == 9 && day >= 23) || (month == 10 && day <= 23)) {
return "天秤座";
} else if ((month == 10 && day >= 24) || (month == 11 && day <= 22)) {
return "天蝎座";
} else if ((month == 11 && day >= 23) || (month == 12 && day <= 21)) {
return "射手座";
} else if ((month == 12 && day >= 22) || (month == 1 && day <= 19)) {
return "摩羯座";
} else if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) {
return "水瓶座";
} else if ((month == 2 && day >= 19) || (month == 3 && day <= 20)) {
return "双鱼座";
}
return "";
} catch (ParseException e) {
return "";
}
}
/**
* 显示更多选项菜单
*/
private void showMoreOptionsMenu() {
String[] options = {"黑名单管理", "设置", "关于"};
new androidx.appcompat.app.AlertDialog.Builder(this)
.setItems(options, (dialog, which) -> {
switch (which) {
case 0:
// 黑名单管理
if (!AuthHelper.requireLogin(this, "查看黑名单需要登录")) {
return;
}
BlacklistActivity.start(this);
break;
case 1:
// 设置
TabPlaceholderActivity.start(this, "设置");
break;
case 2:
// 关于
TabPlaceholderActivity.start(this, "关于");
break;
}
})
.show();
}
/**
* 显示分享个人主页对话框
*/
private void showShareProfileDialog() {
// 获取用户ID
String idText = binding.idLine.getText() != null ? binding.idLine.getText().toString() : "";
String digits = !TextUtils.isEmpty(idText) ? idText.replaceAll("\\D+", "") : "";
if (TextUtils.isEmpty(digits)) {
digits = "24187196"; // 默认ID
}
// 直接生成分享链接
String shareLink = ShareUtils.generateProfileShareLink(digits);
ShareUtils.shareLink(this, shareLink, "个人主页", "来看看我的主页吧");
}
/**
* 加载关注统计数据
*/
private void loadFollowStats() {
com.example.livestreaming.net.ApiService apiService =
com.example.livestreaming.net.ApiClient.getService(this);
retrofit2.Call<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> call =
apiService.getFollowStats(null); // null表示查询当前用户
call.enqueue(new retrofit2.Callback<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>>() {
@Override
public void onResponse(retrofit2.Call<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> call,
retrofit2.Response<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> response) {
if (response.isSuccessful() && response.body() != null) {
com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>> apiResponse = response.body();
if (apiResponse.getCode() == 200 && apiResponse.getData() != null) {
java.util.Map<String, Object> stats = apiResponse.getData();
// 更新关注数
Object followingCount = stats.get("followingCount");
if (followingCount != null) {
int count = 0;
if (followingCount instanceof Number) {
count = ((Number) followingCount).intValue();
}
binding.following.setText(count + "\n关注");
// 更新快捷操作区域的关注数
android.widget.TextView followingCountText = findViewById(R.id.followingCount);
if (followingCountText != null) {
followingCountText.setText(count + "");
}
}
// 更新粉丝数
Object followersCount = stats.get("followersCount");
if (followersCount != null) {
int count = 0;
if (followersCount instanceof Number) {
count = ((Number) followersCount).intValue();
}
binding.followers.setText(count + "\n粉丝");
}
}
}
}
@Override
public void onFailure(retrofit2.Call<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> call, Throwable t) {
// 忽略错误,使用默认显示
}
});
// 加载收藏数(点赞的直播间数量)
loadLikedRoomsCount();
// 加载好友数量
loadFriendsCount();
}
/**
* 加载好友数量
*/
private void loadFriendsCount() {
if (!AuthHelper.isLoggedIn(this)) {
return;
}
String token = com.example.livestreaming.net.AuthStore.getToken(this);
if (token == null) {
return;
}
String url = ApiConfig.getBaseUrl() + "/api/front/friends?page=1&pageSize=1";
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.addHeader("Authori-zation", token)
.get()
.build();
client.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, java.io.IOException e) {
// 忽略错误
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws java.io.IOException {
String body = response.body() != null ? response.body().string() : "";
runOnUiThread(() -> {
try {
org.json.JSONObject json = new org.json.JSONObject(body);
if (json.optInt("code", -1) == 200) {
org.json.JSONObject data = json.optJSONObject("data");
if (data != null) {
long total = data.optLong("total", 0);
android.widget.TextView friendsCountText = findViewById(R.id.friendsCount);
if (friendsCountText != null) {
friendsCountText.setText(total + "");
}
}
}
} catch (Exception e) {
// 忽略解析错误
}
});
}
});
}
/**
* 加载收藏数(点赞的直播间数量)
*/
private void loadLikedRoomsCount() {
com.example.livestreaming.net.ApiService apiService =
com.example.livestreaming.net.ApiClient.getService(this);
retrofit2.Call<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> call =
apiService.getMyLikedRooms(1, 1); // 只获取第一页,用于获取总数
call.enqueue(new retrofit2.Callback<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>>() {
@Override
public void onResponse(retrofit2.Call<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> call,
retrofit2.Response<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> response) {
if (response.isSuccessful() && response.body() != null) {
com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>> apiResponse = response.body();
if (apiResponse.getCode() == 200 && apiResponse.getData() != null) {
com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>> pageData = apiResponse.getData();
Long total = pageData.getTotal();
// 更新快捷操作区域的收藏数
android.widget.TextView likedRoomsCountText = findViewById(R.id.likedRoomsCount);
if (likedRoomsCountText != null) {
likedRoomsCountText.setText((total != null ? total : 0) + "个直播间");
}
}
}
}
@Override
public void onFailure(retrofit2.Call<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> call, Throwable t) {
// 忽略错误,使用默认显示
}
});
}
/**
* 加载钱包余额
*/
private void loadWalletBalance() {
if (!AuthHelper.isLoggedIn(this)) {
return;
}
ApiClient.getService(this).getVirtualBalance()
.enqueue(new Callback<ApiResponse<java.util.Map<String, Object>>>() {
@Override
public void onResponse(Call<ApiResponse<java.util.Map<String, Object>>> call,
Response<ApiResponse<java.util.Map<String, Object>>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
java.util.Map<String, Object> data = response.body().getData();
if (data != null && data.containsKey("balance")) {
Object balanceObj = data.get("balance");
String balanceStr = "0";
if (balanceObj instanceof Number) {
double balance = ((Number) balanceObj).doubleValue();
// 如果是整数,不显示小数点
if (balance == Math.floor(balance)) {
balanceStr = String.valueOf((int) balance);
} else {
balanceStr = String.format("%.2f", balance);
}
} else if (balanceObj instanceof String) {
balanceStr = (String) balanceObj;
}
if (binding.walletBalance != null) {
binding.walletBalance.setText(balanceStr);
}
}
}
}
@Override
public void onFailure(Call<ApiResponse<java.util.Map<String, Object>>> call, Throwable t) {
// 忽略错误,使用默认显示
}
});
}
/**
* 请求位置权限并更新位置
*/
private void requestLocationAndUpdate() {
Log.d(TAG, "========== 开始位置自动更新流程 ==========");
// 检查是否已有位置权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "✅ 已有位置权限,直接开始定位");
// 已有权限,直接开始定位
startLocationUpdate();
} else {
Log.d(TAG, "⚠️ 没有位置权限,请求权限");
// 静默请求权限不显示Toast
requestLocationPermissionLauncher.launch(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
});
}
}
/**
* 开始定位并更新位置信息
*/
private void startLocationUpdate() {
Log.d(TAG, "📍 调用天地图定位服务...");
locationService.startLocation(new TianDiTuLocationService.OnLocationResultListener() {
@Override
public void onSuccess(String province, String city, String address, double latitude, double longitude) {
Log.d(TAG, "✅ 定位成功 - 省份: " + province + ", 城市: " + city + ", 完整地址: " + address);
Log.d(TAG, "📍 经纬度 - 纬度: " + latitude + ", 经度: " + longitude);
runOnUiThread(() -> {
// 格式化地址:省份-城市
String location = "";
if (!TextUtils.isEmpty(province) && !TextUtils.isEmpty(city)) {
// 如果城市名包含省份名,去掉省份
if (city.startsWith(province)) {
location = city;
Log.d(TAG, "城市名包含省份名,只使用城市: " + location);
} else {
location = province + "-" + city;
Log.d(TAG, "格式化为省份-城市: " + location);
}
} else if (!TextUtils.isEmpty(province)) {
location = province;
Log.d(TAG, "只有省份: " + location);
} else if (!TextUtils.isEmpty(city)) {
location = city;
Log.d(TAG, "只有城市: " + location);
}
if (!TextUtils.isEmpty(location)) {
Log.d(TAG, "💾 保存位置到本地: " + location);
// 保存到本地
getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
.edit()
.putString(KEY_LOCATION, location)
.apply();
Log.d(TAG, "🔄 刷新页面显示");
// 刷新显示
loadAndDisplayTags();
Log.d(TAG, "🌐 准备更新到服务器数据库(包含经纬度)");
// 更新到服务器数据库(包含经纬度)
updateLocationToServer(location, latitude, longitude);
Log.d(TAG, "✅ IP归属地更新成功: " + location);
} else {
Log.w(TAG, "⚠️ 位置信息为空,跳过更新");
}
});
}
@Override
public void onError(String error) {
// 静默失败,不显示错误提示
Log.e(TAG, "❌ 位置获取失败: " + error);
}
});
}
/**
* 更新位置信息到服务器数据库(包含经纬度)
*/
private void updateLocationToServer(String location, double latitude, double longitude) {
if (!AuthHelper.isLoggedIn(this)) {
Log.w(TAG, "用户未登录,跳过位置更新");
return;
}
Log.d(TAG, "========== 开始更新位置到服务器 ==========");
Log.d(TAG, "准备更新位置到服务器: " + location);
Log.d(TAG, "经纬度: 纬度=" + latitude + ", 经度=" + longitude);
// 创建更新请求
com.example.livestreaming.net.UserEditRequest request = new com.example.livestreaming.net.UserEditRequest();
request.setAddres(location);
request.setLatitude(latitude);
request.setLongitude(longitude);
Log.d(TAG, "请求对象创建完成");
Log.d(TAG, " - addres: " + request.getAddres());
Log.d(TAG, " - latitude: " + request.getLatitude());
Log.d(TAG, " - longitude: " + request.getLongitude());
Log.d(TAG, " - nickname: " + request.getNickname());
Log.d(TAG, "发送位置更新请求到: /api/front/user/edit");
ApiClient.getService(this).updateUserInfo(request)
.enqueue(new Callback<ApiResponse<Object>>() {
@Override
public void onResponse(Call<ApiResponse<Object>> call, Response<ApiResponse<Object>> response) {
Log.d(TAG, "========== 收到服务器响应 ==========");
Log.d(TAG, "HTTP状态码: " + response.code());
if (response.isSuccessful() && response.body() != null) {
ApiResponse<Object> body = response.body();
Log.d(TAG, "响应体不为空");
Log.d(TAG, " - code: " + body.getCode());
Log.d(TAG, " - message: " + body.getMessage());
Log.d(TAG, " - data: " + body.getData());
if (body.isOk()) {
Log.d(TAG, "✅✅✅ 位置信息(含经纬度)已成功同步到服务器数据库 ✅✅✅");
Log.d(TAG, "更新的位置: " + location);
Log.d(TAG, "更新的经纬度: " + latitude + ", " + longitude);
Toast.makeText(ProfileActivity.this, "位置已更新: " + location, Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "❌ 服务器返回错误");
Log.e(TAG, "错误码: " + body.getCode());
Log.e(TAG, "错误信息: " + body.getMessage());
Toast.makeText(ProfileActivity.this, "位置更新失败: " + body.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
Log.e(TAG, "❌ 响应不成功或响应体为空");
Log.e(TAG, "HTTP状态码: " + response.code());
try {
if (response.errorBody() != null) {
String errorBody = response.errorBody().string();
Log.e(TAG, "错误响应体: " + errorBody);
}
} catch (Exception e) {
Log.e(TAG, "读取错误响应失败", e);
}
}
Log.d(TAG, "========== 位置更新流程结束 ==========");
}
@Override
public void onFailure(Call<ApiResponse<Object>> call, Throwable t) {
Log.e(TAG, "========== 网络请求失败 ==========");
Log.e(TAG, "错误类型: " + t.getClass().getName());
Log.e(TAG, "错误消息: " + t.getMessage(), t);
Toast.makeText(ProfileActivity.this, "位置更新网络错误", Toast.LENGTH_SHORT).show();
}
});
}
/**
* 自动更新位置信息(每次进入页面时调用)
* 静默更新,不显示任何提示
*/
private void autoUpdateLocation() {
Log.d(TAG, "========== 自动更新位置开始 ==========");
// 检查是否登录
if (!AuthHelper.isLoggedIn(this)) {
Log.d(TAG, "用户未登录,跳过自动位置更新");
return;
}
// 检查位置权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "没有位置权限,跳过自动位置更新");
return;
}
Log.d(TAG, "开始自动获取位置...");
// 开始定位
locationService.startLocation(new TianDiTuLocationService.OnLocationResultListener() {
@Override
public void onSuccess(String province, String city, String address, double latitude, double longitude) {
Log.d(TAG, "✅ 自动定位成功");
Log.d(TAG, " 省份: " + province);
Log.d(TAG, " 城市: " + city);
Log.d(TAG, " 完整地址: " + address);
Log.d(TAG, " 纬度: " + latitude);
Log.d(TAG, " 经度: " + longitude);
runOnUiThread(() -> {
// 格式化地址:省份-城市
String location = "";
if (!TextUtils.isEmpty(province) && !TextUtils.isEmpty(city)) {
if (city.startsWith(province)) {
location = city;
} else {
location = province + "-" + city;
}
} else if (!TextUtils.isEmpty(province)) {
location = province;
} else if (!TextUtils.isEmpty(city)) {
location = city;
}
if (!TextUtils.isEmpty(location)) {
Log.d(TAG, "格式化后的位置: " + location);
// 保存到本地
getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
.edit()
.putString(KEY_LOCATION, location)
.apply();
// 刷新显示
loadAndDisplayTags();
// 静默更新到服务器不显示Toast
updateLocationToServerSilently(location, latitude, longitude);
Log.d(TAG, "✅ 自动位置更新完成: " + location);
} else {
Log.w(TAG, "位置信息为空,跳过更新");
}
});
}
@Override
public void onError(String error) {
// 静默失败,只记录日志
Log.d(TAG, "自动定位失败(静默): " + error);
}
});
}
/**
* 静默更新位置到服务器不显示Toast提示
*/
private void updateLocationToServerSilently(String location, double latitude, double longitude) {
Log.d(TAG, "========== 静默更新位置到服务器 ==========");
Log.d(TAG, "位置: " + location);
Log.d(TAG, "经纬度: " + latitude + ", " + longitude);
// 创建更新请求
com.example.livestreaming.net.UserEditRequest request = new com.example.livestreaming.net.UserEditRequest();
request.setAddres(location);
request.setLatitude(latitude);
request.setLongitude(longitude);
ApiClient.getService(this).updateUserInfo(request)
.enqueue(new Callback<ApiResponse<Object>>() {
@Override
public void onResponse(Call<ApiResponse<Object>> call, Response<ApiResponse<Object>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
Log.d(TAG, "✅ 位置信息已静默更新到服务器");
Log.d(TAG, " 地址: " + location);
Log.d(TAG, " 经纬度: " + latitude + ", " + longitude);
} else {
Log.w(TAG, "位置更新失败: " + (response.body() != null ? response.body().getMessage() : "未知错误"));
}
}
@Override
public void onFailure(Call<ApiResponse<Object>> call, Throwable t) {
Log.w(TAG, "位置更新网络错误: " + t.getMessage());
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 停止定位服务
if (locationService != null) {
locationService.stopLocation();
}
}
}