package com.example.livestreaming; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.text.TextUtils; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.LinearLayoutManager; import com.example.livestreaming.databinding.ActivitySettingsPageBinding; import com.example.livestreaming.net.ApiClient; import com.example.livestreaming.net.StreamConfig; import java.util.ArrayList; import java.util.List; public class SettingsPageActivity extends AppCompatActivity { public static final String EXTRA_PAGE = "extra_page"; public static final String PAGE_ACCOUNT_SECURITY = "account_security"; public static final String PAGE_PRIVACY = "privacy"; public static final String PAGE_NOTIFICATIONS = "notifications"; public static final String PAGE_CLEAR_CACHE = "clear_cache"; public static final String PAGE_HELP = "help"; public static final String PAGE_ABOUT = "about"; public static final String PAGE_SERVER = "server"; private ActivitySettingsPageBinding binding; private MoreAdapter adapter; private String page; public static void start(Context context, String page) { Intent intent = new Intent(context, SettingsPageActivity.class); intent.putExtra(EXTRA_PAGE, page); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 检查登录状态,设置页面需要登录(除了服务器设置等通用设置) page = getIntent() != null ? getIntent().getStringExtra(EXTRA_PAGE) : null; if (page != null && !PAGE_SERVER.equals(page) && !PAGE_ABOUT.equals(page) && !PAGE_HELP.equals(page)) { if (!AuthHelper.requireLogin(this, "此设置需要登录")) { finish(); return; } } binding = ActivitySettingsPageBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); binding.backButton.setOnClickListener(v -> finish()); // page已在onCreate开始处获取 if (page == null) page = ""; String title = resolveTitle(page); binding.titleText.setText(title); adapter = new MoreAdapter(item -> { if (item == null) return; if (item.getType() != MoreItem.Type.ROW) return; String t = item.getTitle() != null ? item.getTitle() : ""; // 处理服务器设置相关项目 if ("服务器设置".equals(t)) { SettingsPageActivity.start(this, PAGE_SERVER); return; } if ("API服务器".equals(t)) { showApiBaseUrlDialog(); return; } if ("恢复默认API服务器".equals(t)) { ApiClient.clearCustomBaseUrl(getApplicationContext()); ApiClient.getService(getApplicationContext()); refresh(); Toast.makeText(this, "已恢复默认API服务器", Toast.LENGTH_SHORT).show(); return; } if ("直播流服务器".equals(t)) { showStreamHostDialog(); return; } if ("清除直播流覆写".equals(t)) { StreamConfig.clearStreamHostOverride(getApplicationContext()); refresh(); Toast.makeText(this, "已清除直播流覆写", Toast.LENGTH_SHORT).show(); return; } if ("返回".equals(t)) { finish(); return; } // 处理主播相关点击 if ("主播中心".equals(t)) { StreamerCenterActivity.start(this); return; } if ("切换到主播模式".equals(t)) { com.example.livestreaming.net.AuthStore.setStreamerMode(this, true); Toast.makeText(this, "已切换到主播模式", Toast.LENGTH_SHORT).show(); StreamerCenterActivity.start(this); refresh(); return; } if ("切换回普通用户".equals(t)) { com.example.livestreaming.net.AuthStore.setStreamerMode(this, false); Toast.makeText(this, "已切换回普通用户模式", Toast.LENGTH_SHORT).show(); refresh(); return; } if ("申请成为主播".equals(t)) { Intent intent = new Intent(this, StreamerApplyActivity.class); startActivity(intent); return; } if ("退出登录".equals(t)) { showLogoutDialog(); return; } // 处理其他页面的点击事件 if (PAGE_SERVER.equals(page)) { // 服务器设置页面的其他项目已在上面处理 return; } // 调用统一的点击处理方法 handleItemClick(item); }); binding.recyclerView.setLayoutManager(new LinearLayoutManager(this)); binding.recyclerView.setAdapter(adapter); refreshItems(); } private void handleItemClick(MoreItem item) { String title = item.getTitle() != null ? item.getTitle() : ""; switch (page) { case PAGE_ACCOUNT_SECURITY: handleAccountSecurityClick(title); break; case PAGE_PRIVACY: handlePrivacyClick(title); break; case PAGE_NOTIFICATIONS: handleNotificationsClick(title); break; case PAGE_CLEAR_CACHE: handleClearCacheClick(title); break; case PAGE_HELP: handleHelpClick(title); break; case PAGE_ABOUT: handleAboutClick(title); break; } } private void handleAccountSecurityClick(String title) { if ("修改密码".equals(title)) { showChangePasswordDialog(); } else if ("绑定手机号".equals(title)) { showBindPhoneDialog(); } else if ("登录设备管理".equals(title)) { showDeviceManagementDialog(); } } private void handlePrivacyClick(String title) { if ("黑名单".equals(title)) { showBlacklistDialog(); } else if ("权限管理".equals(title)) { showPermissionManagementDialog(); } else if ("隐私政策".equals(title)) { showPrivacyPolicyDialog(); } } private void handleNotificationsClick(String title) { if ("通知设置".equals(title)) { NotificationSettingsActivity.start(this); } else if ("系统通知".equals(title) || "免打扰".equals(title)) { NotificationSettingsActivity.start(this); } } private void handleClearCacheClick(String title) { if ("缓存大小".equals(title)) { showClearAllCacheDialog(); } else if ("图片缓存".equals(title)) { showClearImageCacheDialog(); } } private void handleHelpClick(String title) { if ("常见问题".equals(title)) { showFAQDialog(); } else if ("意见反馈".equals(title)) { showFeedbackDialog(); } else if ("联系客服".equals(title)) { showCustomerServiceDialog(); } } private void handleAboutClick(String title) { if ("版本".equals(title)) { // 版本信息已在subtitle中显示,点击可显示详细信息 showVersionInfoDialog(); } else if ("用户协议".equals(title)) { showUserAgreementDialog(); } else if ("隐私政策".equals(title)) { showPrivacyPolicyDialog(); } } private void refreshItems() { if (PAGE_CLEAR_CACHE.equals(page)) { // 异步加载缓存大小 updateCacheSize(); } else if (PAGE_ABOUT.equals(page)) { // 更新版本信息 updateVersionInfo(); } else { adapter.submitList(buildItems(page)); } } private void updateCacheSize() { new Thread(() -> { long cacheSize = CacheManager.getCacheSize(this); String sizeText = CacheManager.formatCacheSize(this, cacheSize); runOnUiThread(() -> { List items = new ArrayList<>(); items.add(MoreItem.section("存储")); items.add(MoreItem.row("缓存大小", sizeText, R.drawable.ic_grid_24)); items.add(MoreItem.row("图片缓存", "清理封面/头像缓存", R.drawable.ic_palette_24)); adapter.submitList(items); }); }).start(); } private void updateVersionInfo() { try { PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); String versionName = packageInfo.versionName; int versionCode = packageInfo.versionCode; String versionText = "Live Streaming " + versionName + " (Build " + versionCode + ")"; List items = new ArrayList<>(); items.add(MoreItem.section("应用信息")); items.add(MoreItem.row("版本", versionText, R.drawable.ic_menu_24)); items.add(MoreItem.row("用户协议", "服务条款与规则", R.drawable.ic_menu_24)); items.add(MoreItem.row("隐私政策", "隐私保护说明", R.drawable.ic_menu_24)); adapter.submitList(items); } catch (PackageManager.NameNotFoundException e) { List items = new ArrayList<>(); items.add(MoreItem.section("应用信息")); items.add(MoreItem.row("版本", "Live Streaming 1.0", R.drawable.ic_menu_24)); items.add(MoreItem.row("用户协议", "服务条款与规则", R.drawable.ic_menu_24)); items.add(MoreItem.row("隐私政策", "隐私保护说明", R.drawable.ic_menu_24)); adapter.submitList(items); } } private String resolveTitle(String page) { switch (page) { case PAGE_ACCOUNT_SECURITY: return "账号与安全"; case PAGE_PRIVACY: return "隐私"; case PAGE_NOTIFICATIONS: return "通知"; case PAGE_CLEAR_CACHE: return "清理缓存"; case PAGE_HELP: return "帮助与反馈"; case PAGE_ABOUT: return "关于"; case PAGE_SERVER: return "服务器设置"; default: return "设置"; } } private List buildItems(String page) { List list = new ArrayList<>(); if (PAGE_ACCOUNT_SECURITY.equals(page)) { list.add(MoreItem.section("登录与账号")); list.add(MoreItem.row("修改密码", "设置登录密码", R.drawable.ic_person_24)); list.add(MoreItem.row("绑定手机号", "用于登录与找回", R.drawable.ic_people_24)); list.add(MoreItem.row("登录设备管理", "查看并管理已登录设备", R.drawable.ic_grid_24)); return list; } if (PAGE_PRIVACY.equals(page)) { list.add(MoreItem.section("权限与安全")); list.add(MoreItem.row("黑名单", "管理你屏蔽的用户", R.drawable.ic_people_24)); list.add(MoreItem.row("权限管理", "相机、麦克风、定位等", R.drawable.ic_mic_24)); list.add(MoreItem.row("隐私政策", "了解我们如何保护你的数据", R.drawable.ic_globe_24)); return list; } if (PAGE_NOTIFICATIONS.equals(page)) { list.add(MoreItem.section("消息提醒")); list.add(MoreItem.row("通知设置", "管理通知开关和免打扰", R.drawable.ic_notifications_24)); list.add(MoreItem.row("系统通知", "关注、评论、私信提醒", R.drawable.ic_notifications_24)); list.add(MoreItem.row("免打扰", "设置勿扰时段", R.drawable.ic_notifications_24)); return list; } if (PAGE_CLEAR_CACHE.equals(page)) { // 缓存大小将在updateCacheSize中异步更新 return new ArrayList<>(); } if (PAGE_HELP.equals(page)) { list.add(MoreItem.section("帮助")); list.add(MoreItem.row("常见问题", "问题解答与使用指南", R.drawable.ic_chat_24)); list.add(MoreItem.row("意见反馈", "提交你的建议与问题", R.drawable.ic_chat_24)); list.add(MoreItem.row("联系客服", "在线客服", R.drawable.ic_chat_24)); return list; } if (PAGE_ABOUT.equals(page)) { // 版本信息将在updateVersionInfo中更新 return new ArrayList<>(); } if (PAGE_SERVER.equals(page)) { String apiCurrent = ApiClient.getCurrentBaseUrl(getApplicationContext()); String apiMode = ApiClient.isUsingCustomBaseUrl(getApplicationContext()) ? "自定义" : "自动"; String apiSub = (TextUtils.isEmpty(apiCurrent) ? "" : apiCurrent) + (TextUtils.isEmpty(apiMode) ? "" : ("(" + apiMode + ")")); String streamHost = StreamConfig.getStreamHostOverride(getApplicationContext()); String streamSub = TextUtils.isEmpty(streamHost) ? "未覆写(使用服务端返回)" : ("当前覆写:" + streamHost); list.add(MoreItem.section("API")); list.add(MoreItem.row("API服务器", apiSub, R.drawable.ic_globe_24)); list.add(MoreItem.row("恢复默认API服务器", ApiClient.getDefaultAutoBaseUrl(getApplicationContext()), R.drawable.ic_globe_24)); list.add(MoreItem.section("直播流")); list.add(MoreItem.row("直播流服务器", streamSub, R.drawable.ic_globe_24)); list.add(MoreItem.row("清除直播流覆写", "恢复为服务端返回的地址", R.drawable.ic_globe_24)); return list; } list.add(MoreItem.section("通用")); list.add(MoreItem.row("服务器设置", "切换API与直播流地址", R.drawable.ic_globe_24)); list.add(MoreItem.row("关于", "版本信息、协议", R.drawable.ic_menu_24)); // 主播相关入口 list.add(MoreItem.section("主播")); if (com.example.livestreaming.net.AuthStore.isStreamer(this)) { // 已认证主播 if (com.example.livestreaming.net.AuthStore.isStreamerMode(this)) { list.add(MoreItem.row("主播中心", "管理直播间、查看数据", R.drawable.ic_live_24)); list.add(MoreItem.row("切换回普通用户", "退出主播模式", R.drawable.ic_person_24)); } else { list.add(MoreItem.row("切换到主播模式", "进入主播中心", R.drawable.ic_live_24)); } } else { // 未认证主播,显示申请入口 list.add(MoreItem.row("申请成为主播", "认证后可开播", R.drawable.ic_live_24)); } // 退出登录(仅在已登录时显示) if (com.example.livestreaming.net.AuthStore.getToken(this) != null) { list.add(MoreItem.section("账号")); list.add(MoreItem.row("退出登录", "退出当前账号", R.drawable.ic_person_24)); } return list; } private void refresh() { if (adapter == null) return; adapter.submitList(buildItems(page)); } private void showApiBaseUrlDialog() { String current = ApiClient.getCurrentBaseUrl(getApplicationContext()); String[] history = ApiClient.getBaseUrlHistory(getApplicationContext()); List options = new ArrayList<>(); options.add("输入自定义"); if (history != null && history.length > 0) options.add("从历史选择"); options.add("恢复默认(自动)"); new AlertDialog.Builder(this) .setTitle("API服务器\n当前:" + (current != null ? current : "")) .setItems(options.toArray(new String[0]), (d, which) -> { String sel = options.get(which); if ("输入自定义".equals(sel)) { showApiBaseUrlInput(); return; } if ("从历史选择".equals(sel)) { showApiBaseUrlHistory(); return; } if ("恢复默认(自动)".equals(sel)) { ApiClient.clearCustomBaseUrl(getApplicationContext()); ApiClient.getService(getApplicationContext()); refresh(); } }) .setNegativeButton("取消", null) .show(); } private void showApiBaseUrlInput() { EditText input = new EditText(this); input.setHint("例如:http://192.168.1.164:8081/"); String current = ApiClient.getCurrentBaseUrl(getApplicationContext()); if (!TextUtils.isEmpty(current)) input.setText(current); new AlertDialog.Builder(this) .setTitle("输入API BaseUrl") .setView(input) .setNegativeButton("取消", null) .setPositiveButton("保存", (d, w) -> { String v = input.getText() != null ? input.getText().toString().trim() : ""; if (TextUtils.isEmpty(v)) return; ApiClient.setCustomBaseUrl(getApplicationContext(), v); ApiClient.getService(getApplicationContext()); refresh(); }) .show(); } private void showApiBaseUrlHistory() { String[] history = ApiClient.getBaseUrlHistory(getApplicationContext()); if (history == null || history.length == 0) { Toast.makeText(this, "暂无历史记录", Toast.LENGTH_SHORT).show(); return; } new AlertDialog.Builder(this) .setTitle("选择历史API服务器") .setItems(history, (d, which) -> { String sel = history[which]; if (TextUtils.isEmpty(sel)) return; ApiClient.setCustomBaseUrl(getApplicationContext(), sel); ApiClient.getService(getApplicationContext()); refresh(); }) .setNegativeButton("取消", null) .show(); } private void showStreamHostDialog() { String current = StreamConfig.getStreamHostOverride(getApplicationContext()); String[] history = StreamConfig.getStreamHostHistory(getApplicationContext()); List options = new ArrayList<>(); options.add("输入/修改"); if (history != null && history.length > 0) options.add("从历史选择"); options.add("清除覆写"); new AlertDialog.Builder(this) .setTitle("直播流服务器覆写\n当前:" + (!TextUtils.isEmpty(current) ? current : "未设置")) .setItems(options.toArray(new String[0]), (d, which) -> { String sel = options.get(which); if ("输入/修改".equals(sel)) { showStreamHostInput(); return; } if ("从历史选择".equals(sel)) { showStreamHostHistory(); return; } if ("清除覆写".equals(sel)) { StreamConfig.clearStreamHostOverride(getApplicationContext()); refresh(); } }) .setNegativeButton("取消", null) .show(); } private void showStreamHostInput() { EditText input = new EditText(this); input.setHint("例如:192.168.1.164 或 192.168.1.164:1935"); String current = StreamConfig.getStreamHostOverride(getApplicationContext()); if (!TextUtils.isEmpty(current)) input.setText(current); new AlertDialog.Builder(this) .setTitle("输入直播流服务器") .setView(input) .setNegativeButton("取消", null) .setPositiveButton("保存", (d, w) -> { String v = input.getText() != null ? input.getText().toString().trim() : ""; if (TextUtils.isEmpty(v)) return; StreamConfig.setStreamHostOverride(getApplicationContext(), v); refresh(); }) .show(); } private void showStreamHostHistory() { String[] history = StreamConfig.getStreamHostHistory(getApplicationContext()); if (history == null || history.length == 0) { Toast.makeText(this, "暂无历史记录", Toast.LENGTH_SHORT).show(); return; } new AlertDialog.Builder(this) .setTitle("选择历史直播流服务器") .setItems(history, (d, which) -> { String sel = history[which]; if (TextUtils.isEmpty(sel)) return; StreamConfig.setStreamHostOverride(getApplicationContext(), sel); refresh(); }) .setNegativeButton("取消", null) .show(); } private void showChangePasswordDialog() { // TODO: 接入后端接口 - 修改密码 // 接口路径: POST /api/users/{userId}/password/change // 请求参数: // - userId: 用户ID(从token中获取) // - oldPassword: 旧密码 // - newPassword: 新密码 // 返回数据格式: ApiResponse<{success: boolean, message: string}> // 修改成功后,提示用户并关闭对话框 EditText oldPassword = new EditText(this); oldPassword.setHint("请输入旧密码"); oldPassword.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD); EditText newPassword = new EditText(this); newPassword.setHint("请输入新密码"); newPassword.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD); android.widget.LinearLayout layout = new android.widget.LinearLayout(this); layout.setOrientation(android.widget.LinearLayout.VERTICAL); layout.setPadding(dp(24), dp(16), dp(24), dp(8)); layout.addView(oldPassword); layout.addView(newPassword); new AlertDialog.Builder(this) .setTitle("修改密码") .setView(layout) .setPositiveButton("确定", (d, w) -> { Toast.makeText(this, "密码修改功能待实现", Toast.LENGTH_SHORT).show(); }) .setNegativeButton("取消", null) .show(); } private void showBindPhoneDialog() { // TODO: 接入后端接口 - 绑定手机号 // 接口路径: POST /api/users/{userId}/phone/bind // 请求参数: // - userId: 用户ID(从token中获取) // - phone: 手机号 // - verificationCode: 验证码(需要先调用发送验证码接口) // 返回数据格式: ApiResponse<{success: boolean, message: string}> // TODO: 接入后端接口 - 发送手机验证码 // 接口路径: POST /api/sms/send // 请求参数: // - phone: 手机号 // - type: 验证码类型(bind/change等) // 返回数据格式: ApiResponse<{success: boolean, message: string}> // 绑定成功后,提示用户并关闭对话框 EditText phoneInput = new EditText(this); phoneInput.setHint("请输入手机号"); phoneInput.setInputType(android.text.InputType.TYPE_CLASS_PHONE); new AlertDialog.Builder(this) .setTitle("绑定手机号") .setView(phoneInput) .setPositiveButton("确定", (d, w) -> { Toast.makeText(this, "手机号绑定功能待实现", Toast.LENGTH_SHORT).show(); }) .setNegativeButton("取消", null) .show(); } private void showDeviceManagementDialog() { // TODO: 接入后端接口 - 获取登录设备列表 // 接口路径: GET /api/users/{userId}/devices // 请求参数: // - userId: 用户ID(从token中获取) // 返回数据格式: ApiResponse> // DeviceInfo对象应包含: deviceId, deviceName, deviceType, loginTime, lastActiveTime, isCurrent等字段 // TODO: 接入后端接口 - 退出指定设备登录 // 接口路径: DELETE /api/users/{userId}/devices/{deviceId} // 请求参数: // - userId: 用户ID(从token中获取) // - deviceId: 设备ID(路径参数) // 返回数据格式: ApiResponse<{success: boolean}> // 退出成功后,从设备列表中移除该设备 new AlertDialog.Builder(this) .setTitle("登录设备管理") .setMessage("当前登录设备:\n• 本设备(当前)\n\n功能开发中...") .setPositiveButton("确定", null) .show(); } private void showBlacklistDialog() { // 跳转到黑名单管理页面 BlacklistActivity.start(this); } private void showPermissionManagementDialog() { new AlertDialog.Builder(this) .setTitle("权限管理") .setMessage("应用需要以下权限才能正常工作:\n\n" + "• 相机:用于直播和拍照\n" + "• 麦克风:用于直播和语音聊天\n" + "• 位置:用于附近直播和发现功能\n" + "• 存储:用于保存图片和视频\n\n" + "点击确定将跳转到应用信息页面,请在页面中找到\"权限\"选项来管理各项权限。") .setPositiveButton("前往设置", (d, w) -> { try { Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(android.net.Uri.parse("package:" + getPackageName())); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } catch (Exception e) { Toast.makeText(this, "无法打开设置页面,请手动进入系统设置 > 应用管理", Toast.LENGTH_LONG).show(); } }) .setNegativeButton("取消", null) .show(); } private void showPrivacyPolicyDialog() { String privacyPolicy = "隐私政策\n\n" + "我们非常重视您的隐私保护。本隐私政策说明了我们如何收集、使用和保护您的个人信息。\n\n" + "1. 信息收集\n" + "我们可能收集以下信息:\n" + "• 账户信息:昵称、头像、个人资料\n" + "• 设备信息:设备型号、操作系统版本\n" + "• 使用信息:观看记录、互动记录\n" + "• 位置信息:仅在您授权时收集\n\n" + "2. 信息使用\n" + "我们使用收集的信息用于:\n" + "• 提供和改进服务\n" + "• 个性化推荐\n" + "• 保障账户安全\n\n" + "3. 信息保护\n" + "我们采用行业标准的安全措施保护您的信息,不会向第三方出售您的个人信息。\n\n" + "4. 您的权利\n" + "您可以随时访问、修改或删除您的个人信息。\n\n" + "如有疑问,请联系客服。"; new AlertDialog.Builder(this) .setTitle("隐私政策") .setMessage(privacyPolicy) .setPositiveButton("确定", null) .show(); } private void showClearAllCacheDialog() { new AlertDialog.Builder(this) .setTitle("清理缓存") .setMessage("确定要清理所有缓存吗?") .setPositiveButton("确定", (d, w) -> { CacheManager.clearAllCache(this, new CacheManager.OnCacheClearListener() { @Override public void onSuccess(long clearedSize) { runOnUiThread(() -> { refreshItems(); Toast.makeText(SettingsPageActivity.this, "缓存已清理", Toast.LENGTH_SHORT).show(); }); } @Override public void onError(Exception e) { runOnUiThread(() -> { Toast.makeText(SettingsPageActivity.this, "清理缓存失败", Toast.LENGTH_SHORT).show(); }); } }); }) .setNegativeButton("取消", null) .show(); } private void showClearImageCacheDialog() { new AlertDialog.Builder(this) .setTitle("清理图片缓存") .setMessage("确定要清理图片缓存吗?") .setPositiveButton("确定", (d, w) -> { CacheManager.clearImageCache(this, new CacheManager.OnCacheClearListener() { @Override public void onSuccess(long clearedSize) { runOnUiThread(() -> { refreshItems(); Toast.makeText(SettingsPageActivity.this, "图片缓存已清理", Toast.LENGTH_SHORT).show(); }); } @Override public void onError(Exception e) { runOnUiThread(() -> { Toast.makeText(SettingsPageActivity.this, "清理图片缓存失败", Toast.LENGTH_SHORT).show(); }); } }); }) .setNegativeButton("取消", null) .show(); } private void showFAQDialog() { String faq = "常见问题\n\n" + "Q1: 如何开始直播?\n" + "A: 在首页点击\"创建直播间\"按钮,输入房间信息后即可开始直播。\n\n" + "Q2: 如何关注主播?\n" + "A: 在直播间或主播个人主页点击\"关注\"按钮即可。\n\n" + "Q3: 如何发送消息?\n" + "A: 在直播间底部输入框输入消息后发送,或在消息页面与好友聊天。\n\n" + "Q4: 如何修改个人资料?\n" + "A: 进入个人中心,点击\"编辑资料\"即可修改昵称、签名等信息。\n\n" + "Q5: 如何清理缓存?\n" + "A: 在设置页面选择\"清理缓存\",可以清理应用缓存和图片缓存。\n\n" + "Q6: 忘记密码怎么办?\n" + "A: 请联系客服或通过绑定的手机号找回密码。\n\n" + "Q7: 如何举报不良内容?\n" + "A: 在直播间或用户主页可以举报违规内容,我们会及时处理。\n\n" + // TODO: 接入后端接口 - 举报功能 // 接口路径: POST /api/report // 请求参数: // - userId: 当前用户ID(从token中获取) // - targetType: 举报类型(room/user/message/work等) // - targetId: 被举报对象ID // - reason: 举报原因(可选) // - description: 举报描述(可选) // - images (可选): 举报截图URL列表 // 返回数据格式: ApiResponse<{success: boolean, reportId: string}> // 举报成功后,提示用户并记录举报信息 // "更多问题请联系客服。"; new AlertDialog.Builder(this) .setTitle("常见问题") .setMessage(faq) .setPositiveButton("确定", null) .show(); } private void showFeedbackDialog() { // TODO: 接入后端接口 - 提交意见反馈 // 接口路径: POST /api/feedback // 请求参数: // - userId: 用户ID(从token中获取,可选) // - content: 反馈内容(必填) // - contact: 联系方式(可选,邮箱或手机号) // - images (可选): 反馈图片URL列表 // 返回数据格式: ApiResponse<{success: boolean, feedbackId: string}> // 提交成功后,提示用户并关闭对话框 EditText feedbackInput = new EditText(this); feedbackInput.setHint("请输入您的意见或建议"); feedbackInput.setMinLines(5); new AlertDialog.Builder(this) .setTitle("意见反馈") .setView(feedbackInput) .setPositiveButton("提交", (d, w) -> { Toast.makeText(this, "反馈提交功能待实现", Toast.LENGTH_SHORT).show(); }) .setNegativeButton("取消", null) .show(); } private void showCustomerServiceDialog() { String customerService = "联系客服\n\n" + "我们提供多种客服联系方式:\n\n" + "📞 客服电话:\n" + "400-XXX-XXXX\n" + "服务时间:9:00-22:00\n\n" + "💬 在线客服:\n" + "在应用内消息页面联系客服\n\n" + "📧 邮箱:\n" + "support@livestreaming.com\n\n" + "🕐 服务时间:\n" + "周一至周日 9:00-22:00\n\n" + "我们会尽快回复您的问题。"; new AlertDialog.Builder(this) .setTitle("联系客服") .setMessage(customerService) .setPositiveButton("确定", null) .show(); } private void showVersionInfoDialog() { try { PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); String versionName = packageInfo.versionName; int versionCode = packageInfo.versionCode; String message = "Live Streaming\n版本:" + versionName + "\n构建号:" + versionCode; new AlertDialog.Builder(this) .setTitle("版本信息") .setMessage(message) .setPositiveButton("确定", null) .show(); } catch (PackageManager.NameNotFoundException e) { new AlertDialog.Builder(this) .setTitle("版本信息") .setMessage("Live Streaming 1.0") .setPositiveButton("确定", null) .show(); } } private void showUserAgreementDialog() { String userAgreement = "用户协议\n\n" + "欢迎使用直播应用!使用本应用即表示您同意遵守以下条款:\n\n" + "1. 服务条款\n" + "• 您必须年满18周岁才能使用本服务\n" + "• 您需要对自己的账户安全负责\n" + "• 禁止发布违法违规内容\n\n" + "2. 用户行为规范\n" + "• 禁止发布色情、暴力、赌博等违法内容\n" + "• 禁止骚扰、辱骂其他用户\n" + "• 禁止传播虚假信息\n" + "• 禁止进行任何形式的欺诈行为\n\n" + "3. 知识产权\n" + "• 应用内的所有内容受知识产权法保护\n" + "• 未经授权不得复制、传播\n\n" + "4. 免责声明\n" + "• 用户发布的内容不代表本平台观点\n" + "• 平台不对用户行为承担责任\n\n" + "5. 服务变更\n" + "我们保留随时修改或终止服务的权利。\n\n" + "如有疑问,请联系客服。"; new AlertDialog.Builder(this) .setTitle("用户协议") .setMessage(userAgreement) .setPositiveButton("确定", null) .show(); } private void showLogoutDialog() { new AlertDialog.Builder(this) .setTitle("退出登录") .setMessage("确定要退出当前账号吗?") .setPositiveButton("确定", (d, w) -> { // 清除所有登录数据 com.example.livestreaming.net.AuthStore.clearAll(this); Toast.makeText(this, "已退出登录", Toast.LENGTH_SHORT).show(); // 跳转到登录页面并清除任务栈 Intent intent = new Intent(this, LoginActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); finish(); }) .setNegativeButton("取消", null) .show(); } private int dp(int value) { return (int) (value * getResources().getDisplayMetrics().density); } }