1.2.3-0.0.7 • Published 8 months ago

@ohmi/react-native-amap-geolocation v1.2.3-0.0.7

Weekly downloads
-
License
MIT
Repository
-
Last release
8 months ago

模板版本:v0.2.2

!TIP(https://e.gitee.com/kunyuan-hongke/projects/723653/repos/kunyuan-hongke/react-native-amap-geolocation/sources)

安装与使用

请到三方库的 Releases 发布地址查看配套的版本信息:@ohmi/react-native-amap-geolocation Releases 。对于未发布到npm的旧版本,请参考安装指南安装tgz包。

进入到工程目录并输入以下命令:

!TIP # 处替换为 tgz 包的路径

npm

npm install @ohmi/react-native-amap-geolocation@file:#

yarn

yarn add @ohmi/react-native-amap-geolocation@file:#

下面的代码展示了这个库的基本使用场景:

!WARNING 使用时 import 的库名不变。

import * as React from "react";
import {
    Button,
    Platform,
    ScrollView,
    StyleSheet,
    Text,
    View,
} from "react-native";
import {
    Geolocation, setInterval, addLocationListener, setAllowsBackgroundLocationUpdates,
    setGeoLanguage, setDistanceFilter, setDesiredAccuracy, init, setNeedAddress, start,
    stop, setLocationTimeout, setOnceLocation, GeoLanguage
} from "react-native-amap-geolocation";


const style = StyleSheet.create({
    body: {
        padding: 16,
        paddingTop: Platform.OS === "ios" ? 48 : 16,
    },
    button: {
        flexDirection: "column",
        marginRight: 8,
        marginBottom: 5,
        marginTop: 5
    },
    result: {
        fontFamily: Platform.OS === "ios" ? "menlo" : "monospace",
    },
});

class AmapGeoLocationDemo extends React.Component {
    state = {
        location: null, needAddressText: "setNeedAddress(false)",
        language: "setLanguage(chinese)", interval: "setInterval(默认2000)", onceText: "setOnceLocation(false) 设置单次定位",
        startText: "start 持续定位", timeoutText: "setLocationTimeout 设置请求定位超时时间",distanceText:"setDistanceFilter(0) 设置定位的最小更新距离"
    };
    watchId = 0;
    needAddress = true;
    currLanguage = GeoLanguage.ZH;
    currInterval = false;
    onceLocationJudge = false;
    timeout5000 = false;
    distanseJudge = true;
    init = () => {
        console.log("rn AMapLocationManagerImpl init");
        init("5f7389b845cbd89b1c32e24f526728f4").then(() => {
            console.log("rn AMapLocationManagerImpl init success");
        });

    };
    addLocationListener = () => {
        console.log("rn AMapLocationManagerImpl addLocationListener");
        addLocationListener((locationData) => {
            console.log("rn AMapLocationManagerImpl callback success:" + JSON.stringify(locationData, null, 2));
            let location = locationData;
            this.setState({ location: location });
        });
    };
    setDistanceFilter = () => {
        console.log("rn AMapLocationManagerImpl setDistanceFilter");
        this.distanseJudge = !this.distanseJudge;
        if (this.distanseJudge) {
            setDistanceFilter(0);
            this.setState({ distanceText: "setDistanceFilter(0) 设置定位的最小更新距离" });
        } else {
            setDistanceFilter(1);
            this.setState({ distanceText: "setDistanceFilter(1) 设置定位的最小更新距离" });
        }

    };
    setLocationTimeout = () => {
        console.log("rn AMapLocationManagerImpl setLocationTimeout");
        this.timeout5000 = !this.timeout5000;
        if (this.timeout5000) {
            setLocationTimeout(5000);
            this.setState({ timeoutText: "setLocationTimeout(5000) 设置请求定位超时时间" });
        } else {
            setLocationTimeout(10000);
            this.setState({ timeoutText: "setLocationTimeout(10000) 设置请求定位超时时间" });
        }
    };
    start = () => {
        console.log("rn AMapLocationManagerImpl start");
        start();
    };
    stop = () => {
        console.log("rn AMapLocationManagerImpl stop");
        stop();
    }
    onceLocation = () => {
        this.onceLocationJudge = !this.onceLocationJudge;
        if (this.onceLocationJudge) {
            setOnceLocation(true);
            this.setState({ onceText: "setOnceLocation(true) 设置单次定位", startText: "start 单次定位" });
        } else {
            setOnceLocation(false);
            this.setState({ onceText: "setOnceLocation(false) 设置单次定位", startText: "start 持续定位" });
        }
        console.log("rn AMapLocationManagerImpl current onceLocation:" + this.onceLocationJudge);
    };
    setInterval = () => {
        if (this.currInterval) {
            setInterval(2000);
            this.setState({ interval: "setInterval:2000" });
        } else {
            setInterval(10000);
            this.setState({ interval: "setInterval:10000" });
        }
        this.currInterval = !this.currInterval;
    }
    setNeedAddress = () => {
        this.needAddress = !this.needAddress;
        console.log("rn AMapLocationManagerImpl setNeedAddress:" + this.needAddress);
        if (this.needAddress) {
            setNeedAddress(true);
            this.setState({ needAddressText: "setNeedAddress(true)" });
        } else {
            setNeedAddress(false);
            this.setState({ needAddressText: "setNeedAddress(false)" });
        }
    }
    setLanguage = () => {
        // default = 0,chinese = 1, engilish=2;
        console.log("rn AMapLocationManagerImpl setLanguage");
        if (this.currLanguage == GeoLanguage.ZH) {
            this.currLanguage = GeoLanguage.EN;
            setGeoLanguage(GeoLanguage.EN);
            this.setState({ language: "setLanguage(engilish)" });
        } else {
            this.currLanguage = GeoLanguage.ZH;
            setGeoLanguage(GeoLanguage.ZH);
            this.setState({ language: "setLanguage(chinese)" });
        }

    }
    updateLocationState(location: any) {
    console.log("rn AMapLocationManagerImpl updateLocationState");
    if (location) {
        this.setState({ location: location });
        console.log(location);
    }
}
getCurrentPosition = () => {
    Geolocation.getCurrentPosition(
        (position) => this.updateLocationState(position),
        (error) => this.updateLocationState(error)
    );
};
watchPosition = () => {
    if (!this.watchId) {
        this.watchId = Geolocation.watchPosition(
            (position) => this.updateLocationState(position),
            (error) => this.updateLocationState(error)
        );
        console.log("rn AMapLocationManagerImpl watchPosition watchId:" + this.watchId);
    }
};
clearWatch = () => {
    if (this.watchId) {
        console.log("rn AMapLocationManagerImpl clearWatch watchId:" + this.watchId);
        Geolocation.clearWatch(this.watchId);
        this.watchId = 0;
    }
    stop();
    this.setState({ location: null });
};
render() {
    const location = this.state.location;
    const needAddressText = this.state.needAddressText;
    const language = this.state.language;
    const currInterval = this.state.interval;
    const onceText = this.state.onceText;
    const startText = this.state.startText;
    const timeoutText = this.state.timeoutText;
    const distanceText = this.state.distanceText;
    return (
        <ScrollView contentContainerStyle={style.body}>
        <View style={style.button}>
        <Button onPress={this.init} title="init 初始化接口" />
        </View>
        <View style={style.button}>
        <Button onPress={this.addLocationListener} title="addLocationListener 设置监听回调,原生接口不设置监听回调,text不会显示数据" />
        </View>
        <View style={style.button}>
        <Button onPress={this.setDistanceFilter} title={distanceText} />
        </View>
        <View style={style.button}>
        <Button onPress={this.setLocationTimeout} title={timeoutText} />
        </View>
        <View style={style.button}>
        <Button onPress={this.onceLocation} title={onceText} />
        </View>
        <View style={style.button}>
        <Button onPress={this.start} title={startText} />
        </View>
        <View style={style.button}>
        <Button onPress={this.stop} title="stop 结束持续定位" />
        </View>
        <View style={style.button}>
        <Button onPress={this.setInterval} title={currInterval} />
        </View>
        <View style={style.button}>
        <Button onPress={this.setNeedAddress} title={needAddressText} />
        </View>
        <View style={style.button}>
        <Button onPress={this.setLanguage} title={language} />
        </View>
        <View style={style.button}>
        <Button onPress={this.getCurrentPosition} title="Geolocation.getCurrentPosition 获取当前位置,相当于单次请求" />
        </View>
        <View style={style.button}>
        <Button onPress={this.watchPosition} title="Geolocation.watchPosition 开启持续定位" />
        </View>
        <View style={style.button}>
        <Button onPress={this.clearWatch} title="Geolocation.clearWatch 结束持续定位" />
        </View>
        <Text style={style.result}>{`${JSON.stringify(location, null, 2)}`}</Text>
    </ScrollView>
);
}

}

export default AmapGeoLocationDemo;

使用 Codegen

本库已经适配了 Codegen ,在使用前需要主动执行生成三方库桥接代码,详细请参考 Codegen 使用文档

Link

目前HarmonyOS暂不支持 AutoLink,所以 Link 步骤需要手动配置。

首先需要使用 DevEco Studio 打开项目里的HarmonyOS工程 harmony

1.在工程根目录的 oh-package.json 添加 overrides 字段

{
  ...
  "overrides": {
    "@rnoh/react-native-openharmony" : "./react_native_openharmony"
  }
}

2.引入原生端代码

目前有两种方法:

  1. 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
  2. 直接链接源码。

方法一:通过 har 包引入(推荐)

!TIP har 包位于三方库安装路径的 harmony 文件夹下。

打开 entry/oh-package.json5,添加以下依赖

"dependencies": {
    "@rnoh/react-native-openharmony": "file:../react_native_openharmony",
    "@ohmi/react-native-amap-geolocation": "file:../../node_modules/@ohmi/react-native-amap-geolocation/harmony/amap_geolocation.har"
  }

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

方法二:直接链接源码

!TIP 如需使用直接链接源码,请参考直接链接源码说明

3.在 ArkTs 侧引入 AmapGeolocationPackage

打开 entry/src/main/ets/RNPackagesFactory.ts,添加:

...
+  import {AMapGeolocationPackage} from '@ohmi/react-native-amap-geolocation/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
    new SamplePackage(ctx),
+   new AMapGeolocationPackage(ctx)
  ];
}

