高德定位 官方文档: https://lbs.amap.com/api/android-location-sdk/locationsummary/
高德定位 SDK 下载地址
cocosCreator 基于2.1.4版本
准备工作
高德开发者平台
1.登陆账号 》进入控制台 》应用管理 》 我的应用
2.创建新应用
3.配置Android iOS 获取高德key值
Android配置
安全码SHA1的获取
ios配置
Android层
1.导入高德定位SDK
- AndroidManifest.xml 修改
引入需要的权限
<!--用于进行网络定位-->
<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.导入代码
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
2.开启Background Modes --> Location updates
3.配置info.plist
定位需要的权限 <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 //新增的
5.调用方法
AppController.h
#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");
}
},