UNPKG

react-native-anavi

Version:

react native amap navigation component, Android + iOS

279 lines (254 loc) 7.24 kB
import { NativeModules, NativeEventEmitter, AppState, AppStateStatus } from 'react-native'; const { AMapLocation } = NativeModules; const eventEmitter = new NativeEventEmitter(AMapLocation); export class ALocationProxy { listener: ALocationListner; constructor(listener: ALocationListner) { this.listener = listener; } public stop(): void { const index = listeners.indexOf(this.listener); if (index > -1) { listeners.splice(index, 1); } } } class ALocationListner { once: boolean; background: boolean; callback: (location: ALocation) => void; callbackTarget: any; public constructor(once: boolean, backgroud: boolean, callback: (location: ALocation) => void) { this.once = once; this.background = backgroud; this.callback = callback; } public apply(location: ALocation): void { if (this.callback) { this.callback(location); } } } interface LocationError { readonly code: number; readonly info: string; readonly details: string; } interface LocationQualityReport { /** * 获取提示语义,状态良好时,返回的是内容为空 根据当前的质量报告,给出相应的建议 */ readonly adviseMessage: string; /** * 获取当前的卫星数, 只有在非低功耗模式下此值才有效 */ readonly gpsSatellites: number; /** * 获取卫星状态信息,只有在非低功耗模式下此值才有效 */ readonly gpsStatus: number; /** * 获取网络定位时的网络耗时 单位:毫秒 */ readonly netUseTime: number; /** * 获取网络连接类型(2G、3G、4G、WIFI) */ readonly networkType: string; /** * 是否安装了高危位置模拟软件 首次定位可能没有结果 */ readonly isInstalledHighDangerMockApp: boolean; /** * wifi开关是否打开 如果wifi关闭建议打开wifi开关,提高定位质量 */ readonly isWifiAble: boolean; } export interface ALocation { /** * */ readonly error: LocationError; /** * 获取定位结果来源 */ readonly type: number; /** * 获取纬度 */ readonly latitude: number; /** * 获取纬度 */ readonly longitude: number; /** * 获取定位精度 */ readonly accuracy: number; /** * 获取定位提供者 */ readonly provider: string; /** * 获取速度 */ readonly speed: number; /** * 获取角度 */ readonly bearing: number; /** * 获取当前可用卫星数量, 仅在卫星定位时有效 */ readonly satellites: number; /** * 获取国家名称 */ readonly country: string; /** * 获取城市名称 */ readonly city: string; /** * 获取城市编码 */ readonly cityCode: string; /** * 获取区域名称 */ readonly district: string; /** * 获取区域编码 */ readonly districtCode: string; /** * 获取地址 */ readonly address: string; /** * 获取兴趣点 */ readonly poiName: string; /** * 获取定位时间 */ readonly time: number; /** * 获取定位质量报告 */ readonly quality: LocationQualityReport; } export type ALocationCallback = (location: ALocation) => void; export class ALocationClientOptions { httpTimeout?: number; interval?: number; cacheEnabled?: boolean; mode?: 'Battery_Saving' | 'Device_Sensors' | 'Hight_Accuracy'; protocol?: 'HTTP' | 'HTTPS'; mockEnabled?: boolean; needAddress?: boolean; sensorEnable?: boolean; wifiScan?: boolean; } /** 当前是否在后台运行 */ var isBackground: boolean = false; /** 当前是否在后台定位 */ var isBackgroundLocation: boolean = false; var listeners: ALocationListner[] = []; var locationOptions: ALocationClientOptions = {}; /** 是否已经开始定位*/ var isStarted = false; const start = () => { if (isStarted) { return; } isStarted = true; AMapLocation.start(locationOptions); }; const stop = () => { isStarted = false; AMapLocation.stop(); }; const appStateChangeListner = (status: AppStateStatus) => { isBackground = status !== 'active'; console.log(`------>AMapLocation: The application's status is ${status}`); if (!isBackground) { console.log(`------>AMapLocation: enter forground disable background location`); AMapLocation.enabledBackground(false); } else if (isBackgroundLocation) { console.log(`------>AMapLocation: enter background, enabled background location`); AMapLocation.enabledBackground(true); } }; const amapLocationListner = (location: ALocation) => { for (const listener of listeners) { if (!listener.background && isBackground) { continue; } listener.apply(location); } // 删除once的listener listeners = listeners.filter((listener) => !listener.once); // 没有后台监听 if (isBackgroundLocation && !listeners.find((l) => l.background)) { isBackgroundLocation = false; console.log(`------>AMapLoaction: There has't background location callback, will stop backgroud location`); } // 已经没有位置监听,自动关闭位置服务 if (!listeners.length) { console.log(`------>AMapLoaction: There has't location callback, will auto stop the location service`); stop(); } }; /** * 高德定位服务 */ export class ALocationClient { private constructor() { AppState.addEventListener('change', appStateChangeListner); eventEmitter.addListener('amap_location', amapLocationListner); } private static instance: ALocationClient; /** * 获取ALoaction的单例 */ public static getInstace(): ALocationClient { if (!ALocationClient.instance) { ALocationClient.instance = new ALocationClient(); } return ALocationClient.instance; } /** * 当前是否已启用后台定位 */ public get isBackground(): boolean { return isBackgroundLocation; } /** * 获取或设置定位选项 */ public set options(options: ALocationClientOptions) { locationOptions = options; } public get options(): ALocationClientOptions { return locationOptions; } public location(callback: ALocationCallback, background: boolean = false): ALocationProxy { this.checkIsAutoStop(); if (background && !isBackgroundLocation) { isBackgroundLocation = true; } const listener: ALocationListner = new ALocationListner(false, background, callback); listeners.push(listener); return new ALocationProxy(listener); } public locationOnce(callback: ALocationCallback): void { this.checkIsAutoStop(); listeners.push(new ALocationListner(true, false, callback)); } private checkIsAutoStop(): void { if (!isStarted) { start(); } } }