4.配置 CMakeLists 和引入 RNAmapGeolocationPackage

打开 entry/src/main/cpp/CMakeLists.txt,添加:

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@ohmi/react-native-amap-geolocation/src/main/cpp" ./amap_geolocation)
# RNOH_END: manual_package_linking_1

file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")

add_library(rnoh_app SHARED
    ${GENERATED_CPP_FILES}
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_amap_geolocation)
# RNOH_END: manual_package_linking_2

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SamplePackage.h"
+ #include "RNAmapGeolocationPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
        std::make_shared<RNOHGeneratedPackage>(ctx),
        std::make_shared<SamplePackage>(ctx),
+       std::make_shared<RNAmapGeolocationPackage>(ctx),
    };
}

5.运行

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

然后编译、运行即可。

约束与限制

兼容性

要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。

请到三方库相应的 Releases 发布地址查看 Release 配套的版本信息:@ohmi/react-native-amap-geolocation Releases

高德 APP KEY

为了使用高德 SDK,你需要准备高德 App Key,获取方法参考高德地图 SDK 官方文档:

高德地图 SDK

权限要求

在 entry 目录下的module.json5中添加权限

打开 entry/src/main/module.json5,添加:

...
"requestPermissions": [
  {
    "name": "ohos.permission.LOCATION",
    "reason": "$string:Access_Location",
    "usedScene": {
      "when":"inuse"
    }
  },
  {
    "name": "ohos.permission.APPROXIMATELY_LOCATION",
    "reason": "$string:Access_AppRoximatelyLocation",
    "usedScene": {
      "when":"inuse"
    }
  },
  {
    "name": "ohos.permission.INTERNET",
  }
]

