天天看点

cocosCreator - 高德定位接入准备工作Android层iOS层前端js

高德定位 官方文档: https://lbs.amap.com/api/android-location-sdk/locationsummary/

高德定位 SDK 下载地址

cocosCreator 基于2.1.4版本

准备工作

高德开发者平台

1.登陆账号 》进入控制台 》应用管理 》 我的应用

2.创建新应用

3.配置Android iOS 获取高德key值

Android配置

安全码SHA1的获取

cocosCreator - 高德定位接入准备工作Android层iOS层前端js

ios配置

cocosCreator - 高德定位接入准备工作Android层iOS层前端js

Android层

1.导入高德定位SDK

cocosCreator - 高德定位接入准备工作Android层iOS层前端js
  1. AndroidManifest.xml 修改
    cocosCreator - 高德定位接入准备工作Android层iOS层前端js
引入需要的权限
<!--用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!--用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <!--用于访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!--用于读取手机当前的状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!--用于写入缓存数据到扩展存储卡-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!--用于申请调用A-GPS模块-->
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <!--用于申请获取蓝牙信息进行室内定位-->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
           
<!-- 定位sdk需要配置 -->
        <meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="在高德平台申请的Key值" />
           

3.导入代码

cocosCreator - 高德定位接入准备工作Android层iOS层前端js

gpsContr.java

package org.cocos2dx.javascript.gps;

import android.Manifest;
import android.content.Context;
import android.support.v4.content.PermissionChecker;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.CoordinateConverter;

public class gpsContr {
    private static boolean isLocationReturn = false;
    private static AMapLocationClientOption locationOption = null;
    private static AMapLocationClient locationClient = null;
    private static CoordinateConverter converter = null;

    private static float longitude = -1;
    private static float latitude = -1;
    private static String city = "";
    private static String address = "";
    private static String district = "";
    private static String poiName = "";
    private static String province = "";
    private static String GPSStatus = ""; // ..GPS 定位得状态

    private static String locationResult = "";
    private static Context m_context = null;

    public static void GPSInit(Context context) {
        isGPSReady();
        m_context = context;
        initLocation();
    }

    // 初始化定位
    private static void initLocation() {
        // 初始化client
        locationClient = new AMapLocationClient(m_context);
        locationOption = getDefaultOption();
        // 设置定位参数
        locationClient.setLocationOption(locationOption);
        // 设置定位监听
        locationClient.setLocationListener(locationListener);
        // 计算距离需要
        converter = new CoordinateConverter(m_context);
    }
    // 销毁定位
    public static void destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的,
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient.onDestroy();
            locationClient = null;
            locationOption = null;
            converter = null;
        }
    }

    // 默认的定位参数
    private static AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);// 可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        // AMapLocationMode.Battery_Saving
        mOption.setGpsFirst(false);// 可选,设置是否gps优先,只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30000);// 可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(300000);// 可选,设置定位间隔。默认为2秒 设置成5分钟定位一次
        mOption.setNeedAddress(true);// 可选,设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false);// 可选,设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(false);// 可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);// 可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);// 可选,设置是否使用传感器。默认是false
        mOption.setWifiScan(true); // 可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
        mOption.setLocationCacheEnable(true); // 可选,设置是否使用缓存定位,默认为true
        mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);// 可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言)
        return mOption;
    }

    private static void isGPSReady() {
        try {
            int versionOne = PermissionChecker.checkSelfPermission(m_context, Manifest.permission.ACCESS_FINE_LOCATION);
            if (versionOne != 0) {
//                LocationManager locationManager;
//                locationManager = (LocationManager) m_context.getSystemService(Context.LOCATION_SERVICE);
                List<String> providers = locationManager.getProviders(true);
//                String locationProvider = null;
//                if (providers.contains(LocationManager.GPS_PROVIDER)) {
//                    // 如果是GPS
//                    locationProvider = LocationManager.GPS_PROVIDER;
//                } else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
//                    // 如果是Network
//                    locationProvider = LocationManager.NETWORK_PROVIDER;
//                }
                versionOne = PermissionChecker.checkSelfPermission(m_context, Manifest.permission.ACCESS_FINE_LOCATION);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 定位监听
    private static AMapLocationListener locationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation location) {
            if (null != location) {

                StringBuilder sb = new StringBuilder();
                // errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
                int errCode = location.getErrorCode();
                if (errCode == 0) {
                    sb.append("定位成功" + "\n");
                    sb.append("定位类型: " + location.getLocationType() + "\n");
                    sb.append("经    度    : " + location.getLongitude() + "\n");
                    sb.append("纬    度    : " + location.getLatitude() + "\n");
                    sb.append("精 度 : " + location.getAccuracy() + "米" + "\n");
                    sb.append("省 : " + location.getProvince() + "\n");
                    sb.append("市 : " + location.getCity() + "\n");
                    sb.append("区 : " + location.getDistrict() + "\n");
                    sb.append("地 址 : " + location.getAddress() + "\n");
                    sb.append("兴趣点 : " + location.getPoiName() + "\n");
                    isLocationReturn = true;
                    GPSStatus = "";
                    longitude = (float) location.getLongitude();
                    latitude = (float) location.getLatitude();
                    city = location.getCity();
                    address = location.getAddress();
                    district = location.getDistrict();
                    poiName = location.getPoiName();
                    province = location.getProvince();
                } else if (errCode == 12) {
                    GPSStatus = "没有开启App的定位权限";
                } else if (errCode == 14) {
                    GPSStatus = "GPS定位失败";
                } else {
                    GPSStatus = "GPS信号差";
                    // 定位失败
                    sb.append("定位失败" + "\n");
                    sb.append("错误码:" + location.getErrorCode() + "\n");
                    sb.append("错误信息:" + location.getErrorInfo() + "\n");
                    sb.append("错误描述:" + location.getLocationDetail() + "\n");
                    isLocationReturn = true;
                }
                locationResult = sb.toString();
            }

            // "定位失败"

        }
    };

    // 开始定位
    public static void startLocation() {
        // 启动定位
        locationClient.startLocation();
    }

    // 停止定位
    public static void stopLocation() {
        locationClient.stopLocation();
        locationResult = "stop location";
    }

    // 获取定位的结果字符串
    public static String getLocationString() {
        if (isLocationReturn) {
            isLocationReturn = false;
            return locationResult;
        } else {
            return "定位信息还未返回";
        }
    }

    public static float getLongitude() {
        return longitude;
    }

    public static float getLatitude() {
        return latitude;
    }

    // 省
    public static String getProvince() {
        return province;
    }

    // 市
    public static String getCity() {
        return city;
    }

    // 区
    public static String getDistrict() {
        return district;
    }

    // 地址
    public static String getAddress() {
        return address;
    }

    // 兴趣点
    public static String getPoiName() {
        return poiName;
    }

    // 定位得状态 自己定义得
    public static String getGpsStatus() {
        return GPSStatus;
    }
}

           

