项目作者: amap-demo

项目描述 :
Weex上使用高德定位SDK的示例
高级语言: JavaScript
项目地址: git://github.com/amap-demo/amap-location-weex.git
创建时间: 2018-09-20T08:48:15Z
项目社区:https://github.com/amap-demo/amap-location-weex

开源协议:

下载


前述

  1. 高德官网申请Key.
  2. 阅读开发指南.Android/iOS
  3. 基于Weex 版本:v1.3.11
  4. 本工程是基于React Native环境创建,并不是创建了一个library,如需要修改成library请参考官网

Weex 环境搭建

请参考Weex官网

开发 - Android / iOS

配置好Weex环境后,下载本工程,可以通过npm install安装之后,通过weex run android/ios 直接运行查看效果

Android - 引入高德定位SDk的jar包" class="reference-link">Android - 引入高德定位SDk的jar包

  1. 通过jar包的方式引入
  2. 通过Gradle方式集成

配置AndroidManifest.xml

  1. 注册定位SDK需求的权限
  1. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
  2. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
  3. <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
  4. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
  5. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
  6. <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
  7. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
  8. <uses-permission android:name="android.permission.INTERNET"></uses-permission>
  9. <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
  10. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
  11. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission>
  12. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
  1. 填写您的key

    注意工程中的的key是测试使用的key,在使用过程中请使用自己的key

  1. <meta-data
  2. android:name="com.amap.api.v2.apikey"
  3. android:value="您的key"/>
  1. 注册定位service
  1. <service android:name="com.amap.api.location.APSService"></service>

关键代码

编写模块

WXAMapLocationModule.java

注解方式指定Module名称

  1. @WeexModule(name = "amapLocation")
  2. public class WXAMapLocationModule extends WXModule

通过@JSMethod暴露方法给js

  1. /**
  2. * 获取一次位置
  3. * @param needAddress 是否需要逆地理信息
  4. * @param jsCallback
  5. */
  6. @JSMethod(uiThread = true)
  7. public void getLocation(boolean needAddress, final JSCallback jsCallback) {
  8. if (null == locationOption) {
  9. locationOption = new AMapLocationClientOption();
  10. }
  11. /**
  12. * 设置定位模式为高精度模式,实际开发中可以根据需要自行设置
  13. */
  14. locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
  15. locationOption.setOnceLocation(true);
  16. locationOption.setNeedAddress(needAddress);
  17. if (null == locationClient) {
  18. locationClient = new AMapLocationClient(mWXSDKInstance.getContext());
  19. }
  20. locationClient.setLocationOption(locationOption);
  21. locationClient.setLocationListener(new AMapLocationListener() {
  22. @Override
  23. public void onLocationChanged(AMapLocation location) {
  24. Map<String, Object> resultMap = buildLocationResult(location);
  25. if (null != resultMap
  26. && resultMap.size() > 0
  27. && null != jsCallback) {
  28. //回调结果给JS
  29. jsCallback.invoke(resultMap);
  30. }
  31. }
  32. });
  33. locationClient.startLocation();
  34. }
  35. /**
  36. * 持续获取位置信息
  37. * @param needAddress 是否需要地址信息
  38. * @param interval 定位间隔
  39. * @param jsCallback
  40. */
  41. @JSMethod(uiThread = true)
  42. public void watchLocation(boolean needAddress, int interval, JSCallback jsCallback) {
  43. if (null == locationOption) {
  44. locationOption = new AMapLocationClientOption();
  45. }
  46. keepCallBack = jsCallback;
  47. /**
  48. * 设置定位模式为高精度模式,实际开发中可以根据需要自行设置
  49. */
  50. locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
  51. locationOption.setNeedAddress(needAddress);
  52. locationOption.setOnceLocation(false);
  53. /**
  54. * 定位间隔,单位毫秒
  55. */
  56. locationOption.setInterval(interval);
  57. if(null != locationClient){
  58. locationClient.stopLocation();
  59. locationClient.onDestroy();
  60. locationClient = null;
  61. }
  62. locationClient = new AMapLocationClient(mWXSDKInstance.getContext());
  63. locationClient.setLocationOption(locationOption);
  64. locationClient.setLocationListener(locationListener);
  65. locationClient.startLocation();
  66. }
  67. /**
  68. * 停止定位
  69. */
  70. @JSMethod(uiThread = true)
  71. public void stopLocation() {
  72. if (null != locationClient) {
  73. locationClient.stopLocation();
  74. locationClient.onDestroy();
  75. locationClient = null;
  76. }
  77. }