在 entry 目录下添加位置权限的原因

打开 entry/src/main/resources/base/element/string.json,添加:

...
{
  "string": [
    {
      "name": "Access_Location",
      "value": "access Location"
    },
    {
      "name": "Access_AppRoximatelyLocation",
      "value": "access AppRoximatelyLocation"
    }
  ]
}

API

!TIP "Platform"列表示该属性在原三方库上支持的平台。

!TIP "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

NameDescriptionTypeRequiredPlatformHarmonyOS Support
init初始化 SDKPromiseyesiOS/Androidyes
addLocationListener添加定位监听函数voidyesiOS/Androidyes
isStarted获取当前是否正在定位的状态booleannoAndroidno
setAllowsBackgroundLocationUpdates是否允许后台定位voidnoiOSno
setDesiredAccuracy设定期望的定位精度(米)voidnoiOSno
setDistanceFilter设定定位的最小更新距离(米)voidnoiOSyes
setGeoLanguage设置逆地理信息的语言,目前支持中文和英文voidnoiOS/Androidyes
setGpsFirst设置首次定位是否等待卫星定位结果voidnoAndroidno
setGpsFirstTimeout设置优先返回卫星定位信息时等待卫星定位结果的超时时间(毫秒)voidnoAndroidno
setHttpTimeout设置联网超时时间(毫秒)voidnoAndroidno
setInterval设置发起定位请求的时间间隔(毫秒),默认 2000,最小值为 1000voidnoAndroidyes
setLocatingWithReGeocode连续定位是否返回逆地理编码voidnoiOSno
setLocationCacheEnable设置是否使用缓存策略voidnoAndroidno
setLocationMode设置定位模式voidnoAndroidno
setLocationPurpose设置定位场景voidnoAndroidno
setLocationTimeout指定单次定位超时时间(秒)noyesiOSyes
setMockEnable设置是否允许模拟位置voidnoAndroidno
setNeedAddress设置是否返回地址信息,默认返回地址信息noyesAndroidyes
setOnceLocation设置是否单次定位voidnoAndroidyes
setOnceLocationLatest设置定位是否等待 WiFi 列表刷新voidnoAndroidno
setOpenAlwaysScanWifi设置是否开启wifi始终扫描voidnoAndroidno
setPausesLocationUpdatesAutomatically指定定位是否会被系统自动暂停voidnoiOSno
setReGeocodeTimeout指定单次定位逆地理超时时间(秒)最小值是 2s。注意在单次定位请求前设置。voidnoiOSno
setSensorEnable设置是否使用设备传感器voidnoAndroidno
setWifiScan设置是否允许调用 WiFi 刷新voidnoAndroidno
start开始持续定位voidnoiOS/Androidyes
stop停止持续定位voidnoiOS/Androidyes
Geolocation.getCurrentPosition获取当前位置信息voidnoiOS/Androidyes
Geolocation.watchPosition注册监听器进行持续定位voidnoiOS/Androidyes
Geolocation.clearWatch移除位置监听voidnoiOS/Androidyes