AppActivity.java中调用即可

import org.cocos2dx.javascript.gps.gpsContr;//引入脚本
 gpsContr.GPSInit(this);  //在onCreate()方法中初始化定位
 gpsContr.destroyLocation(); //在onDestroy()方法中销毁定位
           

iOS层

1.引入iOS需要的SDK

cocosCreator - 高德定位接入准备工作Android层iOS层前端js

2.开启Background Modes --> Location updates

cocosCreator - 高德定位接入准备工作Android层iOS层前端js

3.配置info.plist

定位需要的权限
cocosCreator - 高德定位接入准备工作Android层iOS层前端js

<key>NSBluetoothPeripheralUsageDescription</key> <string>是否许允此App使用蓝牙?</string> <key>NSCalendarsUsageDescription</key> <string>是否允许此App使用日历?</string> <key>NSCameraUsageDescription</key> <string>是否允许此App使用您的相机?</string> <key>NSContactsUsageDescription</key> <string>是否允许此App访问您的通讯录?</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>我们想要访问您的位置</string> <key>NSLocationAlwaysUsageDescription</key> <string>我们想要访问您的位置</string> <key>NSLocationWhenInUseUsageDescription</key> <string>我们想要访问您的位置</string> <key>NSMicrophoneUsageDescription</key> <string>允许我访问麦克风才能录音哦</string> <key>NSPhotoLibraryUsageDescription</key> <string>是否允许此App访问您的相册?</string>

4.引入需要的系统库

CoreLocation.framework //新增的

cocosCreator - 高德定位接入准备工作Android层iOS层前端js

5.调用方法

AppController.h

cocosCreator - 高德定位接入准备工作Android层iOS层前端js
#import <UIKit/UIKit.h>
#import <AMapLocationKit/AMapLocationKit.h>

@class RootViewController;

@interface AppController : NSObject <UIApplicationDelegate,WXApiDelegate>
{
}

@property(nonatomic, readonly) RootViewController* viewController;
@property (nonatomic, strong) AMapLocationManager* locationManager;

@end
           

AppController.mm

/****************************************************************************
 Copyright (c) 2010-2013 cocos2d-x.org
 Copyright (c) 2013-2016 Chukong Technologies Inc.
 Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
 
 http://www.cocos2d-x.org
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 ****************************************************************************/

#import "AppController.h"
#import "cocos2d.h"
#import "AppDelegate.h"

#import "RootViewController.h"
#import "SDKWrapper.h"
#import "platform/ios/CCEAGLView-ios.h"

