1. 程式人生 > >Unity與Android交互-Unity接入高德地圖實現定位以及搜索周邊的功能(使用Android Studio)詳細操作

Unity與Android交互-Unity接入高德地圖實現定位以及搜索周邊的功能(使用Android Studio)詳細操作

nac mcc 以及 分享 pack create lis red 效果

剛進公司給安排的任務就是Unity接入高德地圖,算是踩了不少坑總算做出來了,抽點時間寫個博客記錄一下

廢話不多說

先上效果圖

獲取定位並根據手機朝向顯示周邊信息

技術分享 技術分享

使用的Unity版本為5.5,Androad Studio 2.3.1

接下來開始講具體操作

首先是Androad Studio的基本配置


1.創建工程,空白的就行,反正也用不到界面布局

技術分享

等待創建完成

2.新建庫模塊:

切換到Project視圖

技術分享

右擊你的項目 新建一個庫模塊-用來負責與Unity交互

當然你也可以不選擇新建庫模塊 直接在原生app模塊進行操作

技術分享

選擇Android Library

技術分享

等待生成完成

你會看到多出來的

技術分享

3.創建MainActivity:我們新建的library中沒有啟動這個模塊的Java類 所以需要手動創建一個

切換到Android視窗下 選中此文件右鍵創建

技術分享

技術分享

4.刪除布局文件activity_main

布局文件是用來管理Android界面布局的,我們並不需要,所以將它刪除,防止發生一些沒必要的錯誤

技術分享

5.修改配置文件:AndroidManifest

為了能夠正常發布 需要將AndroidManifest進行一些修改

技術分享

在這中間插入啟動Activity的配置

技術分享

        <activity android:name=".MainActivity
"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>

到這裏基本配置就完了

然後進行測試點擊這個

技術分享

或許你會發現報錯了 原因是我們在創建MainActivity的時候他自動引用了布局文件 所以這裏應該將這一行刪除

技術分享

然後再次更新 成功

到這裏基本配置以及完成

引入Unity與高德地圖的包

下載高德地圖包 這裏有個定制選你要用的功能下載就好 這裏我用到的是定位和搜索

技術分享

將下載好的包拖入libs中

技術分享

接下來是Unity的包

新建Unity工程

發布平臺改Android

設置package name與你新建的library庫一致

技術分享

然後發布系統ADT 導出

技術分享

在libs中找到

技術分享

復制進Android Sturio中的libs

選中兩個包Add As Library

技術分享

選library工程 OK

技術分享

等待加載完成

到這裏引入包的操作已經完成

更改MainActivity並發布

主要內容為

獲取當前定位信息

獲取查詢指定字符串周邊信息

