首先也是看到网上有很多这这方面的博客,但是安卓Studio高版本对接unity高版本的却很少,有的还说高版本报错,我也是花时间研究了一下,感觉报错是正常的,一般还是配置环境问题。至于高版本报错,就有点夸张了,但是有很多细节还是要注意的。
下面就为大家分享下我的心得。我尽量写的详细点。
Unity安卓Studio3.1.2版本交互调用高德地图信息
准备材料:
1.我的unity版本是2018.1.18 电脑是 win10系统(家庭版)
2.安卓Studio是AndroidStudio3.1.2/unity版本位2018.1.18
在这里安装教程我就不说 了。直接开始创建安卓工程。
这里全部默认就行了,点next。
这里默认也是默认就行。点击next。
选择图中所示Empty Activity。点击Next。
同样选择默认,点击Finish,等待2分钟会出现如下界面
创建Module:File =>new =>New Module
出现如下界面,选择Android Library。
点开如下图:
注意:这里的Package name:com.example.myLibrary 也就是unity 发布apk要对应的。如下图所示:
点击finish完成后,切换到project工程。
然后把unity jar包复制到libs文件里面:
放进去的时候会出现:
直接选择ok,如下图就完成了。
同样的方式把高德地图的jar包也放进来。如下图
然后选中这俩包,选择add as library
弹出页面选择OK,然后稍等片刻就完成了
完成后如下如:
接下来把他们添加依赖:点击file =>Project Structer
弹出页面选择myLibrary =>Dependencis
点击加号 选择jar dependency
弹出页面一次选择并且点击OK。
搞定之后,
把setContentView(R.layout.activity_main);删除,如上图,否则报错。
切换到安卓工程:找到自己library下的java里面的com.example.mylibrary,我的如下图。
安卓工程下如下图选择:
弹出的框选择默认:点击Finish
编辑类名,这个是用来和unity交互java文件,它和我们一开始创建就有的MainActivity不要搅浑。
这里也是我们要编辑的java脚本。别忘记把布局文件删除,这里我们用unity做,避免报错还是删除比较好。
这里细心的朋友应该发现我是俩工程,这个不用担心,因为5工程不小心删除了,用6重新做了,所有的都是一样的操作,也就是工程一模一样。
Unity jar包地址:
D:\UnityDownloadto\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
这里我们要注意:是mono\Release下的Classes,因为unity的jar包不止这一个。不要选错了如下图
因为安装的盘不同大家注意前面的对应盘,后面的基本都一样。
unity代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Getinto : MonoBehaviour
{ public Text locText;
public Text poiText;
public Button locBtn;
public Button poiBtn; AndroidJavaClass jc;
AndroidJavaObject jo; // Use this for initialization
void Start()
{
OnStart();
locBtn.onClick.AddListener(() => { GetLocationInfo(); });
poiBtn.onClick.AddListener(() => { GetPoiInfo(); });
}
void OnStart()
{
jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
} void GetLocationInfo()
{
locText.text = "";
OnStart();
locText.text = jo.Call<string>("GetInfo");
} void GetPoiInfo()
{
locText.text = "";
OnStart();
poiText.text = jo.Call<string>("GetPoi", "酒店", "", 1);
}
}
MainActivity.java脚本:
package com.example.mylibrary;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
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.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity
extends UnityPlayerActivity
implements PoiSearch.OnPoiSearchListener
{
public AMapLocationClient mLocationClient = null;
public AMapLocationClientOption mLocationOption = null;
private String LocationInfo;
private String strRerurnInfo;
private PoiSearch.Query query;
private PoiResult poir;
private double Latitude;
private double Longitude;
private boolean bolIsPoi = false;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
//获取定位信息
public String GetInfo()
{
startLocation();
this.bolIsPoi = true;
return this.LocationInfo;
}
//获取周边POI信息
public String GetPoi(String content, String val, int index)
{
startLocation();
search(content, val, index);
return this.strRerurnInfo;
}
protected void onStart()
{
super.onStart();
}
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(2000L);
this.mLocationClient.setLocationOption(this.mLocationOption);
this.mLocationClient.startLocation();
}
//三个参数分别为搜索字符串、搜索类型、查询第几页
//前两个参数选其一
//如:酒店、""、1
//第二个参数为poi搜索类型:
//汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|
// 医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|
// 交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施
public void search(String content, String val, int index)
{
if (this.bolIsPoi) {
if (content == null)
{
Toast.makeText(this, "输入为空", Toast.LENGTH_SHORT).show();
}
else
{
this.query = new PoiSearch.Query(content, val, "");
this.query.setPageSize(30);
this.query.setPageNum(index);
PoiSearch poiSearch = new PoiSearch(this, this.query);
if ((this.Latitude != 0.0D) && (this.Longitude != 0.0D))
{
poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(this.Latitude, this.Longitude), 6000));
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
}
else
{
Toast.makeText(this, "定位失败", Toast.LENGTH_SHORT).show();
}
}
}
}
public void onPoiSearched(PoiResult result, int code)
{
this.bolIsPoi = false;
System.out.println("Result" + (result.getPois().get(0)).getLatLonPoint());
System.out.println("Code" + code);
this.poir = result;
StringBuffer sb = new StringBuffer(256);
for (int j = 0; j < this.poir.getPois().size(); j++)
{
sb.append("\n名字:");
sb.append((this.poir.getPois().get(j)).getTitle());
sb.append("\n>地址:");
sb.append((this.poir.getPois().get(j)).getSnippet());
sb.append("\n>距离:");
sb.append((this.poir.getPois().get(j)).getDistance());
}
this.strRerurnInfo = sb.toString();
}
@Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
}
public AMapLocationListener mLocationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation location) {
if (location != null) {
if (location.getErrorCode() == 0) {
//获取坐标信息
Latitude = location.getLatitude();
Longitude = location.getLongitude();
StringBuffer sb = new StringBuffer(256);
sb.append("时间: " + location.getTime());
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());
sb.append("\n定位点AOI信息:" + location.getAoiName());
LocationInfo = sb.toString();
}else {
Log.e("AmapError","location Error, ErrCode:"
+ location.getErrorCode() + ", errInfo:"
+ location.getErrorInfo());
}
}
}
};
}
配置文件(unity修改):AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<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">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<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">
<meta-data
android:name="com.amap.api.v2.apikey" //这里的名字是固定的(复制的时候请删除注释,否则报错)
android:value="64c821ae174ab7429fa45535d01f20ae"/>//这个是自己申请的key值
<activity
android:label="@string/app_name" android:screenOrientation="fullSensor"
android:launchMode="singleTask"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale"
android:name="com.example.autlibrary.MainActivity">
<service android:name="com.amap.api.location.APSService" ></service>//使用定位功能
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="25" />
<uses-feature android:glEsVersion="0x00020000" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />//这些事手机获取权限
</manifest>
AndroidManifest
注意红色标记的内特容,package是对应unity的包名。
布置好后就可以打包了:
打包好后:如图查看,这里需要注意:安卓Studio3.1.2和其他版本不同,他的打包文件在packaged—里面,我们在里面找到libs和res拖进unity的Plugins\Android文件里面。
unity 发布成apk在手机上试试。
3.高德地图
首先要去高德地图开放平台注册一下。
进入控制台:
在应用管理获得自己key值:
SDK下载如下图
4.keystore 设置。
高德地图:
如上图 大家要只要简单记住:发布版本事安卓Studio里面的keyStore,调试是jdk自带的,也就是cmd中查找的。
如何生成Key值?
安卓Studio3.1.2:
按照网上的教程去做就行,因为简单就不写了。
如果你CMD中没有keyStore,可以输入:
keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000
可以重新生成一个Key值,别忘了 记住自己的密码。
以下是keytool的选项以供参考:
Keytool选项 | 描述 |
-genkey | 生成一个键对(公钥和密钥) |
-v | 日志输出 |
-keystore <keystore-name>.keystore | 命名包含密钥的keystore |
-storepass <password> | 设定keystore的密码。 基于安全考虑,不要在命令行中包含这一选项,除非你在一个安全的计算机上。如果你不提供,Keytool会提示你输入。这样,你的密码就不会储存在shell记录中了。 |
-alias <alias_name> | 设定key的别名 |
-keyalg <alg> | 指定生成key时使用的加密算法。支持DSA和RSA。 |
-dname <name> | 指定一个描述谁创建key的名字。该值将填入证书发行人的字段。 注意:你不需要在命令行中指明这些选项。如果不提供,Jarsigner会提示你输入每个字段(CN,OU等)。 |
-validity <valdays> | Key的有效期,天数。 注意:推荐使用10000或更大的数。 |
-keypass <password> | Key的密码。 基于安全考虑,不要在命令行中包含这一选项,除非你在一个安全的计算机上。如果你不提供,Keytool会提示你输入。这样,你的密码就不会储存在shell记录中了。 |
效果图:
显示不是很完美,可能是免费版的而且只有部分地区能显示。有待研究。