注册模块

在WXApplication中添加以下代码

  1. WXSDKEngine.registerModule("amapLocation", WXAMapLocationModule.class);
编写AMapLocationPackage类实现ReactPackage接口
  1. @Override
  2. public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
  3. List<NativeModule> modules = new ArrayList<NativeModule>();
  4. modules.add(new AMapLocationModule(reactContext));
  5. return modules;
  6. }
  7. @Override
  8. public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
  9. return Collections.emptyList();
  10. }

iOS 集成高德定位SDK的AMapLocation" class="reference-link">iOS 集成高德定位SDK的AMapLocation

  1. 通过framework集成,从高德开放平台官网下载定位SDK,拖入工程方式集成
  2. 通过cocoapods集成,进入项目目录platforms/ios/ 打开Podfile文件,添加pod 'AMapLocation',然后在iOS目录下执行pod install

注:使用pod集成时候,WeexSDK 写为pod 'WeexSDK', '0.18.0.3'这版本,目前最新版0.19.0会出现报错,出现白屏问题 (2018.11.1)


配置Xcode工程

  1. plist文件权限,在项目info.plist文件中,加入一下权限

    1. <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    2. <string>路过导航需要您的定位服务,否则可能无法使用,如果您需要使用后台导航功能请选择“始终允许”。</string>
    3. <key>NSLocationAlwaysUsageDescription</key>
    4. <string>路过导航需要您的定位服务,否则可能无法使用。</string>
    5. <key>NSLocationWhenInUseUsageDescription</key>
    6. <string>路过导航需要您的定位服务,否则可能无法使用。</string>
  2. 填写您的key 注意:工程中的的key是测试使用的key,在使用过程中请使用自己的key

    1. // 这里是到 https://lbs.amap.com/dev/key/app 开放平台申请应用的key,设置到这里
    2. [AMapServices sharedServices].apiKey =@"您的key";

关键代码

