移除定位权限:地理编码不需要 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:
@@ -45,8 +45,13 @@ export class AppSettings {
|
||||
|
||||
// 在线文档网址(自托管,AGC 上架的"隐私政策网址"填 PRIVACY_URL)。
|
||||
// ⚠️ 隐私政策与用户协议必须与安装包实际申请的 user_grant 权限保持一致:
|
||||
// 应用仅申请 READ_CALENDAR / READ_WHOLE_CALENDAR / LOCATION / APPROXIMATELY_LOCATION(均前台),
|
||||
// 文档中不得出现"在后台获取位置"(LOCATION_IN_BACKGROUND)与"添加/修改/删除日历活动"(WRITE_CALENDAR)。
|
||||
// 应用仅申请 READ_CALENDAR / READ_WHOLE_CALENDAR / WRITE_CALENDAR(均前台)。
|
||||
// 文档中不得出现"在后台获取位置"(LOCATION_IN_BACKGROUND)。
|
||||
// ⚠️ 0.1.0 起已**移除 LOCATION / APPROXIMATELY_LOCATION**:实测本 SDK(API 26)的
|
||||
// `geoLocationManager.getAddressesFromLocationName`(地址→坐标)无 @permission 标注,
|
||||
// 地理编码不需要定位权限;且应用从不调用 getCurrentLocation,本就不读实时位置。
|
||||
// ⇒ 隐私政策/隐私标签里都**不得**再声称"读取设备精确位置或大致位置"。
|
||||
// ⇒ 若将来真要用实时定位,必须同时改 module.json5、本注释、upa.html 与 AGC 隐私标签。
|
||||
// 四份文档均在设置页通过内置浏览器(DocViewer)打开,内容在线更新、无需重新发版。
|
||||
/** 隐私政策网址 */
|
||||
static readonly PRIVACY_URL: string = 'https://synccalendar.yangyq.net/upa.html';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 同步日历主界面:月视图(左右滑动翻月)/ 周视图 / 日视图 / 日程列表
|
||||
// 混合展示 DAV 与系统日历;每分钟自动同步;可"回到今天"
|
||||
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 { BusinessError, pasteboard } from '@kit.BasicServicesKit';
|
||||
import { DavAccount, AccountStore, CalSource, TYPE_CALDAV } from '../common/AccountStore';
|
||||
@@ -756,11 +756,10 @@ struct Index {
|
||||
}
|
||||
const ctx = context as common.UIAbilityContext;
|
||||
const enc: string = encodeURIComponent(address);
|
||||
// 高德鸿蒙深链 dlat/dlon 为必填(dname 仅作名称显示),先地理编码拿坐标
|
||||
let coords: number[] | null = null;
|
||||
if (await this.ensureLocationPermission()) {
|
||||
coords = await this.geocodeAddress(address);
|
||||
}
|
||||
// 高德鸿蒙深链 dlat/dlon 为必填(dname 仅作名称显示),先地理编码拿坐标。
|
||||
// 地理编码(getAddressesFromLocationName)在本 SDK 上不要求定位权限,
|
||||
// 因此这里既不申请、也不使用定位权限 —— 应用自始至终不读取设备实时位置。
|
||||
const coords: number[] | null = await this.geocodeAddress(address);
|
||||
const base: string = 'amapuri://route/plan/?sourceApplication=SyncCalendar';
|
||||
let link: string;
|
||||
if (coords !== null) {
|
||||
@@ -782,33 +781,7 @@ struct Index {
|
||||
this.getUIContext().getPromptAction().showToast({ message: '未安装高德地图或无法打开' });
|
||||
}
|
||||
|
||||
/** 确认定位权限(地理编码依赖),未授权时向用户申请一次 */
|
||||
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) */
|
||||
/** 正向地理编码:地址 → 坐标(系统服务,无需高德 key、无需定位权限) */
|
||||
private async geocodeAddress(address: string): Promise<number[] | null> {
|
||||
try {
|
||||
if (!geoLocationManager.isGeocoderAvailable()) {
|
||||
|
||||
@@ -44,26 +44,6 @@
|
||||
],
|
||||
"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,
|
||||
|
||||
@@ -24,14 +24,6 @@
|
||||
"name": "perm_read_whole_calendar",
|
||||
"value": "读取所有日历账户的日程,用于在日历中统一展示"
|
||||
},
|
||||
{
|
||||
"name": "perm_location",
|
||||
"value": "将日程中的地址转换为坐标,用于发起高德地图导航"
|
||||
},
|
||||
{
|
||||
"name": "perm_location_approx",
|
||||
"value": "将日程中的地址转换为坐标,用于发起高德地图导航"
|
||||
},
|
||||
{
|
||||
"name": "card_ability_desc",
|
||||
"value": "同步日历服务卡片"
|
||||
|
||||
Reference in New Issue
Block a user