From f4f3504a1c0e1b8680425d09420afb13eb0e7d89 Mon Sep 17 00:00:00 2001 From: yanyilin Date: Mon, 30 Oct 2023 15:43:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E6=BA=90=EF=BC=9Auni.getLocation=20?= =?UTF-8?q?=E7=9A=84=20=E7=B3=BB=E7=BB=9F=E5=AE=9A=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../uni-getLocation-system/changelog.md | 0 .../uni-getLocation-system/package.json | 93 ++++++++++ uni_modules/uni-getLocation-system/readme.md | 6 + .../utssdk/app-android/AndroidManifest.xml | 11 ++ .../utssdk/app-android/config.json | 3 + .../utssdk/app-android/index.uts | 174 ++++++++++++++++++ .../utssdk/app-ios/index.uts | 0 .../utssdk/interface.uts | 125 +++++++++++++ 8 files changed, 412 insertions(+) create mode 100644 uni_modules/uni-getLocation-system/changelog.md create mode 100644 uni_modules/uni-getLocation-system/package.json create mode 100644 uni_modules/uni-getLocation-system/readme.md create mode 100644 uni_modules/uni-getLocation-system/utssdk/app-android/AndroidManifest.xml create mode 100644 uni_modules/uni-getLocation-system/utssdk/app-android/config.json create mode 100644 uni_modules/uni-getLocation-system/utssdk/app-android/index.uts create mode 100644 uni_modules/uni-getLocation-system/utssdk/app-ios/index.uts create mode 100644 uni_modules/uni-getLocation-system/utssdk/interface.uts diff --git a/uni_modules/uni-getLocation-system/changelog.md b/uni_modules/uni-getLocation-system/changelog.md new file mode 100644 index 0000000..e69de29 diff --git a/uni_modules/uni-getLocation-system/package.json b/uni_modules/uni-getLocation-system/package.json new file mode 100644 index 0000000..4b7713c --- /dev/null +++ b/uni_modules/uni-getLocation-system/package.json @@ -0,0 +1,93 @@ +{ + "id": "uni-getLocation-system", + "displayName": "uni-getLocation-system", + "version": "1.0.0", + "description": "uni-getLocation-system", + "keywords": [ + "uni-getLocation-system" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.6.8" + }, + "dcloudext": { + "type": "uts", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "", + "data": "", + "permissions": "" + }, + "npmurl": "" + }, + "uni_modules": { + "uni-ext-api": { + "uni": { + "getLocation": { + "name": "getLocation", + "app": { + "js": false, + "kotlin": true, + "swift": false + } + } + } + }, + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "u", + "aliyun": "u" + }, + "client": { + "Vue": { + "vue2": "u", + "vue3": "u" + }, + "App": { + "app-android": "u", + "app-ios": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-getLocation-system/readme.md b/uni_modules/uni-getLocation-system/readme.md new file mode 100644 index 0000000..f2f72b3 --- /dev/null +++ b/uni_modules/uni-getLocation-system/readme.md @@ -0,0 +1,6 @@ +# uts-location +### 开发文档 +[UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html) +[UTS API插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html) +[UTS 组件插件](https://uniapp.dcloud.net.cn/plugin/uts-component.html) +[Hello UTS](https://gitcode.net/dcloud/hello-uts) \ No newline at end of file diff --git a/uni_modules/uni-getLocation-system/utssdk/app-android/AndroidManifest.xml b/uni_modules/uni-getLocation-system/utssdk/app-android/AndroidManifest.xml new file mode 100644 index 0000000..711a0ff --- /dev/null +++ b/uni_modules/uni-getLocation-system/utssdk/app-android/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/uni_modules/uni-getLocation-system/utssdk/app-android/config.json b/uni_modules/uni-getLocation-system/utssdk/app-android/config.json new file mode 100644 index 0000000..0c9878e --- /dev/null +++ b/uni_modules/uni-getLocation-system/utssdk/app-android/config.json @@ -0,0 +1,3 @@ +{ + "minSdkVersion": 19 +} diff --git a/uni_modules/uni-getLocation-system/utssdk/app-android/index.uts b/uni_modules/uni-getLocation-system/utssdk/app-android/index.uts new file mode 100644 index 0000000..dde095a --- /dev/null +++ b/uni_modules/uni-getLocation-system/utssdk/app-android/index.uts @@ -0,0 +1,174 @@ +import { GetLocation, GetLocationOptions, GetLocationSuccess,GetLocationFail } from "../interface.uts" +import UTSAndroid from 'io.dcloud.uts.UTSAndroid'; +import Context from 'android.content.Context'; +import LocationManager from 'android.location.LocationManager'; +import Criteria from 'android.location.Criteria'; +import Location from 'android.location.Location'; +import LocationListener from 'android.location.LocationListener'; + + + +/** + * 对外的函数接口 + */ +export const getLocation : GetLocation = function (options : GetLocationOptions) { + + /** + * 准备权限 + */ + let permissionNeed : string[] = utsArrayOf("android.permission.ACCESS_FINE_LOCATION"); + UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight:boolean,_grantedList:string[]) { + if (allRight) { + // 交给目前的location 引擎,真实执行 + getLocationImpl(options) + } + }, function (_doNotAskAgain:boolean,_grantedList:string[]) { + console.log("用户拒绝了部分权限:") + let err = new UniError("uni-getLocation-system",-10,"permission missed."); + options.fail?.(err) + options.complete?.(err) + }) + +} + +/****************************************内部功能实现****************************************************/ +/** + * 全局信息处理 + */ +class Global { + /** + * 默认实现 + */ + static lastLocation : Location | null = null; +} + + +/** + * 封装系统监听回调 + */ +class CustomSystemLocationListener extends LocationListener { + override onLocationChanged(location : Location) : void { + Global.lastLocation = location + } +} + + +/** + * 真实的执行位置定位 + */ +function getLocationImpl(options : GetLocationOptions) { + + /** + * add since 2023-09-14 增加默认值兼容逻辑 + */ + if(options.type == null){ + options.type = 'wgs84' + } + if(options.highAccuracyExpireTime == null){ + options.highAccuracyExpireTime = 3000 + } + + + if(options.type != 'wgs84'){ + // 系统定位只支持wgs84,如果不是则报错 + let err = new UniError("uni-getLocation-system",-1,"system location support wgs84 only."); + options.fail?.(err) + options.complete?.(err) + return + } + + if(options.geocode != null && options.geocode == true){ + // 系统定位不支持逆地理编码 + let err = new UniError("uni-getLocation-system",-2,"system location not support geocode."); + options.fail?.(err) + options.complete?.(err) + return + } + + + + let locationManager = UTSAndroid.getAppContext()!.getSystemService(Context.LOCATION_SERVICE) as LocationManager; + let criteria = new Criteria() + + // 用户明确开启了高度 + if (options.altitude != null && options.altitude == true) { + criteria.setAltitudeRequired(true) + } + // 设置精度 + if (options.isHighAccuracy != null && options.isHighAccuracy == true) { + criteria.setAccuracy(Criteria.ACCURACY_FINE) + } else{ + criteria.setAccuracy(Criteria.ACCURACY_COARSE) + } + + criteria.setPowerRequirement(Criteria.POWER_LOW) + criteria.setSpeedRequired(true) + + /** + * 如果存在gps,那么优先gps,这样才有高度信息 + */ + let providerName:string|null = "gps" + if(!locationManager.getProviders(criteria, true).contains("gps")){ + providerName = locationManager.getBestProvider(criteria, true) + } + + if (providerName == null) { + // 没有找到合法的系统定位能力提供者,错误的逻辑 todo + let err = new UniError("uni-getLocation-system",-3,"Provider is not find,Please ensure that the device location function is turned on"); + options.fail?.(err) + options.complete?.(err) + return; + } + // 兜底的逻辑是上次定位的信息 + Global.lastLocation = locationManager.getLastKnownLocation(providerName) + let systemListener = new CustomSystemLocationListener() + locationManager.requestLocationUpdates(providerName, 2000, 0.0.toFloat(), systemListener) + + + // 默认超时6000ms + let timeoutMill:number = 6000; + /** + * 只有设置超出3000ms 才会认为有效 + * https://uniapp.dcloud.net.cn/api/location/location.html#getlocation + */ + if(options.highAccuracyExpireTime != null && options.highAccuracyExpireTime! >= 3000){ + timeoutMill = options.highAccuracyExpireTime! + } + + let taskId = 0 + let startTimeMill = (new Date()).getTime() + // 不管返回结果如何,延迟2s 返回数据 + taskId = setInterval(function () { + if (Global.lastLocation == null) { + // 没有得到想要的位置,统计错误计数+1 + + let currentTimeMill = (new Date()).getTime() + let diffTimeNum = currentTimeMill - startTimeMill + + if (diffTimeNum > timeoutMill) { + locationManager.removeUpdates(systemListener) + // 超过6s了,返回错误 + clearInterval(taskId) + let err = new UniError("uni-getLocation-system",-4,"location fail: timeout"); + options.fail?.(err) + options.complete?.(err) + } + } else { + locationManager.removeUpdates(systemListener) + clearInterval(taskId) + let ret : GetLocationSuccess = { + latitude: Global.lastLocation!.getLatitude(), + longitude: Global.lastLocation!.getLongitude(), + speed: Global.lastLocation!.getSpeed(), + accuracy: Global.lastLocation!.getAccuracy(), + altitude: Global.lastLocation!.getAltitude(), + verticalAccuracy: 0, + horizontalAccuracy: Global.lastLocation!.getAccuracy(), + address: null + } + options.success?.(ret) + Global.lastLocation = null + } + + }, 2000); +} diff --git a/uni_modules/uni-getLocation-system/utssdk/app-ios/index.uts b/uni_modules/uni-getLocation-system/utssdk/app-ios/index.uts new file mode 100644 index 0000000..e69de29 diff --git a/uni_modules/uni-getLocation-system/utssdk/interface.uts b/uni_modules/uni-getLocation-system/utssdk/interface.uts new file mode 100644 index 0000000..e9b7082 --- /dev/null +++ b/uni_modules/uni-getLocation-system/utssdk/interface.uts @@ -0,0 +1,125 @@ +export interface Uni { + + /** + * @description 获取当前的地理位置、速度 + * @param {GetLocation} option + * @example + * ```typescript + * uni.getLocation({ + * type: 'wgs84', + * success: function (res) { + * console.log('当前位置的经度:' + res.longitude); + * console.log('当前位置的纬度:' + res.latitude); + * } + * }); + * ``` + * @tutorial [](http://uniapp.dcloud.io/api/location/location?id=getlocation) + * @uniPlatform { + * "app": { + * "android": { + * "osVer": "4.4.4", + * "uniVer": "√", + * "unixVer": "3.9.0" + * }, + * "ios": { + * "osVer": "x", + * "uniVer": "x", + * "unixVer": "x" + * } + * } + * } + */ + getLocation(options: GetLocationOptions):void; + +} + + + +export type GetLocation = (options: GetLocationOptions) => void; +export type GetLocationSuccess = { + /** + * 纬度,浮点数,范围为-90~90,负数表示南纬 + * @defaultValue 0 + */ + latitude: number, + /** + * 经度,范围为-180~180,负数表示西经 + * @defaultValue 0 + */ + longitude: number, + /** + * 速度,浮点数,单位m/s + * @defaultValue 0 + */ + speed: number, + /** + * 位置的精确度 + */ + accuracy: number, + /** + * 高度,单位 m + * @defaultValue 0 + */ + altitude: number, + /** + * 垂直精度,单位 m(Android 无法获取,返回 0) + * @defaultValue 0 + */ + verticalAccuracy: number, + /** + * 水平精度,单位 m + * @defaultValue 0 + */ + horizontalAccuracy: number, + /** + * 地址信息 + * @defaultValue null + */ + address: any | null +}; +type GetLocationSuccessCallback = (result: GetLocationSuccess) => void; +type GetLocationFailCallback = (result: UniError) => void; +type GetLocationComplete = any; +type GetLocationCompleteCallback = (result: GetLocationComplete) => void; +export type GetLocationOptions = { + /** + * 默认为 wgs84 返回 gps 坐标,gcj02 返回可用于uni.openLocation的坐标 + * @defaultValue wgs84 + */ + type?: string | null, + /** + * 传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度 + * @type boolean + * @defaultValue false + */ + altitude?: boolean | null, + /** + * 传入 true 会解析地址 + * @type boolean + * @defaultValue false + */ + geocode?: boolean | null, + /** + * 高精度定位超时时间(ms),指定时间内返回最高精度,该值3000ms以上高精度定位才有效果 + * @defaultValue 3000 + */ + highAccuracyExpireTime?: number | null, + /** + * 开启高精度定位 + * @type boolean + * @defaultValue false + */ + isHighAccuracy?: boolean | null, + /** + * 接口调用成功的回调函数 + */ + success?: GetLocationSuccessCallback | null, + /** + * 接口调用失败的回调函数 + */ + fail?: GetLocationFailCallback | null, + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete?: GetLocationCompleteCallback | null +}; -- GitLab