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的流量不知道被哪位同學用完了,
/// <summary>
/// 根據經緯度獲取地址
/// </summary>
/// <param name="LngLatStr">經度緯度組成的字符串 例如:"113.692100,34.752853"</param>
/// <param name="timeout">超時時間默認10秒</param>
/// <returns>失敗返回"" </returns>
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
}
ok,這個之後:
就得到jar包了:
下面是在unity中使用:
測試代碼:
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的流量不知道被哪位同學用完了,
/// <summary>
/// 根據經緯度獲取地址
/// </summary>
/// <param name="LngLatStr">經度緯度組成的字符串 例如:"113.692100,34.752853"</param>
/// <param name="timeout">超時時間默認10秒</param>
/// <returns>失敗返回"" </returns>
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);
}
/// <summary>
/// 根據經緯度獲取地址
/// </summary>
/// <param name="lng">經度 例如:113.692100</param>
/// <param name="lat">維度 例如:34.752853</param>
/// <param name="timeout">超時時間默認10秒</param>
/// <returns>失敗返回"" </returns>
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);
}
/// <summary>
/// 根據URL獲取地址
/// </summary>
/// <param name="url">Get方法的URL</param>
/// <param name="timeout">超時時間默認10秒</param>
/// <returns></returns>
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,結束。