移除定位权限:地理编码不需要 LOCATION(AGC 隐私标签审核)

AGC 以「未如实填写隐私标签」退回本次提审。核查后发现根因是
申请了两个用不到的敏感权限,与隐私标签无法自洽。

依据(本机 SDK API 26,targetSdk 26.0.0):
- @ohos.geoLocationManager.d.ts 中 getCurrentLocation / getLastLocation /
  on('locationChange') 均有 @permission APPROXIMATELY_LOCATION;
- 而 getAddressesFromLocationName(地址→坐标)与 getAddressesFromLocation
  (坐标→地址)**没有 @permission**,只有 @syscap ...Location.Geocoder。
- 本应用从不调用 getCurrentLocation,本就不读设备实时位置,只在「一键导航」
  时把用户填写的地址换算为坐标。

改动:
- module.json5:删除 LOCATION、APPROXIMATELY_LOCATION(现仅 5 个权限)
- Index.ets:删除 ensureLocationPermission(),openInAmap() 直接调
  geocodeAddress();同步清掉随之无用的 abilityAccessCtrl / bundleManager 导入
- string.json:删除 perm_location、perm_location_approx
- AppSettings.ets:更新权限一致性注释,警示后续勿再照旧文档写错政策

验证:assembleHap BUILD SUCCESSFUL;解包 hap 与 .app 内 module.json 均只剩
5 个权限、LOCATION 零命中;真机 hdc install -r 成功,aa start 无崩溃。

