摘要:打卡签到、骑手轨迹、外勤巡检、物流追踪------几乎所有需要"知道用户在哪"的App都要接定位SDK。但Android、iOS、鸿蒙三端的定位接入方式差异不小:权限模型不同、初始化流程不同、前后台定位策略不同、耗电表现也不同。
一、先回答最核心的问题
定位SDK做什么? 获取设备当前的经纬度坐标,是所有地图能力中最基础的一个------有了坐标,才能做逆地理编码(坐标转地址)、路径规划(算距离)、轨迹记录等后续操作。
和地图SDK的区别? 定位SDK只取坐标,不渲染地图画面。如果你的App只需要"知道用户在哪儿"而不需要"展示一张地图",只需要接定位SDK,不需要接地图SDK。
三端差异大吗? 大。Android用系统LocationManager或厂商定位服务,iOS用CoreLocation,鸿蒙用鸿蒙Location Kit------三端的权限申请方式、后台定位策略、耗电优化手段都不同。
二、三端接入对比
在写代码之前,先了解三端的关键差异,避免用同一套思路硬搬:
| 对比维度 | Android | iOS | 鸿蒙(HarmonyOS) |
|---|---|---|---|
| 定位API | LocationManager / 厂商服务 | CoreLocation | Location Kit |
| 权限申请 | 运行时权限(ACCESS_FINE_LOCATION等) | Info.plist配置 + 运行时弹窗 | ability配置 + 运行时弹窗 |
| 后台定位 | 需额外声明FOREGROUND_SERVICE | 需开启Background Modes | 需声明backgroundMode |
| 精度选项 | 高精度/GPS/省电/仅设备 | 最佳精度/十米/百米/三公里 | 高精度/低功耗 |
| 坐标系 | WGS84(原始)/ GCJ02(国测局偏移) | WGS84 | WGS84 / GCJ02 |
| 耗电等级 | 中等(GPS持续开启时较高) | 较低(系统级优化) | 较低 |
| 竞品覆盖 | 高德/百度/腾讯/丰图均有 | 高德/百度/腾讯/丰图均有 | 高德/百度有,丰图/腾讯覆盖待确认 |
鸿蒙的差异化:目前鸿蒙原生定位SDK的第三方覆盖度不如Android/iOS成熟。如果你的App需要适配鸿蒙,选型时要确认目标图商是否已发布鸿蒙原生版本。
三、Android端接入要点
3.1 权限配置
xml
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 后台定位需要 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
运行时权限申请(Android 6.0+):
java
// 检查并申请定位权限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_REQUEST_CODE);
}
3.2 初始化与定位请求
java
// 获取LocationManager
LocationManager locationManager =
(LocationManager) getSystemService(LOCATION_SERVICE);
// 创建定位请求
LocationRequest request = new LocationRequest();
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setInterval(5000); // 最小更新间隔5秒
request.setFastestInterval(1000); // 最快更新间隔1秒
// 发起定位
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
request,
locationCallback,
Looper.getMainLooper()
);
3.3 前后台定位策略
| 场景 | 前台定位 | 后台定位 |
|---|---|---|
| 打卡签到 | ✅ 只需前台 | ❌ 不需要 |
| 骑手轨迹 | ✅ 前台持续 | ✅ 后台持续(需FOREGROUND_SERVICE) |
| 外勤巡检 | ✅ 定时更新 | ❌ 不需要 |
| 物流追踪 | ✅ 前台持续 | ✅ 后台持续 |
后台定位耗电警告:后台持续定位会显著增加耗电。建议:
- 降低更新频率(如30秒一次而非5秒一次)
- 使用地理围栏(Geofence)代替持续定位------只在进出特定区域时触发
- Android 12+要求在前台通知中显示定位中状态
四、iOS端接入要点
4.1 权限配置
xml
<!-- Info.plist -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>用于获取您的位置以展示附近门店</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>用于后台持续记录您的配送轨迹</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
4.2 初始化与定位请求
swift
import CoreLocation
class LocationManager: NSObject, CLLocationManagerDelegate {
let manager = CLLocationManager()
func startLocation() {
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.distanceFilter = 10 // 移动10米以上才更新
// 前台定位
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let lat = location.coordinate.latitude
let lng = location.coordinate.longitude
// 处理坐标
}
}
4.3 iOS特有的坑
坑:坐标系问题。iOS的CoreLocation返回WGS84坐标,但国内地图显示需要GCJ02坐标(国测局偏移)。如果你使用丰图/高德/腾讯的SDK,通常会自动处理偏移;但如果自己取原始坐标再渲染到地图上,需要手动做坐标转换。
坑:后台定位审核。苹果对后台定位审核严格,App必须在Info.plist中明确说明后台定位的用途,审核人员会检查是否合理。"为了记录用户轨迹"这种笼统描述可能被拒。
五、鸿蒙端接入要点
5.1 权限配置
json
// module.json5
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:location_reason",
"usedScene": { "when": "inuse" }
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:location_reason",
"usedScene": { "when": "inuse" }
}
]
}
}
5.2 定位请求
typescript
import { location } from '@kit.LocationKit';
// 创建定位请求
let request: location.LocationRequest = {
priority: location.LocationRequestPriority.ACCURACY,
scenario: location.LocationRequestScenario.NAVIGATION,
updateInterval: 5000
};
// 发起定位
location.on('locationChange', request, (loc: location.Location) => {
console.log(`纬度: ${loc.latitude}, 经度: ${loc.longitude}`);
});
说明:鸿蒙Location Kit的API细节(类名、参数名)可能随HarmonyOS版本更新,以华为开发者文档最新版为准。
5.3 鸿蒙注意事项
- 权限分级:鸿蒙将定位权限分为精确位置(LOCATION)和粗略位置(APPROXIMATELY_LOCATION),需要分别申请
- 场景参数:鸿蒙定位有scenario参数(出行/导航/定位等),不同场景的精度和耗电不同
- 适配成熟度:鸿蒙生态仍在发展中,部分第三方SDK的鸿蒙版本功能可能不如Android/iOS完善,选型前务必确认
六、三端统一接入策略
如果你的App需要同时支持三端,建议以下策略:
6.1 抽象层设计
App业务层
↓
定位服务抽象层(统一接口)
↓
├── Android定位实现
├── iOS定位实现
└── 鸿蒙定位实现
定义统一的定位服务接口,三端各自实现,业务层不关心底层差异:
typescript
// 统一接口定义
interface ILocationService {
startLocation(callback: LocationCallback): void;
stopLocation(): void;
getLastLocation(): Location | null;
}
interface Location {
latitude: number;
longitude: number;
accuracy: number;
timestamp: number;
}
6.2 权限申请时机
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 首次打开App时申请 | 用户一打开就弹权限 | 导航、运动类(用户有预期) |
| 使用功能时申请 | 点击"签到"时才弹权限 | 工具类App(体验更好) |
| 分步申请 | 先申请粗略位置,需要时再申请精确位置 | 对精度要求渐进的场景 |
建议:大多数业务场景适合"使用功能时申请"------用户点击"打卡"按钮时弹出定位权限,用户清楚为什么需要授权,通过率更高。
6.3 耗电优化清单
- 降低更新频率:非导航场景不需要秒级更新,5-30秒足够
- 使用地理围栏:只进/出特定区域时触发,替代持续定位
- 前后台切换:App退到后台时降低频率或暂停定位
- 精度按需:不需要高精度时用低功耗模式(十米级/百米级)
- 及时停止:不需要定位时立刻停止,避免SDK持续占用GPS
定位SDK和所有其他接口一样,企业商用即需购买商业授权,与调用量无关。
- 丰图定位SDK没有免费体验额度,注册后直接按量计费或购买商业授权
- 纯定位App(不渲染地图)上架安卓商店时不卡测绘资质,但图商协议层商用必须授权
- 只要合规证书+用量小 → 项目版2万/年;全量使用 → 基础版5万/年
这部分不展开,详见此前的授权系列文章。
最后讲讲踩过的坑,少走弯路。
坑1:"Android和iOS用同一套权限逻辑"
三端权限模型完全不同。Android是运行时权限+后台定位需额外声明;iOS是Info.plist配置+审核严格;鸿蒙是ability配置+权限分级。不能简单复制粘贴,必须按各端规范处理。
坑2:"后台定位不额外声明也没事"
Android 10+和iOS 13+都要求后台定位必须明确声明。不声明就使用后台定位,要么系统直接杀掉定位服务,要么App被应用商店下架。
坑3:"鸿蒙版直接用Android代码改"
鸿蒙虽然兼容部分Android API,但Location Kit是鸿蒙自己的定位框架,API名称、参数结构、权限模型都与Android不同。直接用Android代码改会出运行时错误。
坑4:"定位精度越高越好"
不一定。GPS高精度定位耗电是低功耗模式的5-10倍。如果你的场景只需要知道用户在哪个城市(不需要精确到街道),用低功耗模式就够了。
坑5:"坐标系不用管"
如果你只用一个平台的服务(如全程用丰图),坐标系通常自动处理。但如果混用多个平台(如用iOS原生定位+高德地图渲染),WGS84和GCJ02之间的偏移会导致位置偏差几百米------这个坑很多团队踩过。
定位SDK接入的核心不是"调一个API获取坐标",而是三件事:
- 权限处理:三端各有规范,必须分别适配
- 前后台策略:前台定位vs后台持续定位,耗电差异巨大
- 坐标系:混用多平台时,坐标偏移是最常见的坑
选型建议:
- Android/iOS两端 → 高德/百度/腾讯/丰图均有成熟SDK
- 鸿蒙适配 → 确认目标图商是否已发布鸿蒙原生版本
- 纯定位(不渲染地图)→ 丰图定位SDK+项目版2万证书是合规方案