技術分享
  1 package com.example.autlibrary;
  2 
  3 import android.os.Bundle;
  4 import android.util.Log;
  5 import android.widget.Toast;
  6 import com.amap.api.location.AMapLocation;
  7 import com.amap.api.location.AMapLocationClient;
  8 import com.amap.api.location.AMapLocationClientOption;
  9 import com.amap.api.location.AMapLocationListener;
 10 import com.amap.api.services.core.LatLonPoint;
 11 import com.amap.api.services.core.PoiItem;
 12 import com.amap.api.services.poisearch.PoiResult;
 13 import com.amap.api.services.poisearch.PoiSearch;
 14 import com.unity3d.player.UnityPlayerActivity;
 15 
 16 public class MainActivity
 17         extends UnityPlayerActivity
 18         implements PoiSearch.OnPoiSearchListener
 19 {
 20     public AMapLocationClient mLocationClient = null;
 21     public AMapLocationClientOption mLocationOption = null;
 22     private String LocationInfo;
 23     private String strRerurnInfo;
 24     private PoiSearch.Query query;
 25     private PoiResult poir;
 26     private double Latitude;
 27     private double Longitude;
 28     private boolean bolIsPoi = false;
 29 
 30     protected void onCreate(Bundle savedInstanceState)
 31     {
 32         super.onCreate(savedInstanceState);
 33     }
 34     //獲取定位信息
 35     public String GetInfo()
 36     {
 37         startLocation();
 38         this.bolIsPoi = true;
 39         return this.LocationInfo;
 40     }
 41     //獲取周邊POI信息
 42     public String GetPoi(String content, String val, int index)
 43     {
 44         startLocation();
 45         search(content, val, index);
 46         return this.strRerurnInfo;
 47     }
 48 
 49     protected void onStart()
 50     {
 51         super.onStart();
 52     }
 53 
 54     private void startLocation()
 55     {
 56         this.mLocationClient = new AMapLocationClient(getApplicationContext());
 57         this.mLocationClient.setLocationListener(this.mLocationListener);
 58         this.mLocationOption = new AMapLocationClientOption();
 59         this.mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
 60         this.mLocationOption.setInterval(2000L);
 61         this.mLocationClient.setLocationOption(this.mLocationOption);
 62         this.mLocationClient.startLocation();
 63     }
 64 
 65     //三個參數分別為搜索字符串、搜索類型、查詢第幾頁
 66     //前兩個參數選其一
 67     //如:酒店、""、1
 68     //第二個參數為poi搜索類型:
 69     //汽車服務|汽車銷售|汽車維修|摩托車服務|餐飲服務|購物服務|生活服務|體育休閑服務|
 70     // 醫療保健服務|住宿服務|風景名勝|商務住宅|政府機構及社會團體|科教文化服務|
 71     // 交通設施服務|金融保險服務|公司企業|道路附屬設施|地名地址信息|公共設施
 72     public void search(String content, String val, int index)
 73     {
 74         if (this.bolIsPoi) {
 75             if (content == null)
 76             {
 77                 Toast.makeText(this, "輸入為空", Toast.LENGTH_SHORT).show();
 78             }
 79             else
 80             {
 81                 this.query = new PoiSearch.Query(content, val, "");
 82                 this.query.setPageSize(30);
 83                 this.query.setPageNum(index);
 84                 PoiSearch poiSearch = new PoiSearch(this, this.query);
 85                 if ((this.Latitude != 0.0D) && (this.Longitude != 0.0D))
 86                 {
 87                     poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(this.Latitude, this.Longitude), 6000));
 88 
 89                     poiSearch.setOnPoiSearchListener(this);
 90                     poiSearch.searchPOIAsyn();
 91                 }
 92                 else
 93                 {
 94                     Toast.makeText(this, "定位失敗", Toast.LENGTH_SHORT).show();
 95                 }
 96             }
 97         }
 98     }
 99 
100     public void onPoiSearched(PoiResult result, int code)
101     {
102         this.bolIsPoi = false;
103         System.out.println("Result" + (result.getPois().get(0)).getLatLonPoint());
104         System.out.println("Code" + code);
105         this.poir = result;
106         StringBuffer sb = new StringBuffer(256);
107         for (int j = 0; j < this.poir.getPois().size(); j++)
108         {
109             sb.append("\n名字:");
110             sb.append((this.poir.getPois().get(j)).getTitle());
111             sb.append("\n>地址:");
112             sb.append((this.poir.getPois().get(j)).getSnippet());
113             sb.append("\n>距離:");
114             sb.append((this.poir.getPois().get(j)).getDistance());
115         }
116         this.strRerurnInfo = sb.toString();
117     }
118 
119     @Override
120     public void onPoiItemSearched(PoiItem poiItem, int i) {
121 
122     }
123 
124     public AMapLocationListener mLocationListener = new AMapLocationListener() {
125         @Override
126         public void onLocationChanged(AMapLocation location) {
127             if (location != null) {
128                 if (location.getErrorCode() == 0) {
129                     //獲取坐標信息
130                     Latitude = location.getLatitude();
131                     Longitude = location.getLongitude();
132 
133                     StringBuffer sb = new StringBuffer(256);
134                     sb.append("時間: " + location.getTime());
135                     sb.append("\n緯度:" + location.getLatitude());
136                     sb.append("\n經度:" + location.getLongitude());
137                     sb.append("\n精度:" + location.getAccuracy());
138                     sb.append("\n地址:" + location.getAddress());
139                     sb.append("\n國家信息:" + location.getCountry());
140                     sb.append("\n省信息:" + location.getProvince());
141                     sb.append("\n城市信息:" + location.getCity());
142                     sb.append("\n城區信息:" + location.getDistrict());
143                     sb.append("\n街道信息:" + location.getStreet());
144                     sb.append("\n街道門牌號信息:" + location.getStreetNum());
145                     sb.append("\n城市編碼:" + location.getCityCode());
146                     sb.append("\n地區編碼:" + location.getAdCode());
147                     sb.append("\n定位點AOI信息:" + location.getAoiName());
148                     LocationInfo = sb.toString();
149                 }else {
150                     Log.e("AmapError","location Error, ErrCode:"
151                             + location.getErrorCode() + ", errInfo:"
152                             + location.getErrorInfo());
153                 }
154             }
155         }
156     };
157 }
MainActivity

修改完MainActivity 無錯誤的話 就可以發布了

