最近需要接入SDK,现整理在安卓端接入SDK的过程。
接入SDK的整体过程可以概括为两步:
1.在安卓端编写class并生成目标jar包
2.把该jar包导入unity,然后在C#中调用即可
首先第一步,在安卓端编写class并生成jar包:
1.下载安装eclipse并配置相关环境:
直接在官网下载对应的eclipse版本即可:Eclipse Downloads | The Eclipse Foundation
注意:直接下载安装的eclipse是没有安卓ADT套件的,此时无法新建Android项目,也无法配置sdk路径,所以需要先安装ADT套件 —— (文末会放出需要的工具链接)
1)安装ADT套件:
* 在线安装ADT:
菜单栏:Help ->Install new software -> Add
填入以下URL地址:https://dl-ssl.google.com/android/eclipse/
之后一路next安装完成即可
*离线安装ADT:
PS:推荐一个很好用的安卓工具网站:AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载
1.在上面的网站中下载ADT Plugin: 这里下载“ADT-23.0.6”
2.在eclipse中导入该zip包(注意下载之后的ADT不需要解压,可以直接在eclipse中导入使用)
菜单栏:Windows-》install new software
在“Archive”中选择刚才下载的“ADT-23.0.6.zip”文件即可。一路点击next,finish后开始安装,注意这里安装需要一点时间,右下角会显示安装进度
当安装完成后会提示重启eclipse
重启后在windows菜单栏下就可以看到“SDK Manager”选项了
2)在eclipse中配置 android sdk路径:
*1.同样在以上网站中下载SKT Tools:
选择Windows平台的zip压缩包
下载完成后解压得到:
*2.然后在eclipse中配置安卓SDK路径:
选择菜单栏“Window -》Preferences”:
点击下方的“Apply”,会弹出提示框:
*3.点击“Open SDK Manager”,更新SDK
系统会自动选择这四个文件:
先点击下方的“Install”安装这几个文件:
*4.选择目标API下载:
针对本项目,这里使用的是“android-20”,所以只下载对应的API-20以及对应的SDK Build-tools即可:
下载完成之后:
如此eclipse中安卓环境就搭建完成了
注意:
1.使用的SDK 路径最好不要有中文,不然可能会出现一些意想不到的问题
2.ADT的版本“ADT 23.0.6” 和 SDK Manager面板中“SDK Build tools”的版本是不一样的,“SDK Build tools”中显示的"Build tools"是与API 版本对应的“Build tools”,与ADT 无关。
使用在线模式:https://dl-ssl.google.com/android/eclipse/ 下载安装的ADT工具包当前最新版本为“23.0.7”。查看eclipse的ADT版本方式:菜单栏Help - > about Eclipse IDE
选中右侧最后一个即可查看ADT版本:
2.新建Android项目:
菜单栏:“New ->Other...”
设置package name和该项目的sdk版本,勾选“Mark this project as a library”,之后一路点击“Next”,项目创建成功
在该项目中导入Unity的class.jar:该class.jar作为安卓和Unity之间相互通信的桥梁。
文件路径:该文件通常在Unity的安装路径下,下面以Unity2018.4版本为例:
由于在Unity中打包时"scripting Backend”默认使用的是“Mono”,因此这里选择“Mono”文件夹下的“Classes.jar",路径为:
C:Program FilesUnityHubEditor2018.4.36f1EditorDataPlaybackEnginesAndroidPlayerVariationsmonoReleaseClassesClasses.jar
如果"scripting Backend"使用的是“IL2CPP",则选择“il2cpp”文件夹下的“Classes.jar”即可
* 将该“classes.jar”拖到安卓项目的“libs”文件夹下(如果新建的工程中没有libs文件夹,则新建一个)
之后选中该“classes.jar”,鼠标右键“Build Path -> Add to build path":
3.编写Android端相关代码:
1)在“MainActivity.java”中继承“UnityPlayerActivity”(需要“import com.unity3d.player.UnityPlayerActivity;”)
2)注释掉“setContentView(R.layout.activity_main);”:
3)然后在“MainActivity.java”中编写几个Unity和Android之间相互调用的方法:
//android中的方法,在Unity中调用该方法
public int Sum(int x, int y) {
return x + y;
}
//android中的方法,首先被Unity调用,然后向Unity传递消息 —— 通过调用Unity中的方法来传递消息
public void CallUnityFunc(String str){
str = str + "2.Yes, it is. -- from android_call_unity";
String ReceiveObject = "GameManager";
String ReceiverMethod="RefreshLabel";
UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
}
从安卓端调用Unity中C#代码的方式:UnityPlayer.UnitySendMessage(Obj, Method, str)
表示向当前scene场景中GameObject名字为“Obj”的对象发送消息,该"Obj“对象上所有挂载的脚本且处于"Enabled”状态的,如果这些脚本中有命名为“Method”的方法则会被执行,“str”代表从安卓传递给Unity的参数。
1.在运行过程中会自动查找当前场景中是否有命名为“Obj”的GameObject,如果没有则从安卓向Unity传递消息失败。
2.如果包含有"Method"方法的脚本挂载在"Obj“对象上,但该脚本处于"SetActive(false)"状态,则消息传递也是失败的
如上图,当包含有"RefreshLabel"方法的“GameMgr”脚本处于false状态,则消息传递依然失败
MainActivity.java完整代码如下:
package com.frank.sdktest;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
//android中的方法,在Unity中调用该方法
public int Sum(int x, int y) {
return x + y;
}
//android中的方法,首先被Unity调用,然后向Unity传递消息 —— 通过调用Unity中的方法来传递消息
public void CallUnityFunc(String str){
str = str + "2.Yes, it is. -- from android_call_unity";
String ReceiveObject = "GameManager";
String ReceiverMethod="RefreshLabel";
UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
}
}
4)从项目中导出jar包以供Unity调用:
选中项目,右键选择“Export”
选择“src”,“res”两个文件夹,并设置导出jar包的路径即可
如此Android端的操作就完成了。
PS:可能遇到的问题
1.eclipse项目左下角有时候会出现“!”或者“x”,此时可能是由于项目使用的jdk与软件配置的jdk不一致导致的
解决办法:选中项目,右键:
2.项目下方的“Problems”中可能出现:
解决办法:菜单栏“Project ——》Clean”
3.新建Android项目后有时会出现:
解决办法:试过很多方法后发现是Android SDK路径中包含有中文,改成英文即可
4.问题:
解决办法:
选中该提示打开对应的文件,在该xml文件中加入以下代码:
完整代码如下:
第二步:在Unity端导入刚才生成的jar包,并编写C#调用代码:
1.在Unity端导入之前生成的jar包:
首先在Unity端新建项目工程,在Assets目录下新建“Plugins/Android”,将之前生成的jar导入该路径,同时将上面Android工程下的“libs”、“res”文件夹和“AndroidMainfest.xml”文件放入同一路径下
注意:删除“libs”文件夹下的“classes.jar”,不然Unity5.x以上版本打包时会报错。这个“classes.jar"就是之前导入android项目中的起到Unity与android之间相互调用桥梁作用的jar包。这里由于在Unity打包时选择"scripting Backend”会自动调用该classes.jar,所以这里不需要该jar
2.编写Unity和Android交互代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameMgr : MonoBehaviour
{
private AndroidJavaClass _jc;
private AndroidJavaObject _jo;
public Text unityCallAndroidLabel;
public Text unityAndAndroidLabel;
void Start()
{
_jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
_jo = _jc.GetStatic("currentActivity");
unityCallAndroidLabel.text = "Sum: " + _jo.Call("Sum", 2, 3);
_jo.Call("CallUnityFunc", "1.Hello, today is a good day. -- from unity_call_android n");
}
public void RefreshLabel(string str)
{
unityAndAndroidLabel.text = str;
}
}
PS: AndroidJavaObject调用变量和方法的方式:
Call //调用AndroidJavaObject代码中的非static方法 CallStatic //调用AndroidJavaObject代码中的static方法 Get //获取AndroidJavaObject中的非static变量 GetStatic //获取AndroidJavaObject中的static变量 Set //设置AndroidJavaObject中的非static变量 SetStatic //设置AndroidJavaObject中的static变量
3.打包安卓apk:
注意:通常情况编写完成后我们会习惯在Unity中运行下看看效果,但此项目中由于会调用Android代码,因此直接运行是会报错的。需要打包成apk后运行在模拟器或者手机上才能看到效果
1)设置包名:
设置包名与Android项目的package name一致,并设置API level
2)设置Android SDK 以及NDK:
* 将eclipse项目中使用的SDK拷贝一份,把拷贝后的SDK路径设置为Unity打包的Android sdk路径
原因:Unity在打包apk时会对SDK进行更新,关键是由于eclipse版本等问题,更新之后的sdk无法用于eclipse开发安卓项目,因此需要把SDK分开进行使用
*NDK:点击“Download”即会自动下载ndk压缩包,下载完成后解压并设置路径即可:
PS:"NDK“文件可以直接点击上面的“Download"下载,不需要找别的链接先下载好
3)开始打包:
打包时会提示更新"SDKTools”,点击“Update Android SDK”即可 —— 直接线上更新"SDKTools"需要网络可以连上google才可以
这里更新会花很长时间,耐心等待........
当出现如下弹窗时则代表快要更新完成了:
点击“Update”。当SDK更新完了之后则会自动开始打包。
打包完成:
PS:Unity中打包安卓apk时使用的"Android sdk"要和eclipse项目中使用的"Android sdk”两个路径分开。因为在Unity中打包apk时会对sdk进行更新,但关键是更新之后的sdk在eclipse中已不再适用,会报下面的错误:
在eclipse中点击“Open SDK Manager"后依然无法打开"sdk manager“窗口
因此解决办法就是将eclipse项目中使用到的"SDK"复制一份,然后将副本作为Unity中使用的sdk路径,Unity在打包apk时会对副本中的sdk更新,但不会影响eclipse中用到的sdk原件。如此两个项目都可以正常运行。
4)运行效果:
将打包出来的apk安装到手机上得到效果:
如此Unity接入SDK的安卓端 —— 基础篇就已经完成了。
以上是Unity中接入SDK的基础篇,后面会接入实际的科大讯飞语音SDK内容。
PS:
Eclipse中使用到的工具:EclipseTools.zip-Unity3D文档类资源-CSDN下载
Unity打包apk时用到的SDK:https://download.csdn.net/download/m0_47975736/33240932
NDK: https://download.csdn.net/download/m0_47975736/33254055
Unity和Eclipse端的项目源码:https://download.csdn.net/download/m0_47975736/33240308