遗留问题

  • isStarted()接口获取当前是否正在定位的状态,harmony暂不支持issue#2
  • setGpsFirst()接口获取当前是否正在定位的状态,harmony暂不支持issue#3
  • setGpsFirstTimeout()接口获取当前是否正在定位的状态,harmony暂不支持issue#4
  • setHttpTimeout()接口获取当前是否正在定位的状态,harmony暂不支持issue#5
  • setMockEnable()接口获取当前是否正在定位的状态,harmony暂不支持issue#6
  • setOnceLocationLatest()接口获取当前是否正在定位的状态,harmony暂不支持issue#7
  • setOpenAlwaysScanWifi()接口获取当前是否正在定位的状态,harmony暂不支持issue#8
  • setPausesLocationUpdatesAutomatically()接口获取当前是否正在定位的状态,harmony暂不支持issue#9
  • setReGeocodeTimeout()接口获取当前是否正在定位的状态,harmony暂不支持issue#10
  • setSensorEnable()接口获取当前是否正在定位的状态,harmony暂不支持issue#11
  • setWifiScan()接口获取当前是否正在定位的状态,harmony暂不支持issue#12
  • setLocationCacheEnable()接口获取当前是否正在定位的状态,harmony暂不支持issue#13
  • setLocationMode()接口获取当前是否正在定位的状态,harmony暂不支持issue#14
  • setLocationPurpose()接口获取当前是否正在定位的状态,harmony暂不支持issue#15
  • setLocatingWithReGeocode()接口获取当前是否正在定位的状态设置连续定位是否返回逆地理编码,harmony暂不支持issue#19
  • setDesiredAccuracy()接口设定期望的定位精度,harmony暂不支持issue#22
  • setAllowsBackgroundLocationUpdates()接口是否允许后台定位,harmony暂不支持issue#23

其他

开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。