应用在首次打开或运行中,在用户未主动点击权限对应的相关功能或服务时,提前向用户弹窗申请开启【读取全部日程】权限,不符合相关法律法规要求。该问题已被修复。

Signed-off-by: laoyang <laoyang@example.com>
This commit is contained in:
laoyang
2026-09-16 20:54:41 +08:00
parent 76d82886e4
commit 353473127a
8 changed files with 163 additions and 71 deletions
+7 -3
View File
@@ -365,14 +365,18 @@ export class AppSettings {
}
}
/** 是否混合显示系统日历日程(默认开) */
/**
* 是否混合显示系统日历日程。
* ⚠️ 默认**关闭**:读取系统日历需要"读取全部日程"敏感权限,按《审核指南》7.17
* 只能在用户主动打开该开关时才申请,因此默认值必须与实际授权状态一致(无授权 = 关)。
*/
static async getShowSystemCalendar(context: common.Context): Promise<boolean> {
try {
const store: preferences.Preferences =
await preferences.getPreferences(context, AppSettings.STORE);
return await store.get(AppSettings.KEY_SHOW_SYSTEM, true) as boolean;
return await store.get(AppSettings.KEY_SHOW_SYSTEM, false) as boolean;
} catch (err) {
return true;
return false;
}
}
@@ -1,6 +1,6 @@
// entry/src/main/ets/common/CalendarDataService.ets
// 合并数据源:本地库(DAV 同步 + 本机事件) + 系统日历(只读展示)
import { common, abilityAccessCtrl, Permissions } from '@kit.AbilityKit';
import { common, abilityAccessCtrl, bundleManager, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { calendarManager } from '@kit.CalendarKit';
import { AccountStore, CalSource, BookPalette, LOCAL_CAL_KEY, DavAccount } from './AccountStore';
@@ -29,15 +29,52 @@ export class DisplayEvent {
}
export class CalendarDataService {
/** 申请读取全部日历权限(混合展示系统日历需要 */
static async ensureSystemCalendarPermission(context: common.UIAbilityContext): Promise<boolean> {
/** 本功能依赖的日历权限:读取本应用日历 + 读取全部日历(即"读取全部日程" */
private static readonly CALENDAR_PERMISSIONS: Permissions[] = [
'ohos.permission.READ_CALENDAR',
'ohos.permission.READ_WHOLE_CALENDAR'
];
/**
* 是否已获得"读取全部日程"权限。
* **只检查、绝不弹窗** —— 供界面判断状态、决定是否需要引导用户主动授权。
* 注意:checkAccessToken 只反映本应用授权状态,不会触发任何系统弹窗。
*/
static async hasSystemCalendarPermission(): Promise<boolean> {
try {
const atManager = abilityAccessCtrl.createAtManager();
const permissions: Permissions[] = [
'ohos.permission.READ_CALENDAR',
'ohos.permission.READ_WHOLE_CALENDAR'
];
const result = await atManager.requestPermissionsFromUser(context, permissions);
const info = bundleManager.getBundleInfoForSelfSync(
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
const tokenId: number = info.appInfo.accessTokenId;
for (const p of CalendarDataService.CALENDAR_PERMISSIONS) {
const status = await atManager.checkAccessToken(tokenId, p);
if (status !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
return false;
}
}
return true;
} catch (err) {
return false;
}
}
/**
* 申请"读取全部日程"权限(READ_CALENDAR + READ_WHOLE_CALENDAR)。
*
* ⚠️ 合规约束(《审核指南》7.17):**只能在用户主动点击使用对应功能时调用**,
* 例如在设置页打开"混合显示系统日历"开关、把系统日历模式切到"备份到 CalDAV 日历本"。
* 严禁在 App 启动 / 首次打开 / 未同意隐私政策等用户未主动操作的时机调用。
*
* 已授权时直接返回 true,不会再弹窗(先 checkAccessToken,避免多余弹窗)。
*/
static async requestSystemCalendarPermission(context: common.UIAbilityContext): Promise<boolean> {
if (await CalendarDataService.hasSystemCalendarPermission()) {
return true;
}
try {
const atManager = abilityAccessCtrl.createAtManager();
const result = await atManager.requestPermissionsFromUser(
context, CalendarDataService.CALENDAR_PERMISSIONS);
for (const r of result.authResults) {
if (r !== 0) {
return false;
+2 -2
View File
@@ -28,8 +28,8 @@ export struct TipsPanel {
{
icon: $r('app.media.tip_calendar'),
title: '系统日历,也能一起管',
desc: '手机系统日历可与 CalDAV 日历混合显示在同一时间轴;还能把系统日历本通过 CalDAV 同步备份,' +
'一处编辑、处处更新。'
desc: '手机系统日历可与 CalDAV 日历混合显示在同一时间轴,也能把系统日历本通过 CalDAV 同步备份,' +
'一处编辑、处处更新。到「设置 → 混合显示系统日历」开启并授权即可。'
},
{
icon: $r('app.media.tip_mute'),