Unity功能记录(五)------ Android studio打包aar包后与unity互相通信

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 () {
		
	}
}




















猜你喜欢

转载自blog.csdn.net/dengshunhao/article/details/80595420