| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- import { type LocationSource, type LocationSourceCallbacks } from './locationSource'
- function hasLocationPermission(settings: WechatMiniprogram.AuthSetting): boolean {
- const authSettings = settings as Record<string, boolean | undefined>
- return !!authSettings['scope.userLocation']
- }
- function hasBackgroundLocationPermission(settings: WechatMiniprogram.AuthSetting): boolean {
- const authSettings = settings as Record<string, boolean | undefined>
- return !!authSettings['scope.userLocationBackground']
- }
- export class RealLocationSource implements LocationSource {
- callbacks: LocationSourceCallbacks
- active: boolean
- boundLocationHandler: ((result: WechatMiniprogram.OnLocationChangeCallbackResult) => void) | null
- constructor(callbacks: LocationSourceCallbacks) {
- this.callbacks = callbacks
- this.active = false
- this.boundLocationHandler = null
- }
- get mode(): 'real' {
- return 'real'
- }
- start(): void {
- if (this.active) {
- this.callbacks.onStatus('后台持续定位进行中')
- return
- }
- wx.getSetting({
- success: (result) => {
- const settings = result.authSetting || {}
- if (hasBackgroundLocationPermission(settings)) {
- this.startBackgroundLocation()
- return
- }
- if (hasLocationPermission(settings)) {
- this.requestBackgroundPermissionInSettings()
- return
- }
- wx.authorize({
- scope: 'scope.userLocation',
- success: () => {
- this.requestBackgroundPermissionInSettings()
- },
- fail: () => {
- this.requestBackgroundPermissionInSettings()
- },
- })
- },
- fail: (error) => {
- const message = error && error.errMsg ? error.errMsg : 'getSetting 失败'
- this.callbacks.onError(`GPS授权检查失败: ${message}`)
- },
- })
- }
- stop(): void {
- if (!this.active) {
- this.callbacks.onStatus('后台持续定位未启动')
- return
- }
- if (typeof wx.offLocationChange === 'function' && this.boundLocationHandler) {
- wx.offLocationChange(this.boundLocationHandler)
- }
- this.boundLocationHandler = null
- wx.stopLocationUpdate({
- complete: () => {
- this.active = false
- this.callbacks.onStatus('后台持续定位已停止')
- },
- })
- }
- destroy(): void {
- if (typeof wx.offLocationChange === 'function' && this.boundLocationHandler) {
- wx.offLocationChange(this.boundLocationHandler)
- }
- this.boundLocationHandler = null
- if (this.active) {
- wx.stopLocationUpdate({ complete: () => {} })
- this.active = false
- }
- }
- requestBackgroundPermissionInSettings(): void {
- this.callbacks.onStatus('请在授权面板开启后台定位')
- wx.openSetting({
- success: (result) => {
- const settings = result.authSetting || {}
- if (hasBackgroundLocationPermission(settings)) {
- this.startBackgroundLocation()
- return
- }
- this.callbacks.onError('GPS启动失败: 未授予后台定位权限')
- },
- fail: (error) => {
- const message = error && error.errMsg ? error.errMsg : 'openSetting 失败'
- this.callbacks.onError(`GPS启动失败: ${message}`)
- },
- })
- }
- startBackgroundLocation(): void {
- wx.startLocationUpdateBackground({
- type: 'wgs84',
- success: () => {
- this.bindLocationListener()
- this.active = true
- this.callbacks.onStatus('后台持续定位已启动')
- },
- fail: (error) => {
- const message = error && error.errMsg ? error.errMsg : 'startLocationUpdateBackground 失败'
- this.callbacks.onError(`GPS启动失败: ${message}`)
- },
- })
- }
- bindLocationListener(): void {
- if (this.boundLocationHandler) {
- return
- }
- this.boundLocationHandler = (result) => {
- this.callbacks.onLocation({
- latitude: result.latitude,
- longitude: result.longitude,
- accuracy: result.accuracy,
- speed: result.speed,
- timestamp: Date.now(),
- sourceMode: 'real',
- })
- }
- wx.onLocationChange(this.boundLocationHandler)
- }
- }
|