From 08771bc2aab901563c7818354ace92057ab8c374 Mon Sep 17 00:00:00 2001 From: yanyilin Date: Fri, 15 Sep 2023 17:28:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E8=85=BE=E8=AE=AF=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../uni-getLocation-tencent/changelog.md | 2 + .../uni-getLocation-tencent/package.json | 90 ++++++++ uni_modules/uni-getLocation-tencent/readme.md | 50 +++++ .../utssdk/app-android/AndroidManifest.xml | 31 +++ .../utssdk/app-android/config.json | 7 + .../utssdk/app-android/index.uts | 204 ++++++++++++++++++ .../utssdk/app-ios/config.json | 3 + .../utssdk/interface.uts | 85 ++++++++ 8 files changed, 472 insertions(+) create mode 100644 uni_modules/uni-getLocation-tencent/changelog.md create mode 100644 uni_modules/uni-getLocation-tencent/package.json create mode 100644 uni_modules/uni-getLocation-tencent/readme.md create mode 100644 uni_modules/uni-getLocation-tencent/utssdk/app-android/AndroidManifest.xml create mode 100644 uni_modules/uni-getLocation-tencent/utssdk/app-android/config.json create mode 100644 uni_modules/uni-getLocation-tencent/utssdk/app-android/index.uts create mode 100644 uni_modules/uni-getLocation-tencent/utssdk/app-ios/config.json create mode 100644 uni_modules/uni-getLocation-tencent/utssdk/interface.uts diff --git a/uni_modules/uni-getLocation-tencent/changelog.md b/uni_modules/uni-getLocation-tencent/changelog.md new file mode 100644 index 0000000..d9e3cc5 --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/changelog.md @@ -0,0 +1,2 @@ +## 1.0.0(2023-09-11) +基于腾讯定位服务,实现uni.getLocation 获取定位功能 diff --git a/uni_modules/uni-getLocation-tencent/package.json b/uni_modules/uni-getLocation-tencent/package.json new file mode 100644 index 0000000..18f3737 --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/package.json @@ -0,0 +1,90 @@ +{ + "id": "uni-getLocation-tencent", + "displayName": "uni-getLocation-tencent", + "version": "1.0.0", + "description": "基于腾讯定位服务,实现uni.getLocation 获取定位功能", + "keywords": [ + "uni-getLocation-tencent" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.9.0" + }, + "dcloudext": { + "type": "uts", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件使用的 腾讯定位SDK会采集数据,详情可参考:https://lbs.qq.com/", + "permissions": "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + }, + "npmurl": "" + }, + "uni_modules": { + "uni-ext-api": { + "uni": [ + "getLocation" + ] + }, + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-android": { + "minVersion": "19" + }, + "app-ios": { + "minVersion": "9" + } + }, + "H5-mobile": { + "Safari": "n", + "Android Browser": "n", + "微信浏览器(Android)": "n", + "QQ浏览器(Android)": "n" + }, + "H5-pc": { + "Chrome": "n", + "IE": "n", + "Edge": "n", + "Firefox": "n", + "Safari": "n" + }, + "小程序": { + "微信": "n", + "阿里": "n", + "百度": "n", + "字节跳动": "n", + "QQ": "n", + "钉钉": "n", + "快手": "n", + "飞书": "n", + "京东": "n" + }, + "快应用": { + "华为": "n", + "联盟": "n" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-getLocation-tencent/readme.md b/uni_modules/uni-getLocation-tencent/readme.md new file mode 100644 index 0000000..f1ab96c --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/readme.md @@ -0,0 +1,50 @@ +# uts-tencentgeolocation腾讯定位插件使用文档 + +## Android 平台 + +1. 申请腾讯地图key + +[申请网址](https://lbs.qq.com/mobile/androidMapSDK/developerGuide/getKey) + +2. 配置key到插件中 + +修改项目根目录下 AndroidManifest.xml +`` + +3. 打包自定义基座 + +注意将`uts-tencentgeolocation/utssdk/app-android/libs/androix-core-1.0.0.jar`先移到其他目录。 + +4. 运行自定义基座 + +注意打包自定义基座后将androix-core-1.0.0.jar移回原位,然后真机运行自定义基座。这个临时的移出移入问题后续会升级解决,详见uts插件开发文档的[临时注意](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#tempnotice)。 + +## iOS 平台 + +1.申请腾讯地图key + +[申请网址](https://lbs.qq.com/mobile/androidMapSDK/developerGuide/getKey) + +2.配置key到插件中 + +将申请的key配置到插件目录下 app-ios -> info.plist 中 TencentLBSAPIKey 对应的值 + +```xml +TencentLBSAPIKey +您申请的Key +``` + +3.配置访问位置权限描述信息 + +选中工程中的 manifest.json -> App权限配置 -> iOS隐私信息访问的许可描述,分别配置下列权限描述信息 + +- NSLocationAlwaysUsageDescription +- NSLocationWhenInUseUsageDescription +- NSLocationAlwaysAndWhenInUseUsageDescription + +4.制作自定义基座运行后生效 + +## 相关开发文档 + +- [UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html) +- [UTS 原生插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html) \ No newline at end of file diff --git a/uni_modules/uni-getLocation-tencent/utssdk/app-android/AndroidManifest.xml b/uni_modules/uni-getLocation-tencent/utssdk/app-android/AndroidManifest.xml new file mode 100644 index 0000000..3b88fd1 --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/utssdk/app-android/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/uni_modules/uni-getLocation-tencent/utssdk/app-android/config.json b/uni_modules/uni-getLocation-tencent/utssdk/app-android/config.json new file mode 100644 index 0000000..f7f9ab6 --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/utssdk/app-android/config.json @@ -0,0 +1,7 @@ +{ + "dependencies": [ + "com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.3.0" + ], + "minSdkVersion": "19" +} + diff --git a/uni_modules/uni-getLocation-tencent/utssdk/app-android/index.uts b/uni_modules/uni-getLocation-tencent/utssdk/app-android/index.uts new file mode 100644 index 0000000..df26477 --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/utssdk/app-android/index.uts @@ -0,0 +1,204 @@ +import { + UTSAndroid +} from "io.dcloud.uts"; + +import ActivityCompat from "androidx.core.app.ActivityCompat"; +import Manifest from "android.Manifest"; +import Looper from "android.os.Looper"; +import TencentLocationManager from "com.tencent.map.geolocation.TencentLocationManager"; +import TencentLocationListener from "com.tencent.map.geolocation.TencentLocationListener"; +import TencentLocation from "com.tencent.map.geolocation.TencentLocation"; +import TencentLocationRequest from "com.tencent.map.geolocation.TencentLocationRequest"; +import PackageManager from "android.content.pm.PackageManager"; +import Class from 'java.lang.Class'; +import Exception from 'java.lang.Exception'; + +import { GetLocation, GetLocationOptions, GetLocationSuccess,GetLocationFail } from "../interface.uts" + + + +export const getLocation : GetLocation = function (options : GetLocationOptions) { + + if(!checkHasIntegration()){ + // 当前没有集成腾讯sdk,提示需要打包 + let ret = new UniError("uni-getLocation-tencent",-10,"需要打自定义基座"); + + options.fail?.(ret) + options.complete?.(ret) + return; + } + if (!checkLocationConfig()) { + let ret = new UniError("uni-getLocation-tencent",-20,"未通过配置预校验,通常是app key 配置错误"); + options.fail?.(ret) + options.complete?.(ret) + return; + } + + /** + * 准备权限 + */ + let permissionNeed = ["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 ret = new UniError("uni-getLocation-tencent",-30,"permission missed."); + options.fail?.(ret) + options.complete?.(ret) + }) + + +} + + +/****************************************内部功能实现****************************************************/ + + +/** + * 定位监听结果包装类 + */ +class LocationOptionsWapper { + + hostOption : GetLocationOptions; + + constructor(option : GetLocationOptions) { + this.hostOption = option + } + + onLocationChanged(location : TencentLocation, _error : Int, + _reason : string) { + + let ret : GetLocationSuccess = { + latitude: location.latitude, + longitude: location.longitude, + speed: 0, + accuracy: location.accuracy, + altitude: location.altitude, + verticalAccuracy: 0, + horizontalAccuracy: location.accuracy, + address: location.address + } + + this.hostOption.success?.(ret) + // 包装数据结构返回 + } + + + onStatusUpdate(_name : string, _status : Int, _desc : string) { + // 定位状态发生变化 + } +}; + + +/** + * Tencent 定位监听实现类 + */ +class SingleLocationListener extends TencentLocationListener { + + + hostOptionWraper : LocationOptionsWapper; + + constructor(option : LocationOptionsWapper) { + super(); + this.hostOptionWraper = option + } + + override onLocationChanged(location : TencentLocation, error : Int, + reason : string) : void { + this.hostOptionWraper.onLocationChanged(location, error, reason); + } + + override onStatusUpdate(name : string, status : Int, desc : string) : void { + this.hostOptionWraper.onStatusUpdate(name, status, desc); + } + +} +/** + * 判断当前的基座是否已经集成了sdk, 即是否是自定义基座 + */ +function checkHasIntegration() : boolean { + + let hasIntegration = true + try { + let xClass = Class.forName("com.tencent.map.geolocation.TencentLocationListener") + } catch (e : Exception) { + hasIntegration = false; + } + + if (!hasIntegration) { + return false; + } + + return true +} +/** + * 检查定位的相关配置是否正确 + */ +function checkLocationConfig() : boolean { + + let packageName = UTSAndroid.getAppContext()!.getPackageName(); + let appInfo = UTSAndroid.getAppContext()!.getPackageManager()!.getApplicationInfo(packageName, PackageManager.GET_META_DATA) + + let metaData = appInfo.metaData + if (metaData == null) { + return false; + } + let adId = metaData.getString("TencentMapSDK") + if (adId == null) { + return false; + } + let splitArray = adId!.split("-") + let keyCharNum = splitArray.size + + if (keyCharNum > 5) { + // 存在超过5个-,说明是符合规则的appkey + return true; + } + // 不符合校验规则,打回 + return false; +} + + +/** + * 腾讯地图获取定位信息 + * 参考文档:https://lbs.qq.com/mobile/androidLocationSDK/androidGeoGuide/androidGeoAdapt + */ +function getLocationImpl(locationOptions : GetLocationOptions) { + + if(locationOptions.type != null && locationOptions.type!.toUpperCase() != 'GCJ-02' && locationOptions.type!.toUpperCase() != 'GCJ02'){ + // 腾讯定位只支持GCJ-02,如果不是则报错 + let ret = new UniError("uni-getLocation-tencent",-1,"GCJ-02 support only."); + locationOptions.fail?.(ret) + locationOptions.complete?.(ret) + return + } + + let mLocationManager = TencentLocationManager.getInstance(UTSAndroid.getAppContext()); + // 定位监听器封装 + let locationOptionWrapper = new LocationOptionsWapper(locationOptions); + let mLocationListener = new SingleLocationListener(locationOptionWrapper); + // 发起单次请求 + let locationRequest = TencentLocationRequest.create() + // 是否需要逆地理编码 + if (locationOptions.geocode != null && locationOptions.geocode == true) { + locationRequest.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_NAME); + } else { + locationRequest.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_GEO); + } + // 是否开启了高精度 + if (locationOptions.isHighAccuracy != null && locationOptions.isHighAccuracy == true) { + locationRequest.setAllowGPS(true) + } + /** + * 高度信息,腾讯没有明确的api设置 + */ + if (locationOptions.altitude != null && locationOptions.altitude == true) { + locationRequest.setAllowGPS(true) + } + + mLocationManager.requestSingleFreshLocation(locationRequest, mLocationListener, Looper.getMainLooper()); + +} diff --git a/uni_modules/uni-getLocation-tencent/utssdk/app-ios/config.json b/uni_modules/uni-getLocation-tencent/utssdk/app-ios/config.json new file mode 100644 index 0000000..721b81e --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/utssdk/app-ios/config.json @@ -0,0 +1,3 @@ +{ + "deploymentTarget": "9" +} \ No newline at end of file diff --git a/uni_modules/uni-getLocation-tencent/utssdk/interface.uts b/uni_modules/uni-getLocation-tencent/utssdk/interface.uts new file mode 100644 index 0000000..3ed7b50 --- /dev/null +++ b/uni_modules/uni-getLocation-tencent/utssdk/interface.uts @@ -0,0 +1,85 @@ +export interface Uni { + /** + * 获取当前的地理位置、速度 + * + * @tutorial http://uniapp.dcloud.io/api/location/location?id=getlocation + */ + getLocation: GetLocation; +} + +export type GetLocation = (options: GetLocationOptions) => void; +export type GetLocationSuccess = { + /** + * 纬度,浮点数,范围为-90~90,负数表示南纬 + */ + latitude: number, + /** + * 经度,范围为-180~180,负数表示西经 + */ + longitude: number, + /** + * 速度,浮点数,单位m/s + */ + speed: number, + /** + * 位置的精确度 + */ + accuracy: number, + /** + * 高度,单位 m + */ + altitude: number, + /** + * 垂直精度,单位 m(Android 无法获取,返回 0) + */ + verticalAccuracy: number, + /** + * 水平精度,单位 m + */ + horizontalAccuracy: number, + /** + * 地址信息 + */ + 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的坐标 + */ + type?: string | null, + /** + * 传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度 + * @type boolean + */ + altitude?: boolean | null, + /** + * 传入 true 会解析地址 + * @type boolean + */ + geocode?: boolean | null, + /** + * 高精度定位超时时间(ms),指定时间内返回最高精度,该值3000ms以上高精度定位才有效果 + */ + highAccuracyExpireTime?: number | null, + /** + * 开启高精度定位 + * @type boolean + */ + isHighAccuracy?: boolean | null, + /** + * 接口调用成功的回调函数 + */ + success?: GetLocationSuccessCallback | null, + /** + * 接口调用失败的回调函数 + */ + fail?: GetLocationFailCallback | null, + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete?: GetLocationCompleteCallback | null +}; -- GitLab