先在Android端实现定位功能,再打包成JAR文件提供接口方法给Unity调用。
Unity3D (5.3.4)
Eclipse: Neon(4.6.0)
Unity提供了跟Android交互的接口,可以参考雨松大大的博客。
1.首先新建一个Android工程,在最小SDK版本里选4.0以上,不然在Unity打包的时候会报错。
2.创建出来的工程目录如下:
3.可以删掉MainActivity里面不必要的代码,引用的布局也要删掉:
package com.example.locationtest;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
4.因为要调用Unity提供的接口,需要把Unity提供的JAR库classes.jar文件导入到我们的安卓工程里。我的Unity版本是5.3.4,文件在这里:
5.把库文件拖到Android工程的libs文件夹下面,右键选Build Path ->Add to Build Path导入包。
6.Activity中的方法想要被Unity调用,这个Activity就需要继承UnityPlayerActivity,这是Unity提供的包里面的接口类。代码里写了一个GetInfo()的方法给Unity在代码中调用,获取定位的信息LocationInfo。
package com.example.locationtest;
import android.os.Bundle;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity extends UnityPlayerActivity {
private String LocationInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public String GetInfo(){
return LocationInfo;
}
}
7.接下来就是实现高德地图中的定位功能了,这方面的内容可以参考官网的文档,还是很容易实现的,这里就不详述了。我的代码如下:
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.locationtest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE">uses-permission>
<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>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name="com.amap.api.location.APSService">service>
<activity
android:name=".MainActivity"
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="ac239bfa4a6067c16fe5d1bc32347f83">
meta-data>
application>
manifest>
MainActivity.Java:
package com.example.gdloctest;
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.AMapLocationClientOption.AMapLocationMode;
import com.amap.api.location.AMapLocationListener;
import com.unity3d.player.UnityPlayerActivity;;
public class MainActivity extends UnityPlayerActivity {
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明AMapLocationClientOption对象
public AMapLocationClientOption mLocationOption = null;
//定位回调字符串
private String LocationInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public String GetInfo(){
startLocation();
return LocationInfo;
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
private void startLocation(){
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);
//初始化AMapLocationClientOption对象
mLocationOption = new AMapLocationClientOption();
//设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
//设置定位间隔,单位毫秒,默认为2000ms,最低1000ms。
mLocationOption.setInterval(2000);
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
}
public AMapLocationListener mLocationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation location) {
// TODO Auto-generated method stub
if (location != null) {
if (location.getErrorCode() == 0) {
StringBuffer sb = new StringBuffer(256);
sb.append("时间: ");
sb.append(location.getTime());
sb.append("\n纬度:");
sb.append(location.getLatitude());
sb.append("\n纬度:");
sb.append(location.getLongitude());
sb.append("\n精度:");
sb.append(location.getAccuracy());
sb.append("\n地址:");
sb.append(location.getAddress());
sb.append("\n国家信息:");
sb.append(location.getCountry());
sb.append("\n省信息:");
sb.append(location.getProvince());
sb.append("\n城市信息:");
sb.append(location.getCity());
sb.append("\n城区信息:");
sb.append(location.getDistrict());
sb.append("\n街道信息:");
sb.append(location.getStreet());
sb.append("\n街道门牌号信息:");
sb.append(location.getStreetNum());
sb.append("\n城市编码:");
sb.append(location.getCityCode());
sb.append("\n地区编码:");
sb.append(location.getAdCode());
sb.append("\n定位点AOI信息:");
sb.append(location.getAoiName());
LocationInfo = sb.toString();
}else {
//定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
Log.e("AmapError","location Error, ErrCode:"
+ location.getErrorCode() + ", errInfo:"
+ location.getErrorInfo());
}
}
}
};
}
8.接下来就可以打包成JAR文件给Unity调用了。选中我们的工程文件夹,可以先点击工具栏的Project->clean,再Project->Build Project。然后右键Export,选导出为JAR文件,点击Next,在下一个窗口中展开工程目录,只需要导出src这个文件夹就可以了。点击Finish,导出JAR文件…
9.将安卓工程的文件拷贝到Unity工程的Plugins->Android文件夹里。没有这个目录的话需要自己创建一个。文件夹目录如下,把我们刚刚导出的JAR文件放在的bin文件夹中,另外还需要把我们的安卓工程目录里把libs文件夹和res文件夹以及AndroidManifest文件拷贝进去,注意拷贝完要把libs文件夹里面的classes.jar文件删掉,不然文件会冲突:
10.接着就可以在Unity中调用了。注意Unity中的包名要和Android工程里的保持一致,否则会无法调用。我们新建一个简单的场景,添加一个Text和Button控件,在我们点击Button的时候,Text就会显示获取到的定位信息。
11.新建一个脚本,挂载在摄像机上面:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class GetLocationInfo : MonoBehaviour {
public Text text;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void StartLocation() {
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic("currentActivity");
text.text = jo.Call<string>("GetInfo");
}
}
在StartLocation()方法中通过jo.Call<返回值类型>(“方法名”)的方式调用了我们在Android工程里面提供的GetInfo方法。让Button的点击事件执行StartLocation()这个方法,即可获取定位信息。
用模拟器测试有些信息好像获取不到,但是真机测试是没问题的…