注意:华为旧文档 @ohos.geolocation(API 9 已废弃)仍写"需要权限 LOCATION",
那是老接口,勿据此判断——应以本机 .d.ts 为准。
This commit is contained in:
2026-10-28 23:14:08 +08:00
parent b7bc4b5403
commit d993dd3d4b
4 changed files with 13 additions and 63 deletions
+7 -2
View File
@@ -45,8 +45,13 @@ export class AppSettings {
// 在线文档网址(自托管,AGC 上架的"隐私政策网址"填 PRIVACY_URL)。 // 在线文档网址(自托管,AGC 上架的"隐私政策网址"填 PRIVACY_URL)。
// ⚠️ 隐私政策与用户协议必须与安装包实际申请的 user_grant 权限保持一致: // ⚠️ 隐私政策与用户协议必须与安装包实际申请的 user_grant 权限保持一致:
// 应用仅申请 READ_CALENDAR / READ_WHOLE_CALENDAR / LOCATION / APPROXIMATELY_LOCATION(均前台), // 应用仅申请 READ_CALENDAR / READ_WHOLE_CALENDAR / WRITE_CALENDAR(均前台)。
// 文档中不得出现"在后台获取位置"(LOCATION_IN_BACKGROUND)与"添加/修改/删除日历活动"(WRITE_CALENDAR)。 // 文档中不得出现"在后台获取位置"(LOCATION_IN_BACKGROUND)。
// ⚠️ 0.1.0 起已**移除 LOCATION / APPROXIMATELY_LOCATION**:实测本 SDK(API 26)的
// `geoLocationManager.getAddressesFromLocationName`(地址→坐标)无 @permission 标注,
// 地理编码不需要定位权限;且应用从不调用 getCurrentLocation,本就不读实时位置。
// ⇒ 隐私政策/隐私标签里都**不得**再声称"读取设备精确位置或大致位置"。
// ⇒ 若将来真要用实时定位,必须同时改 module.json5、本注释、upa.html 与 AGC 隐私标签。
// 四份文档均在设置页通过内置浏览器(DocViewer)打开,内容在线更新、无需重新发版。 // 四份文档均在设置页通过内置浏览器(DocViewer)打开,内容在线更新、无需重新发版。
/** 隐私政策网址 */ /** 隐私政策网址 */
static readonly PRIVACY_URL: string = 'https://synccalendar.yangyq.net/upa.html'; static readonly PRIVACY_URL: string = 'https://synccalendar.yangyq.net/upa.html';
+6 -33
View File
@@ -2,7 +2,7 @@
// 同步日历主界面:月视图(左右滑动翻月)/ 周视图 / 日视图 / 日程列表 // 同步日历主界面:月视图(左右滑动翻月)/ 周视图 / 日视图 / 日程列表
// 混合展示 DAV 与系统日历;每分钟自动同步;可"回到今天" // 混合展示 DAV 与系统日历;每分钟自动同步;可"回到今天"
import { curves, display, router, window } from '@kit.ArkUI'; import { curves, display, router, window } from '@kit.ArkUI';
import { common, abilityAccessCtrl, bundleManager } from '@kit.AbilityKit'; import { common } from '@kit.AbilityKit';
import { geoLocationManager } from '@kit.LocationKit'; import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError, pasteboard } from '@kit.BasicServicesKit'; import { BusinessError, pasteboard } from '@kit.BasicServicesKit';
import { DavAccount, AccountStore, CalSource, TYPE_CALDAV } from '../common/AccountStore'; import { DavAccount, AccountStore, CalSource, TYPE_CALDAV } from '../common/AccountStore';
@@ -756,11 +756,10 @@ struct Index {
} }
const ctx = context as common.UIAbilityContext; const ctx = context as common.UIAbilityContext;
const enc: string = encodeURIComponent(address); const enc: string = encodeURIComponent(address);
// 高德鸿蒙深链 dlat/dlon 为必填(dname 仅作名称显示),先地理编码拿坐标 // 高德鸿蒙深链 dlat/dlon 为必填(dname 仅作名称显示),先地理编码拿坐标。
let coords: number[] | null = null; // 地理编码(getAddressesFromLocationName)在本 SDK 上不要求定位权限,
if (await this.ensureLocationPermission()) { // 因此这里既不申请、也不使用定位权限 —— 应用自始至终不读取设备实时位置。
coords = await this.geocodeAddress(address); const coords: number[] | null = await this.geocodeAddress(address);
}
const base: string = 'amapuri://route/plan/?sourceApplication=SyncCalendar'; const base: string = 'amapuri://route/plan/?sourceApplication=SyncCalendar';
let link: string; let link: string;
if (coords !== null) { if (coords !== null) {
@@ -782,33 +781,7 @@ struct Index {
this.getUIContext().getPromptAction().showToast({ message: '未安装高德地图或无法打开' }); this.getUIContext().getPromptAction().showToast({ message: '未安装高德地图或无法打开' });
} }
/** 确认定位权限(地理编码依赖),未授权时向用户申请一次 */ /** 正向地理编码:地址 → 坐标(系统服务,无需高德 key、无需定位权限) */
private async ensureLocationPermission(): Promise<boolean> {
try {
const atManager = abilityAccessCtrl.createAtManager();
const bundleInfo = bundleManager.getBundleInfoForSelfSync(
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
const tokenId = bundleInfo.appInfo.accessTokenId;
const status = await atManager.checkAccessToken(tokenId, 'ohos.permission.LOCATION');
if (status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
return true;
}
} catch (err) {
// 未授权会走申请流程
}
try {
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
const atManager = abilityAccessCtrl.createAtManager();
// LOCATION 与 APPROXIMATELY_LOCATION 必须一起申请
const result = await atManager.requestPermissionsFromUser(context,
['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION']);
return result.authResults.every((r: number): boolean => r === 0);
} catch (err) {
return false;
}
}
/** 正向地理编码:地址 → 坐标(系统服务,无需高德 key) */
private async geocodeAddress(address: string): Promise<number[] | null> { private async geocodeAddress(address: string): Promise<number[] | null> {
try { try {
if (!geoLocationManager.isGeocoderAvailable()) { if (!geoLocationManager.isGeocoderAvailable()) {
-20
View File
@@ -44,26 +44,6 @@
], ],
"when": "inuse" "when": "inuse"
} }
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:perm_location",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:perm_location_approx",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
} }
], ],
"deliveryWithInstall": true, "deliveryWithInstall": true,
@@ -24,14 +24,6 @@
"name": "perm_read_whole_calendar", "name": "perm_read_whole_calendar",
"value": "读取所有日历账户的日程,用于在日历中统一展示" "value": "读取所有日历账户的日程,用于在日历中统一展示"
}, },
{
"name": "perm_location",
"value": "将日程中的地址转换为坐标,用于发起高德地图导航"
},
{
"name": "perm_location_approx",
"value": "将日程中的地址转换为坐标,用于发起高德地图导航"
},
{ {
"name": "card_ability_desc", "name": "card_ability_desc",
"value": "同步日历服务卡片" "value": "同步日历服务卡片"