编写模块 WXAMapLocationModule

  1. ```
  2. #import "WXAMapLocationModule.h"
  3. #import <AMapLocationKit/AMapLocationKit.h>
  4. @interface WXAMapLocationModule ()<AMapLocationManagerDelegate>
  5. @property (nonatomic,strong) AMapLocationManager *locManager;
  6. @property (nonatomic,copy) WXModuleKeepAliveCallback singleLocCallBack;
  7. @property (nonatomic,copy) WXModuleKeepAliveCallback repeatLocCallBack;
  8. @end
  9. @implementation WXAMapLocationModule
  10. WX_EXPORT_METHOD_SYNC(@selector(getLocation:completionBlock:))
  11. WX_EXPORT_METHOD_SYNC(@selector(watchLocation:interval:repeatLocationBlock:))
  12. WX_EXPORT_METHOD_SYNC(@selector(stopLocation))
  13. /**
  14. * 获取一次位置,如果当前正在连续定位,调用此方法将会失败
  15. * @param withReGeocode 是否反地理编码(获取逆地理信息需要联网)
  16. * @param singleLocCallBack 单次定位完成后的Block
  17. */
  18. - (void)getLocation:(BOOL)withReGeocode completionBlock: (WXModuleKeepAliveCallback)singleLocCallBack {
  19. __weak typeof(self) weakSelf = self;
  20. [self.locManager requestLocationWithReGeocode:withReGeocode completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
  21. NSDictionary *result = [weakSelf createResultDictWithLocation:location LocationReGeocode:regeocode error:error];
  22. if (result && singleLocCallBack) {
  23. singleLocCallBack(result, NO);
  24. }
  25. }];
  26. }
  27. /**
  28. * 持续获取位置信息
  29. * @param needAddress 是否需要地址信息
  30. * @param interval 时间间隔(目前此参数无效)
  31. * @param repeatLocCallBack 继续定位的回调
  32. */
  33. - (void)watchLocation:(BOOL)needAddress interval:(NSUInteger)interval repeatLocationBlock:(WXModuleKeepAliveCallback)repeatLocCallBack {
  34. self.repeatLocCallBack = repeatLocCallBack;
  35. self.locManager.locatingWithReGeocode = needAddress;
  36. [self.locManager startUpdatingLocation];
  37. }
  38. /**
  39. * 停止定位
  40. */
  41. - (void)stopLocation {
  42. [self.locManager stopUpdatingLocation];
  43. self.locManager = nil;
  44. }
  45. // 定位回调代理
  46. /**
  47. * @brief 连续定位回调函数.注意:如果实现了本方法,则定位信息不会通过amapLocationManager:didUpdateLocation:方法回调。
  48. * @param manager 定位 AMapLocationManager 类。
  49. * @param location 定位结果。
  50. * @param reGeocode 逆地理信息。
  51. */
  52. - (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode {
  53. if (self.repeatLocCallBack) {
  54. NSDictionary *result = [self createResultDictWithLocation:location LocationReGeocode:reGeocode error:nil];
  55. self.repeatLocCallBack(result, YES);
  56. }
  57. }
  58. - (AMapLocationManager *)locManager {
  59. if (!_locManager) {
  60. _locManager = [[AMapLocationManager alloc] init];
  61. _locManager.delegate = self;
  62. [_locManager setLocationTimeout:3.0];
  63. [_locManager setReGeocodeTimeout:3.0];
  64. }
  65. return _locManager;
  66. }
  67. @end
  68. ```

注册模块

  • WeexSDKManager类中注册模块
    [WXSDKEngine registerModule:@"amapLocation" withClass:[WXAMapLocationModule class]];

Js中调用

在src/index.vue中实现对定位的调用

  1. <script>
  2. export default {
  3. name: '高德定位示例',
  4. data () {
  5. return {
  6. result: '',
  7. }
  8. },
  9. methods: {
  10. onceLocation: function() {
  11. weex.requireModule('amapLocation').getLocation(true, loc => {
  12. var str;
  13. if(loc.code != 0){
  14. this.result = '定位失败\n,errorCode:' + loc.code + '\n错误说明:' + loc.errorDetail
  15. console.error('定位失败:' + loc.code + "," + loc.errorDetail)
  16. } else {
  17. str = '定位成功\n'
  18. + '经纬度:' + loc.lon + ',' + loc.lat + '\n'
  19. if(loc.addr != 'undefined' && loc.addr != null && loc.addr != ''){
  20. str += '地址:' + loc.addr +'\n'
  21. }
  22. str += '回调时间:' + loc.callbackTime
  23. this.result = str
  24. }
  25. });
  26. },
  27. watchLocation: function() {
  28. weex.requireModule('amapLocation').watchLocation(false, 2000, loc => {
  29. var str;
  30. if(loc.code != 0){
  31. this.result = '定位失败\n,errorCode:' + loc.code + '\n错误说明:' + loc.errorDetail
  32. console.error('定位失败:' + loc.code + "," + loc.errorDetail)
  33. } else {
  34. str = '定位成功\n'
  35. + '经纬度:' + loc.lon + ',' + loc.lat + '\n'
  36. if(loc.addr != 'undefined' && loc.addr != null && loc.addr != ''){
  37. str += '地址:' + loc.addr +'\n'
  38. }
  39. str += '回调时间:' + loc.callbackTime
  40. this.result = str
  41. }
  42. });
  43. },
  44. stopLocation: function() {
  45. weex.requireModule('amapLocation').stopLocation();
  46. },
  47. }
  48. }
  49. </script>

运行

  1. //初始化运行环境
  2. npm install
  3. //在android、iOS设备上运行
  4. weex run android / ios