unity打包成apk中会有一个Mainactivity,当引入Androidstudio打包出来的aar包时,其aar包这边的设置会高于unity playSetting里面的设置,也就是unity playSetting设置的横竖屏/Icon/应用名等都是无效的
1.创建Android工程,File - new - Model - Android Library
2.模块中创建一个MainActivity,记得勾选Lanch Activity
3.删除布局文件,并注释setContentView(R.layout.activity_bomb);
4.导入unity classes
路径:C:\Program Files\unity2017.3\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
把classes.jar copy到libs文件夹下,然后右键点击Add As Library等待编译完成就是右图所示,点击可以打开看到里面的类
5.查看模块中的AndroidManifest,如果是这种简单的,就要从.app中的AndroidManifest复制过来并修改
6.Activity继承自UnityPlayerActivity并添加要让unity那边调用的方法
7.点击Model-build - make Module
等待build完成后切换成project视图找到aar包:
用压缩软件打开,进行如下两步操作:
①.将libs中的classes.jar删除即可,将AndroidManifest.xml放入Plugins/Android中
②.将aar包中的android:icon android:label两行删除,因为会与unity中的androidmanifest.xml这两行冲突
将修改后的aar包放入unity Plugins/Android目录下:
新建场景,创建一个Text文本,新建test.cs:
using UnityEngine;
using UnityEngine.UI;
public class test : MonoBehaviour {
public Text text;
// Use this for initialization
void Start () {
text = GetComponent<Text>();
//获得位于com.unity3d.player包下的UnityPlayer类
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
//获得jc所代表的类下的currentActivity对象
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
text.text = jo.Call<int>("add", 1, 2).ToString();
}
// Update is called once per frame
void Update () {
}
public void changeColor()
{
text.color = Color.red;//将Text的颜色改成红色
}
}
运行后:text文本的值由aaa变成了3,且变成红色,通信成功
补充知识点:
- 如果Android那边的类不需要访问资源只需纯代码就可以完成的时候可以用下面方法调用:
AndroidJavaObject jo = new AndroidJavaObject("包名.类名");//入伏哦构造函数需要参数可以后面传参数
再用jo调用方法,此时unity这边也不需要Android manifest,只需要aar包即可
- 当调用的方法是静态方法时:
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
text.text = jc.CallStatic<int>("add", 1, 2).ToString();
- unity不接入Android,调用Android SDK中的方法:
①.先找到你要调用的方法定义的地方(以Log.e为例):
在Android studio中写下你要调用的方法:
Log.e("unity", "errorTest");
②.Ctrl+鼠标点击Log进入该类,可以看到该类所在的包(也就是路径):
③.unity代码:
AndroidJavaClass jc = new AndroidJavaClass("包名.类名");
jc.CallStatic<int>("方法名","参数列表");
以下是调用Android Toast方法:
Android原生调用方法:
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(BombActivity.this, "DebugTest", Toast.LENGTH_SHORT).show();
}
});
Unity调用Android SDK:
public static void showAsToast(this string text, AndroidJavaObject activity = null)
{
Debug.Log(text);
if (activity == null)
{
AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
activity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
}
AndroidJavaClass Toast = new AndroidJavaClass("android.widget.Toast");
AndroidJavaObject context = activity.Call<AndroidJavaObject>("getApplicationContext");
activity.Call("runOnUiThread", new AndroidJavaRunnable(() => {
AndroidJavaObject javaString = new AndroidJavaObject("java.lang.String", text);
Toast.CallStatic<AndroidJavaObject>("makeText", context, javaString, Toast.GetStatic<int>("LENGTH_SHORT")).Call("show");
}
));
}
public static AndroidJavaObject toJavaString(this string CSharpString)
{
return new AndroidJavaObject("java.lang.String", CSharpString);
}
以下是调用Android日历方法:
Android原生调用方法:
new DatePickerDialog(BombActivity.this,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
}
}
, 2018, 1, 22).show();
Unity调用Android SDK:
using System;
using UnityEngine;
using UnityEngine.UI;
public class test : MonoBehaviour {
public static Text text;
private DateTime selectTime = DateTime.Now;
public class DataCallBack : AndroidJavaProxy //模拟接口
{
public DataCallBack() : base("android.widget.DatePicker.OnDateChangedListener") { }//"传递的是该接口所在的路径"
//实现这个接口里面的方法
void onDateSet(AndroidJavaObject view, int year, int month, int dayOfMonth) //当遇到Android中的类时可以用AndroidJavaObject来代替
{
//点击后响应的方法
text.text = year + "/" + (month + 1) + "/" + dayOfMonth;
}
}
// Use this for initialization
void Start () {
text = GetComponent<Text>();
AndroidJavaObject currentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
new AndroidJavaObject("android.widget.DatePicker", currentActivity,new DataCallBack(), selectTime.Year,selectTime.Month-1,selectTime.Day).Call("Show"); //当一个类里面包含接口时需要一个内部类就是上面的DataCallBack
}));
}
// Update is called once per frame
void Update () {
}
}
④.设置项目不打包成apk而是生成aar包
applicationId :
最近做了一个Android手机蓝牙与硬件交互,搞得心力憔悴,补充一下坑
1.Androidstudio打aar包是不会将第三方库包含进去的,也就是说如果你的项目使用了第三方库,打包到unity可能会出现类似的错误:
解决方案: 将依赖库都拷贝到Plugins/Android目录下
拷贝完成unity视图:
注意拷贝的时候不能将以下包拷贝过去:
2.Android程序安装完出现了两个图标
程序安装完出现了两个AP图标,AndroidManifest.xml中一定是有两个
<category
android:name="android.intent.category.LAUNCHER"
/>
解决办法:
去掉次要activity中的这一行, 次要的(不是程序运行的第一个activity)的,程序运行的第一个activity里面的这句要保留.
但是如果app有依赖,那么依赖里的launcher也要去掉
3.Android创建子线程和回调主线程的几种方式