發布到library庫中

技術分享

然後你在

“你的工程目錄”\autlibrary\build\intermediates\bundles\debug中會有這些

技術分享

右鍵Show in Exploer 並在文件夾中找到他們

技術分享

這樣就發布成功了

與Unity間的交互

上一步我們導出了工程包

我們需要將它修改為Unity可用的工程

復制classes.jar

粘貼到libs

刪除libs中的unity-classes.jar

技術分享

-

技術分享

-

技術分享

這樣的話就修改成功了 然後我們將它導入Unity

復制libs和res文件夾到Unity

技術分享

需要創建Plugins和Android文件夾 復制過後是這樣的關系

技術分享

這樣就成功導入進了Unity

配置AndroidManifest.Xml文件,並創建C#腳本

不知道你還記不記得我們在Unity中導出的包 找到它!我們需要裏面的Xml文件

技術分享

將它復制到\Assets\Plugins\Android下

技術分享

接著就要對它進行修改了

技術分享

技術分享
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.autlibrary" xmlns:tools="http://schemas.android.com/tools" android:versionName="1.0" android:versionCode="1" android:installLocation="preferExternal">
 3   <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
 4   <application android:theme="@style/UnityThemeSelector" android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false" android:isGame="true" android:banner="@drawable/app_banner">
 5       <meta-data
 6         android:name="com.amap.api.v2.apikey"
 7         android:value="64c821ae174ab7429fa45535d01f20ae"/>
 8       <activity 
 9         android:label="@string/app_name" android:screenOrientation="fullSensor" 
10         android:launchMode="singleTask" 
11         android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" 
12         android:name="com.example.autlibrary.MainActivity">
13       <service android:name="com.amap.api.location.APSService" ></service>
14       <intent-filter>
15         <action android:name="android.intent.action.MAIN" />
16         <category android:name="android.intent.category.LAUNCHER" />
17         <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
18       </intent-filter>
19       <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
20     </activity>
21   </application>
22   <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="25" />
23   <uses-feature android:glEsVersion="0x00020000" />
24   <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
25   <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
26   <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
27   <uses-permission android:name="android.permission.INTERNET" />
28   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
29   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
30   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
31   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
32   <uses-permission android:name="android.permission.READ_PHONE_STATE" />
33   <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
34   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
35   <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
36   <uses-permission android:name="android.permission.WAKE_LOCK" />
37   <uses-permission android:name="android.permission.WRITE_SETTINGS" />
38 </manifest>
AndroidManifest

配置完畢就可以搭界面和寫C#邏輯了

新建GetLocationAndPoiInfo腳本

技術分享
 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 using UnityEngine.UI;
 5 
 6 public class GetLocationAndPoiInfo : MonoBehaviour {
 7 
 8     public Text locText;
 9     public Text poiText;
10     public Button locBtn;
11     public Button poiBtn;
12 
13     AndroidJavaClass jc;
14     AndroidJavaObject jo;
15 
16     // Use this for initialization
17     void Start () {
18         OnStart();
19         locBtn.onClick.AddListener(() => { GetLocationInfo(); });
20         poiBtn.onClick.AddListener(() => { GetPoiInfo(); });
21     }
22     void OnStart() {
23         jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
24         jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
25     }
26 
27     void GetLocationInfo() {
28         locText.text = "";
29         OnStart();
30         locText.text = jo.Call<string>("GetInfo");
31     }
32 
33     void GetPoiInfo() {
34         locText.text = "";
35         OnStart();
36         poiText.text = jo.Call<string>("GetPoi", "酒店", "", 1);
37     }
38 }
GetLocationAndPoiInfo

將腳本掛在任何一個物體上

布置界面

技術分享

因為是Android工程發布到手機(或模擬器)才能運行

上成果圖

技術分享

到這裏接高德地圖SDK的工作就做完了

根據手機朝向顯示不同店家的邏輯我就不寫了 挺麻煩的

我說一下思路:

在AndroidStudio中獲取各個店家的經緯度與自身坐標點的相對位置信息並輸出

在Unity中獲取到這個信息、解析、並轉換為角度、再轉換為匹配Input.compass指南針坐標系的角度

然後設置一個視野範圍(度數)

最後根據手機朝向顯示視野範圍內不同的店家

這麽做有什麽用處呢

做類似pokemon go這樣的東西時候這些信息就有用了

寫在最後:第一次公開寫博,如有不妥之處請多指教

Unity與Android交互-Unity接入高德地圖實現定位以及搜索周邊的功能(使用Android Studio)詳細操作