#import "MessageViewController.h"
#import <AMapFoundationKit/AMapFoundationKit.h>

#define APP_NAME    @"hs_jindian13s"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
static void SendToJS(const char* str){
    se::ScriptEngine::getInstance()->evalString(str);
}

using namespace cocos2d;

@interface AppController ()<AMapLocationManagerDelegate>

@end

@implementation AppController
Application* app = nullptr;
static float latitude = -1;
static float longgitude = -1;
static NSString *city = @"";
@synthesize window;

#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[SDKWrapper getInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    // Add the view controller's view to the window and display.
    float scale = [[UIScreen mainScreen] scale];
    CGRect bounds = [[UIScreen mainScreen] bounds];
    window = [[UIWindow alloc] initWithFrame: bounds];
    
    // cocos2d application instance
    app = new AppDelegate(bounds.size.width * scale, bounds.size.height * scale);
    app->setMultitouch(true);
    // Use RootViewController to manage CCEAGLView
    _viewController = [[RootViewController alloc]init];
    
#ifdef NSFoundationVersionNumber_iOS_7_0
    _viewController.automaticallyAdjustsScrollViewInsets = NO;
    _viewController.extendedLayoutIncludesOpaqueBars = NO;
    _viewController.edgesForExtendedLayout = UIRectEdgeAll;
#else
    _viewController.wantsFullScreenLayout = YES;
#endif
    MessageViewController* Voiceview = [[MessageViewController alloc] init];
    [_viewController.view addSubview:Voiceview.view];
    // Set RootViewController to window
    if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0){
        // warning: addSubView doesn't work on iOS6
        [window addSubview: _viewController.view];
    }else{
        // use this method on ios6
        [window setRootViewController:_viewController];
    }
    [window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    //run the cocos2d-x game scene
    app->start();
    [AMapServices sharedServices].apiKey =@"高德key";
    
    [self configLocationManager];
    [self startLocation];
    return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
    [[SDKWrapper getInstance] applicationWillResignActive:application];
   
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
    [[SDKWrapper getInstance] applicationDidBecomeActive:application];
   
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
     */
    [[SDKWrapper getInstance] applicationDidEnterBackground:application];
    app->applicationDidEnterBackground();
     
}

- (void)applicationWillEnterForeground:(UIApplication *)application {

    /*
     Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
     */
    [[SDKWrapper getInstance] applicationWillEnterForeground:application];
    app->applicationWillEnterForeground();
    
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    [[SDKWrapper getInstance] applicationWillTerminate:application];
    delete app;
    app = nil;
}

#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /*
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
     */
}

#pragma location
- (void)configLocationManager {
    self.locationManager = [[AMapLocationManager alloc] init];
    [self.locationManager setDelegate:self];
    
    //设置不允许系统暂停定位
    [self.locationManager setPausesLocationUpdatesAutomatically:NO];
    
    //设置允许在后台定位
    [self.locationManager setAllowsBackgroundLocationUpdates:NO];
    
    //设置允许连续定位逆地理
    [self.locationManager setLocatingWithReGeocode:YES];
    
    //设置定位最小更新距离方法如下,单位米。当两次定位距离满足设置的最小更新距离时,SDK会返回符合要求的定位结果
    [self.locationManager setDistanceFilter:200];
}

- (void) startLocation {
    [self.locationManager startUpdatingLocation];
}

- (void)cleanUpAction {
    //停止定位
    [self.locationManager stopUpdatingLocation];
    [self.locationManager setDelegate:nil];
}

- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode {
    //    NSLog(@"location:{lat:%f; lon:%f; accuracy:%f}", location.coordinate.latitude, location.coordinate.longitude, location.horizontalAccuracy);
    latitude = location.coordinate.latitude;
    longgitude = location.coordinate.longitude;
    city = reGeocode.city;
    NSLog(@"lat:%f;lon:%f; city : %@", latitude, longgitude, city);
}

- (void)amapLocationManager:(AMapLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
}

//纬度
+ (float) getLatitude {
    return latitude;
}

//经度
+ (float) getLonggitude {
    return longgitude;
}

//市
+ (NSString*) getCity {
    return city;
}
@end

           

前端js

sendLocation() {
    	let Longgitude= ''; //经度
        let Latitude= '';   //纬度
        if (cc.sys.OS_ANDROID === cc.sys.os) {
            Latitude= jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getLatitude", "()Ljava/lang/String;");
            Longgitude= jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getLongitude", "()Ljava/lang/String;");
        } else if (cc.sys.OS_IOS === cc.sys.os) {
            Latitude = jsb.reflection.callStaticMethod("AppController", "getLatitude"); 
            Longgitude= jsb.reflection.callStaticMethod("AppController", "getLonggitude");
        }
    },
           

继续阅读