Files
frontend/src/screens/profile/PrivacyPolicyScreen.tsx
lafay f3d54a3f4c
Some checks failed
Frontend CI / ota (android) (push) Has been cancelled
Frontend CI / ota (ios) (push) Has been cancelled
Frontend CI / build-and-push-web (push) Has been cancelled
Frontend CI / build-android-apk (push) Failing after 7m23s
feat(background): implement user consent mechanism for auto-start functionality
Add auto-start consent system that requires explicit user permission before enabling background sync services. Users can now choose between silent mode (no auto-start) or background mode (15-minute sync intervals).

- Add consent service with AutoStartMode enum and storage utilities
- Create withRemoveAutoStart Expo plugin to disable Android auto-start defaults
- Integrate consent checks into JPush service, background task manager, and foreground service
- Add auto-start consent UI in notification settings with descriptive dialog
- Update privacy policy with section 8 explaining auto-start scenarios and user controls
- Change default sync mode from BATTERY_SAVER to DISABLED
- Export reinitBackgroundService function for re-initializing after consent changes
- Merge OTA Android and iOS workflows into matrix build
- Add release signing config in withSigning plugin for Android
- Expand .dockerignore with native credential and build artifact exclusions
2026-06-15 20:43:15 +08:00

381 lines
16 KiB
TypeScript
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.
/**
* 隐私政策页面 PrivacyPolicyScreen
* 威友 - 隐私政策
* 扁平化设计风格
*/
import React, { useMemo } from 'react';
import {
View,
StyleSheet,
ScrollView,
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { useRouter } from 'expo-router';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import {
useAppColors,
spacing,
type AppColors,
} from '../../theme';
import { Text, SimpleHeader } from '../../components/common';
import { useResponsive, useResponsiveSpacing } from '../../hooks';
// 内容最大宽度
const CONTENT_MAX_WIDTH = 400;
// 威友橙主题色
const THEME_COLORS = {
primary: '#FF6B35',
};
// 政策最后更新日期
const LAST_UPDATED = '2026年6月15日';
// 隐私政策内容
const PRIVACY_SECTIONS = [
{
title: '引言',
content: `威友(以下简称"我们"或"本应用")非常重视用户的隐私和个人信息保护。我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。
本隐私政策旨在帮助您了解我们如何收集、使用、存储、共享和保护您的个人信息,以及您享有的相关权利。请您在使用我们的服务前,仔细阅读并理解本隐私政策的全部内容。
【敏感个人信息提示】请您注意,您发布的照片、视频可能包含生物识别信息,您的位置信息属于行踪轨迹信息,通讯录信息属于社交关系信息,以上均属于敏感个人信息。我们收集这些信息是为了实现校园社交的核心功能,请您谨慎考虑是否提供。拒绝提供敏感个人信息仅会影响相关功能的使用,不会影响您使用其他服务。`,
},
{
title: '一、我们收集的信息',
content: `1.1 您主动提供的信息
当您注册、登录或使用我们的服务时,您可能需要提供以下信息:
• 账号信息:手机号、邮箱地址、用户名、密码等
• 个人资料:昵称、头像、性别、生日、学校、专业等
• 联系信息:真实姓名、地址(用于特定功能)
• 内容信息:您发布的内容、评论、私信等
1.2 我们在您使用服务时收集的信息
• 设备信息包括设备型号、操作系统版本、设备设置、唯一设备标识符如IMEI、Android ID、IDFA、OAID、MAC地址等、IP地址等
• 日志信息IP地址、访问时间、浏览记录、操作日志等
• 相机/相册权限:用于发布动态、更换头像。我们仅在您主动触发相关功能时申请权限,且不会在后台持续收集
• 通讯录权限:经您授权后用于查找好友`,
},
{
title: '二、我们如何使用信息',
content: `2.1 我们使用收集的信息用于以下目的:
• 为您提供注册、登录及身份验证服务
• 为您展示个性化的内容推荐
• 实现社交功能,如好友推荐、内容分享、附近的人
• 向您发送服务通知、安全提示
• 改善和优化我们的产品和服务
• 保护账号安全,防范欺诈和恶意行为
• 遵守法律法规的要求
2.2 我们使用Cookie和同类技术
我们使用Cookie和同类技术如Web Beacon、Pixel标签、本地存储来确保应用正常运转、记住您的偏好、分析您使用我们服务的情况。具体包括
• 用于记住您的登录状态
• 了解您的使用偏好,提供个性化服务
• 分析服务使用情况,优化产品体验
• 用于广告归因和效果分析
我们不会将Cookie用于本政策所述目的之外的任何用途。您可以通过设备设置管理Cookie但这可能影响某些功能的使用。`,
},
{
title: '三、信息的共享与披露',
content: `3.1 我们不会将您的个人信息出售给任何第三方,但在以下情况下可能会共享或披露您的信息:
3.2 经您同意的情况
在获得您的明确同意后,我们会与第三方共享您的个人信息。
3.3 与我们的关联公司共享
为向您提供一致的服务体验,我们可能会与关联公司共享必要的个人信息。
3.4 与服务提供商共享
我们可能会委托第三方服务提供商处理您的信息,如云服务提供商、支付服务提供商、数据分析服务商、推送服务商等。这些服务提供商仅能在我们授权的范围内使用您的信息,且我们要求其遵守严格的保密义务。
3.5 法律法规要求及无需征得同意的情形
在以下情况下,我们可能会披露您的信息,且无需征得您的授权同意:
1与国家安全、国防安全有关的
2与公共安全、公共卫生、重大公共利益有关的
3与犯罪侦查、起诉、审判和判决执行等有关的
4出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的
5所收集的个人信息是个人信息主体自行向社会公众公开的
6从合法公开披露的信息中收集个人信息的如合法的新闻报道、政府信息公开等渠道
7根据个人信息主体要求签订和履行合同所必需的
8为配合学校、教育机构或相关主管部门履行法定管理职责如学籍管理、校园安全、突发事件处理等
9法律法规规定的其他情形。
3.6 匿名化信息
我们可能会对您的个人信息进行匿名化处理,使其无法识别特定个人,然后使用或共享这些匿名化信息。`,
},
{
title: '四、信息的存储与保护',
content: `4.1 信息存储
• 原则上,我们在中华人民共和国境内收集和产生的个人信息,将存储在中华人民共和国境内
• 如部分服务需要使用境外服务器(如跨境数据传输),我们会单独征得您的授权同意,并确保符合法律法规要求
• 我们会采取合理的技术和管理措施保护您的信息安全
• 我们只会在达成本隐私政策所述目的所需的期限内保留您的信息
4.2 安全措施
• 使用加密技术保护数据传输安全
• 实施访问控制,限制对个人信息的访问
• 定期进行安全审计和风险评估
• 对员工进行隐私保护培训
4.3 安全事件处理
如发生个人信息泄露等安全事件,我们会:
• 及时采取补救措施
• 按照法律法规要求通知您和监管部门
• 配合相关部门进行调查`,
},
{
title: '五、您的权利',
content: `5.1 访问和更正
您有权访问和更正您的个人信息。您可以在应用内的"设置"-"编辑资料"中查看和修改大部分个人信息。
5.2 删除
在以下情况下,您可以要求我们删除您的个人信息:
• 我们处理信息的行为违反法律法规
• 我们未经您同意收集、使用您的信息
• 您不再使用我们的服务并要求删除
• 我们违反与您的约定处理您的信息
5.3 撤回同意
您可以随时撤回对我们收集、使用您个人信息的同意。但请注意,撤回同意可能会影响您使用某些服务。
5.4 注销账号
您可以在"设置"-"账号安全"中申请注销账号。注销后我们将停止为您提供服务并删除或匿名化您的个人信息。但根据法律法规规定如《网络安全法》要求的日志留存不少于6个月我们需要保留部分必要信息以配合监管、处理历史纠纷或履行法定义务。
5.5 投诉与建议
如果您对我们的隐私政策或信息处理有任何疑问或建议请联系我们system@qczlit.cn`,
},
{
title: '六、未成年人保护',
content: `6.1 我们非常重视对未成年人个人信息的保护。我们的服务主要面向大学生及成年用户。
6.2 如果您是未满18周岁的未成年人在使用我们的服务前请确保在监护人的陪同下阅读本隐私政策并在获得监护人同意后再使用我们的服务。
6.3 如果您是未成年人的监护人,请监督您的被监护人使用本服务。
6.4 如果我们发现自己在未事先获得监护人同意的情况下收集了未成年人的个人信息,我们会尽快删除相关数据。`,
},
{
title: '七、第三方SDK目录',
content: `为了保障App的稳定运行或实现特定功能我们可能接入第三方SDK。截至本隐私政策更新之日我们主要使用以下服务
1. 极光推送JPush
• 提供方:深圳市和讯华谷信息技术有限公司
• 使用目的:实现消息推送功能,向您的设备发送通知提醒
• 收集的个人信息设备标识符Registration ID、Android ID、IMEI、OAID、设备型号、操作系统版本、IP地址、应用列表信息
• 隐私政策https://www.jiguang.cn/privacy
2. Expo推送服务
• 提供方Expo650 Industries, Inc.
• 使用目的:辅助消息推送通道管理
• 收集的个人信息设备推送令牌Push Token、设备标识符
3. WorkManagerAndroid系统组件
• 提供方Google LLC
• 使用目的:在用户同意自启动后,执行后台消息同步任务
• 收集的个人信息:无额外个人信息收集
• 隐私政策https://policies.google.com/privacy
4. expo-task-manager / expo-background-task
• 提供方Expo650 Industries, Inc.
• 使用目的:在用户同意自启动后,管理后台任务调度
• 收集的个人信息:无额外个人信息收集
5. expo-notifications
• 提供方Expo650 Industries, Inc.
• 使用目的:在用户同意自启动后,恢复通知服务
• 收集的个人信息:设备推送令牌
6. expo-callkit-telecom
• 提供方Expo650 Industries, Inc.
• 使用目的:通话功能相关服务
• 收集的个人信息:无额外个人信息收集
如您后续接入其他第三方SDK如微信登录、分享等功能我们将在本章节更新相关说明并告知您对应SDK收集的信息类型和用途。更新后的SDK目录将在应用内公布请以最新版本为准。`,
},
{
title: '八、应用自启动与关联启动说明',
content: `8.1 自启动/关联启动的目的与场景
为了及时向您推送消息通知,本应用可能需要在以下场景进行自启动或关联启动:
• 设备开机完成后:恢复后台消息推送服务,确保您能及时收到新消息提醒
• 应用更新后:恢复后台任务调度,保证消息同步功能正常运作
• 系统重启后:恢复通知服务,确保推送通道可用
• 关联启动场景:当系统或其他应用触发相关事件时,为保证推送服务连续性而进行关联启动
8.2 用户同意机制
• 自启动/关联启动功能仅在您明确同意后才启用
• 首次使用时,我们会在"通知设置"中向您说明自启动的目的、场景、规则及必要性,并征得您的同意
• 您可随时在"设置-通知设置-后台同步模式"中更改选择:
- 静默模式:不自启动,仅在使用应用时接收消息
- 后台模式同意自启动系统每15分钟检查一次新消息
- 实时模式:同意自启动,通知栏常驻保活,即时同步消息
8.3 关闭自启动的影响
• 选择静默模式后,应用不会自启动
• 您仅在打开应用时才能接收消息
• 此模式最省电,但可能错过实时消息
• 关闭自启动不会影响应用内的其他功能使用
8.4 我们承诺
• 自启动行为仅用于消息推送服务,不会用于收集额外个人信息
• 自启动行为不会用于广告推送或其他商业目的
• 我们仅在用户同意的范围内使用自启动功能`,
},
{
title: '九、隐私政策的更新',
content: `9.1 我们可能会不时更新本隐私政策。更新后的隐私政策将在应用内公布,并标注更新日期。
9.2 对于重大变更,我们会在变更生效前通过应用内通知、弹窗等方式告知您。
9.3 如您不同意变更后的内容,应立即停止使用本服务。如您继续使用本服务,即视为您已阅读并同意受变更后的隐私政策约束。`,
},
{
title: '十、联系我们',
content: `如果您对本隐私政策有任何疑问、意见或建议,或者您希望行使您的权利,请通过以下方式与我们联系:
• 邮箱system@qczlit.cn
• 公司:青春之旅电子信息科技(威海)有限公司
• 地址:山东省威海市环翠区哈尔滨工业大学(威海)
我们将在收到您的请求后的15个工作日内予以回复。对于复杂的请求我们可能会延长回复期限并及时告知您延长的原因和预计回复时间。`,
},
];
function createPrivacyStyles(colors: AppColors) {
return StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
scrollContent: {
paddingHorizontal: 28,
paddingTop: 24,
},
// 内容区域
content: {
maxWidth: CONTENT_MAX_WIDTH,
alignSelf: 'center',
width: '100%',
},
// 更新日期
lastUpdated: {
fontSize: 13,
color: colors.text.hint,
marginBottom: 20,
},
// 重点提示框
highlightBox: {
backgroundColor: '#FFF5F0',
borderRadius: 12,
padding: 16,
marginBottom: 20,
borderLeftWidth: 4,
borderLeftColor: THEME_COLORS.primary,
},
highlightTitle: {
fontSize: 15,
fontWeight: '600',
color: THEME_COLORS.primary,
marginBottom: 8,
},
highlightText: {
fontSize: 14,
lineHeight: 22,
color: colors.text.secondary,
},
// 隐私政策内容卡片
privacyCard: {
backgroundColor: '#F5F5F7',
borderRadius: 16,
padding: 20,
marginBottom: 24,
},
section: {
marginBottom: 24,
},
sectionLast: {
marginBottom: 0,
},
sectionTitle: {
fontSize: 16,
fontWeight: '600',
color: THEME_COLORS.primary,
marginBottom: 12,
},
sectionContent: {
fontSize: 14,
lineHeight: 24,
color: colors.text.primary,
},
// 底部版权
footer: {
alignItems: 'center',
},
footerText: {
fontSize: 13,
color: colors.text.hint,
textAlign: 'center',
marginBottom: 4,
},
});
}
export const PrivacyPolicyScreen: React.FC = () => {
const colors = useAppColors();
const styles = useMemo(() => createPrivacyStyles(colors), [colors]);
const insets = useSafeAreaInsets();
const router = useRouter();
const { isMobile } = useResponsive();
const responsivePadding = useResponsiveSpacing({ xs: 20, sm: 24, md: 28, lg: 32, xl: 40 });
// 底部间距,避免被 TabBar 遮挡
const scrollBottomInset = isMobile ? 64 + 24 + insets.bottom + spacing.md : spacing.lg;
return (
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
<StatusBar style="auto" />
<SimpleHeader title="隐私政策" onBack={() => router.back()} />
<ScrollView
contentContainerStyle={[styles.scrollContent, { paddingHorizontal: responsivePadding, paddingBottom: scrollBottomInset }]}
showsVerticalScrollIndicator={false}
>
<View style={styles.content}>
{/* 更新日期 */}
<Text style={styles.lastUpdated}>{LAST_UPDATED}</Text>
{/* 重点提示 */}
<View style={styles.highlightBox}>
<Text style={styles.highlightTitle}></Text>
<Text style={styles.highlightText}>
</Text>
</View>
{/* 隐私政策内容 */}
<View style={styles.privacyCard}>
{PRIVACY_SECTIONS.map((section, index) => (
<View key={index} style={[styles.section, index === PRIVACY_SECTIONS.length - 1 && styles.sectionLast]}>
<Text style={styles.sectionTitle}>{section.title}</Text>
<Text style={styles.sectionContent}>{section.content}</Text>
</View>
))}
</View>
{/* 底部版权 */}
<View style={styles.footer}>
<Text style={styles.footerText}>© 2026 </Text>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
};
export default PrivacyPolicyScreen;