https://blog.csdn.net/unity_http/article/details/79929454
https://blog.csdn.net/why1happy/article/details/105765140
https://www.jianshu.com/p/1adbf9091575
https://blog.csdn.net/m0_37583098/article/details/78604329 接入ios可以参考
https://blog.csdn.net/qq_37310110/article/details/83145193 无需jar包
https://blog.csdn.net/qq_35080168/article/details/103425746
https://www.cnblogs.com/herenzhiming/articles/8334117.html android 调用unity的方法
https://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/ 高德错误码返回参考
本篇主要介绍在unity中接入高德定位sdk。
方法1、不用接入sdk,直接使用unity原生的方法,获得经纬度之后,以get请求得到城市相关信息。
代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using UnityEngine;
public class GPSDemo : MonoBehaviour
{
private AndroidJavaClass unity;
IEnumerator Start()
{
if (unity == null)
{
unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
}
if (!Input.location.isEnabledByUser)
{
Input.location.Start();
yield break;
}
// Start service before querying location
Input.location.Start();
// Wait until service initializes
int maxWait = 20;
while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
{
yield return new WaitForSeconds(1);
maxWait--;
}
// Service didn't initialize in 20 seconds
if (maxWait < 1)
{
print("Timed out");
yield break;
}
// Connection has failed
if (Input.location.status == LocationServiceStatus.Failed)
{
print("Unable to determine device location");
yield break;
}
else
{
// Access granted and location value could be retrieved
Debug.LogError("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);
//取出位置的经纬度
string str = Input.location.lastData.longitude + "," + Input.location.lastData.latitude;
Debug.Log("定位信息" + GetLocationByLngLat(str));
}
// Stop service if there is no need to query location updates continuously
Input.location.Stop();
}
const string key = "6bda73179a87a92394489045b32a0f46"; //去高德地图开发者申请 这个key的流量不知道被哪位同学用完了,
///
/// 根据经纬度获取地址
///
/// 经度纬度组成的字符串 例如:"113.692100,34.752853"
/// 超时时间默认10秒
/// 失败返回""
public string GetLocationByLngLat(string LngLatStr, int timeout = 10000)
{
string url = $"http://restapi.amap.com/v3/geocode/regeo?key={key}&location={LngLatStr}";
return GetLocationByURL(url, timeout);
}
public string GetLocationByLngLat(double lng, double lat, int timeout = 10000)
{
string url = $"http://restapi.amap.com/v3/geocode/regeo?key={key}&location={lng},{lat}";
Debug.LogError("url = " + url);
return GetLocationByURL(url, timeout);
}
private string GetLocationByURL(string url, int timeout = 10000)
{
string strResult = "";
try
{
HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
req.ContentType = "multipart/form-data";
req.Accept = "*/*";
//req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)";
req.UserAgent = "";
req.Timeout = timeout;
req.Method = "GET";
req.KeepAlive = true;
HttpWebResponse response = req.GetResponse() as HttpWebResponse;
using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
strResult = sr.ReadToEnd();
}
Debug.LogError("xxx123" + strResult);
}
catch (Exception ex)
{
Debug.LogError("ex = " + ex.ToString());
strResult = "";
}
return strResult;
}
这个就可以了。
你可以在web浏览器直接如下格式的请求:
http://restapi.amap.com/v3/geocode/regeo?key=6bda73179a87a92394489045b32a0f46&location=74,40
74,40是经纬度,逗号隔开。
key=6bda73179a87a92394489045b32a0f46 是人家的web开发的key。自己可以自己申请,申请的过程后文会介绍。这里先暂时用别人的。
2、使用sdk的接入
这里介绍的是android平台下接入高德sdk。
下载sdk:
https://lbs.amap.com/api/android-navi-sdk/download/
key的获取。
首先德注册高德开发账号,网址:https://lbs.amap.com/
注册之后,到达控制台:https://console.amap.com/dev/key/app
点击管理Key
创建新应用,随便起个名字。
1:起个刚才创建新应用的名字
2:服务平台选择android
3、发布版安全码SHA1获取方式:
3.1到达unity的项目:
选择keystore存放的路径,我这里选择在D盘了。
记住你的密码,这个在打包的时候会用到。
3.2到android studio中敲入如下命令:keytool -list -v -keystore D:\user.keystore
D:\user.keystore就是我们刚才的那个keystore文件。
得到:
ok,把这个SHA1,复制给上面的那个4开发SHA1中即可。
调试版的也用此命令:keytool -list -v -keystore debug.keystore
debug.keystore是android studio自带的:
在下:这个在安装了android studio之后就有了。
ok,同样也会得到:
将其复制到5:
4、最后一步是packageName:这个名字是你的android的应用包名:
ok,有了这个key之后,就可以了。
下面是代码部分:
android部分:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="demo.xiaoming.com.xiaominglib">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
<activity android:name=".MainActivity2" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.amap.api.v2.apikey" android:value="你的那个key"></meta-data>
<service android:name="com.amap.api.location.APSService"></service>
</application>
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!--获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!--这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!--写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
<!--用于申请获取蓝牙信息进行室内定位-->
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
</manifest>
Activity类:
package demo.xiaoming.com.xiaominglib;
import android.os.Debug;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
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.unity3d.player.UnityPlayerActivity;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity2 extends UnityPlayerActivity
{
public XiaomingInterface xiaomingInterface;
public int Add(int a, int b)
{
return a+b;
}
//声明mLocationClient对象
public AMapLocationClient mLocationClient = null;
public AMapLocationClientOption mLocationOption = null;
private String LocationInfo;
private String ErrorInfo="";
//获取定位信息
public String[] GetInfo()
{
String[] a=new String[2];
a[0]=this.LocationInfo;
a[1]=this.ErrorInfo;
Log.i("startget", "star get");
startLocation();
Log.i("endget", "endget");
return a;
}
private void startLocation()
{
this.mLocationClient = new AMapLocationClient(getApplicationContext());
//回调监听
this.mLocationClient.setLocationListener(this.mLocationListener);
//初始化定位参数
this.mLocationOption = new AMapLocationClientOption();
this.mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
this.mLocationOption.setInterval(1000L);
this.mLocationOption.setHttpTimeOut(10000l);
this.mLocationOption.setNeedAddress(true);
this.mLocationClient.setLocationOption(this.mLocationOption);
this.mLocationClient.startLocation();
}
public AMapLocationListener mLocationListener = new AMapLocationListener()
{
@Override
public void onLocationChanged(AMapLocation location)
{
Log.d("location xxxx = ", location.getAddress());
if (location != null)
{
if (location.getErrorCode() == 0)
{
StringBuffer sb = new StringBuffer(256);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(location.getTime());
String time=df.format(date);
sb.append("时间: " + time);
sb.append("\n纬度:" + location.getLatitude());
sb.append("\n经度:" + location.getLongitude());
sb.append("\n精度:" + location.getAccuracy());
sb.append("\n地址:" + location.getAddress());
sb.append("\n国家信息:" + location.getCountry());
sb.append("\n省信息:" + location.getProvince());
sb.append("\n城市信息:" + location.getCity());
sb.append("\n城区信息:" + location.getDistrict());
sb.append("\n街道信息:" + location.getStreet());
sb.append("\n街道门牌号信息:" + location.getStreetNum());
sb.append("\n城市编码:" + location.getCityCode());
sb.append("\n地区编码:" + location.getAdCode());
LocationInfo = sb.toString();
Log.d("LocationInfo = ", LocationInfo);
}
else
{
StringBuffer errorinfo = new StringBuffer(256);
errorinfo.append("错误代码:"+location.getErrorCode());
errorinfo.append("\n"+location.getErrorInfo());
ErrorInfo=errorinfo.toString();
Log.d("ErrorInfo = ", ErrorInfo);
}
mLocationClient.stopLocation();
mLocationClient.unRegisterLocationListener(mLocationListener);
Log.d("ErrorInfo = ", "stopLocation");
if(xiaomingInterface != null)
{
String[] res=new String[2];
res[0]=LocationInfo;
res[1]=ErrorInfo;
Log.d("ErrorInfoxxxx1", res[0]);
Log.d("ErrorInfoxxxx1", res[1]);
xiaomingInterface.FinishLocation(res);
Log.d("ErrorInfoxxxx2", ErrorInfo);
}
}
}
};
public void SetInterface(XiaomingInterface xx)
{
this.xiaomingInterface = xx;
if(this.xiaomingInterface != null)
{
Log.d("setinterface", "xiaomingInterface");
}
}
}
buildgradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation files('libs/AMap_Location_V5.0.0_20200609.jar')
}
afterEvaluate { //这个加入之后不会产生多个BuildConfig
generateReleaseBuildConfig.enabled = false
generateDebugBuildConfig.enabled = false
}
//task to delete the old jar(删除之前的.jar)
task deleteOldJar(type: Delete) {
delete 'release/AndroidPlugin.jar'
}
//task to export contents as jar(拷贝到指定目录 并修改名)
task exportJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
///Rename the jar
rename('classes.jar', 'AndroidPlugin.jar')
}
exportJar.dependsOn(deleteOldJar, build)
再次之前,还要导入jar包:
一个untiy的,一个是高度sdk的jar包。
rebuild失败,可以换代理:这是整个工程的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
maven { url "https://jitpack.io" }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
maven { url "https://jitpack.io" }
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
测试代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using UnityEngine;
public class UnityCallback : AndroidJavaProxy
{
public UnityCallback() : base("demo.xiaoming.com.xiaominglib.XiaomingInterface")
{
}
void FinishLocation(string[] strs)
{
Debug.LogError("xxxxx============");
for(int i=0;i<strs.Length;++i)
{
Debug.LogError("info=" + strs[i]);
}
}
}
public class GPSDemo : MonoBehaviour
{
private AndroidJavaClass unity;
IEnumerator Start()
{
if (unity == null)
{
unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
}
for (int i = 0; i < 5; ++i)
{
Debug.LogError("startxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx " + i);
}
Debug.LogError("start isEnabledByUser" + Input.location.isEnabledByUser);
if (!Input.location.isEnabledByUser)
{
Debug.LogError("start isEnabledByUser");
Input.location.Start();
yield break;
}
// Start service before querying location
Input.location.Start();
// Wait until service initializes
int maxWait = 20;
while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
{
yield return new WaitForSeconds(1);
maxWait--;
}
// Service didn't initialize in 20 seconds
if (maxWait < 1)
{
print("Timed out");
yield break;
}
// Connection has failed
if (Input.location.status == LocationServiceStatus.Failed)
{
print("Unable to determine device location");
yield break;
}
else
{
// Access granted and location value could be retrieved
Debug.LogError("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);
//取出位置的经纬度
string str = Input.location.lastData.longitude + "," + Input.location.lastData.latitude;
Debug.Log("定位信息" + GetLocationByLngLat(str));
}
// Stop service if there is no need to query location updates continuously
Input.location.Stop();
}
const string key = "6bda73179a87a92394489045b32a0f46"; //去高德地图开发者申请 这个key的流量不知道被哪位同学用完了,
///
/// 根据经纬度获取地址
///
/// 经度纬度组成的字符串 例如:"113.692100,34.752853"
/// 超时时间默认10秒
/// 失败返回""
public string GetLocationByLngLat(string LngLatStr, int timeout = 10000)
{
string url = $"http://restapi.amap.com/v3/geocode/regeo?key={key}&location={LngLatStr}";
return GetLocationByURL(url, timeout);
}
///
/// 根据经纬度获取地址
///
/// 经度 例如:113.692100
/// 维度 例如:34.752853
/// 超时时间默认10秒
/// 失败返回""
public string GetLocationByLngLat(double lng, double lat, int timeout = 10000)
{
string url = $"http://restapi.amap.com/v3/geocode/regeo?key={key}&location={lng},{lat}";
Debug.LogError("url = " + url);
return GetLocationByURL(url, timeout);
}
///
/// 根据URL获取地址
///
/// Get方法的URL
/// 超时时间默认10秒
///
private string GetLocationByURL(string url, int timeout = 10000)
{
string strResult = "";
try
{
HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
req.ContentType = "multipart/form-data";
req.Accept = "*/*";
//req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)";
req.UserAgent = "";
req.Timeout = timeout;
req.Method = "GET";
req.KeepAlive = true;
HttpWebResponse response = req.GetResponse() as HttpWebResponse;
using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
strResult = sr.ReadToEnd();
}
Debug.LogError("xxx123" + strResult);
}
catch (Exception ex)
{
Debug.LogError("ex = " + ex.ToString());
strResult = "";
}
return strResult;
}
public void OnClickButton()
{
UseSDK();
}
private void UseSDK()
{
AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
int a = currentActivity.Call<int>("Add", 2, 5);
Debug.LogError("add = " + a);
//注册回调接口
UnityCallback callback = new UnityCallback();
currentActivity.Call("SetInterface", callback);
string[] strs = currentActivity.Call<string[]>("GetInfo");
//Debug.LogError("map = ");
//for (int i = 0; i < strs.Length; ++i)
//{
// Debug.LogError("i = " + i + " " + strs[i]);
//}
//Debug.LogError("3333333333333333333333333333333");
//StartCoroutine(Sxxx());
}
private IEnumerator Sxxx()
{
if (!Input.location.isEnabledByUser)
{
Debug.LogError("start isEnabledByUser " + Input.location.isEnabledByUser);
Input.location.Start();
yield break;
}
}
}
ok,结束。