Unity3d调用Android的Toast方法

由于我刚刚学习Unity3d,所以打算写一款手游,但在账号密码输入界面,我发现了一个问题,当用户点击登陆时,如果输入框没值,那么我想告诉用户你必须要输入值,这在android中很常见,因为Android只需要一行代码即可完成

Toast.makeText(getApplicationContext(), "is Toast",Toast.LENGTH_SHORT).show();

但是当我天真的去翻Unity时并没有找到相应的c#代码。

所以我疯狂的百度博客,有不少博客也写到了Unity和Android之间互相调用,但是我尝试了很多博客,发现这些博客总共就2种方法,

第一种:将android代码打包成jar,arr文件放到Unity工程。

第二种将Unity工程导成Android项目在做修改。

但这两种方法无疑都是很麻烦的,在我尝试的过程中发生了大量问题,我足足修改了2天,才将arr文件顺利打包进unity的apk文件,但是使用过程中我发现android报错了,通过翻遍apk的源码,我发现这个错误是说Jni找不到你定义的方法,通过Log的查询我发现它在UnityActivity中寻找,而这个类中是并没有存在这个方法的,为此我想了好久,不断的测试,都没找到方法。

为此我询问了我朋友,他和我一起寻找,终于在GitHub上找到了一个解决方法,其实我们不需要去定义jar包或者arr文件,因为当unity打包的时候会自动导入andorid类,并且将c#代码转换成java代码

因此我们只要通过Unity定义的方法获取android的类,进行方法调用即可,不需要自己去开个android项目

接下来,我会将代码和网站放上来,帮助和我一样踩坑的人

网站:https://github.com/mtsalenc/toaster

Unity脚本代码

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ShowToast : MonoBehaviour {
	string toastString;
	string input;
	AndroidJavaObject currentActivity;
	AndroidJavaClass UnityPlayer;
	AndroidJavaObject context; 
	// Use this for initialization
	void Start () {
		if (Application.platform == RuntimePlatform.Android) {
			UnityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
			currentActivity = UnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity");
			context = currentActivity.Call<AndroidJavaObject> ("getApplicationContext");
		}
	}
	public void ToAndroidClipBoard(string s){
		//InputField txtField){
		if (Application.platform == RuntimePlatform.Android) {
			//input = txtField.text;
			input=s;
			currentActivity.Call("runOnUiThread",new AndroidJavaRunnable(toClipBoardOnUiThread));
		}
	}
	void toClipBoardOnUiThread(){
		AndroidJavaClass Context = new AndroidJavaClass ("android.content.Context");
		AndroidJavaObject CLIPBOARD_SERVICE = Context.GetStatic<AndroidJavaObject> ("CLIPBOARD_SERVICE");
		AndroidJavaObject clipboardMgr = currentActivity.Call<AndroidJavaObject> ("getSystemService", CLIPBOARD_SERVICE);
		AndroidJavaClass ClipData = new AndroidJavaClass ("android.content.ClipData");
		AndroidJavaObject clipData = ClipData.CallStatic<AndroidJavaObject> ("newPlainText", "deltaBit", input);
		clipboardMgr.Call ("setPrimaryClip", clipData);

		showToastOnUiThread ("Copied to clipboard:" + input);
	}

	void showToastOnUiThread(string toastString){
		this.toastString = toastString;
		currentActivity.Call ("runOnUiThread", new AndroidJavaRunnable (showToast));
	}
	void showToast(){
		AndroidJavaClass Toast = new AndroidJavaClass ("android.widget.Toast");
		AndroidJavaObject javaString = new AndroidJavaObject ("java.lang.String", toastString);
		AndroidJavaObject toast = Toast.CallStatic<AndroidJavaObject> ("makeText", context, javaString, Toast.GetStatic<int> ("LENGTH_SHORT"));
		toast.Call ("show");
	}
}

在使用过程中,只需要将脚本挂载在一个GameObject中,然后直接调用ToAndroidClipBoard方法即可弹出土司

随后我仔细的查看了代码,接下来我会进行分析代码,当然 AndroidJavaClass,GetStatic,Call这个我就不讲了,这个从外貌就能知道意思

首先

if (Application.platform == RuntimePlatform.Android) {
			UnityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
			currentActivity = UnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity");
			context = currentActivity.Call<AndroidJavaObject> ("getApplicationContext");
		}

这块代码我就不说了,如果你导出过Android工程的话,就会对里面的东西有所了解,当然,没看过也没关系,我简单讲解一下,首先UnityPlayer就是你游戏主要的东西,在Android代码中,它会写成这样

UnityPlayer player=new UnityPler();
setContentView(player);

如果对android代码不清楚的同学,也可以百度一下,setContentView就是设置界面

currentActivity:这个东西我大概估计了一下,应该是获取当前显示的Activity.

不懂得人可能会问Activity是什么,这个我简单讲解一下,Activity是Android的一个最重要的东西,简单来说你见到的每一个界面都是运行在Activity上

Context :在Android中叫做上下文,Context你可以把他想象成一个大环境,只有在再这个环境下我们才能读取资源等等,在这里我不细说了,感兴趣的可以去看看android编程

public void ToAndroidClipBoard(string s){
		if (Application.platform == RuntimePlatform.Android) {
			input=s;
			//runOnUiThread是让后面的方法运行在主线程,这一点也是Android的知识,在Android中像土司这样的东西必须要在主线程调用,
			//否则会报异常,这一点希望各位能够记住
			currentActivity.Call("runOnUiThread",new AndroidJavaRunnable(toClipBoardOnUiThread));
		}
	}

随后它会调用toClipBoardOnUiThread()方法,这个方法是将String字符串添加到剪贴板中,具体的我就不说了,毕竟我们主要是Toast,而这个的android的代码我也会贴出来

void toClipBoardOnUiThread(){
		AndroidJavaClass Context = new AndroidJavaClass ("android.content.Context");
		AndroidJavaObject CLIPBOARD_SERVICE = Context.GetStatic<AndroidJavaObject> ("CLIPBOARD_SERVICE");
		//得到剪贴板管理器的对象
		AndroidJavaObject clipboardMgr = currentActivity.Call<AndroidJavaObject> ("getSystemService", CLIPBOARD_SERVICE);

		AndroidJavaClass ClipData = new AndroidJavaClass ("android.content.ClipData");
		AndroidJavaObject clipData = ClipData.CallStatic<AndroidJavaObject> ("newPlainText", "deltaBit", input);
		clipboardMgr.Call ("setPrimaryClip", clipData);

		showToastOnUiThread ("Copied to clipboard:" + input);
	}

Android:

public void toClipBoardOnUiThread(String input){
        ClipboardManager  systemService = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
        ClipData data=ClipData.newPlainText("deltaBit",input);
        systemService.setPrimaryClip(data);
    }

最后就到我们的土司阶段了

void showToastOnUiThread(string toastString){
		this.toastString = toastString;
		currentActivity.Call ("runOnUiThread", new AndroidJavaRunnable (showToast));
	}
	void showToast(){
		AndroidJavaClass Toast = new AndroidJavaClass ("android.widget.Toast");
		AndroidJavaObject javaString = new AndroidJavaObject ("java.lang.String", toastString);
		AndroidJavaObject toast = Toast.CallStatic<AndroidJavaObject> ("makeText", context, javaString, Toast.GetStatic<int> ("LENGTH_SHORT"));
		toast.Call ("show");
	}

首先还是runOnUiThread,调用showToast方法

随后通过AndroidJavaClass得到Toast类,通过AndroidJavaObject获取JavaString对象,随后通过CallStatic静态调用Toast中的静态方法makeText,将context,string,"LENGTH_SHORT"传进去,第三个参数是Toast类定义的int静态值,对应的是Toast显示的长度,当然你也可以直接传进0或者1,最后,用toast类调用show方法即可显示

Android代码就是我上面写的那句代码

所以下面我将那个类修改了一下,这个类就是单纯弹土司的类,需要的可以直接粘贴

using UnityEngine;
using System.Collections;

public class Toast : MonoBehaviour {
	string data;//Toast要显示的数据
	AndroidJavaObject currentActivity;
	AndroidJavaClass UnityPlayer;
	AndroidJavaObject context; 
	// Use this for initialization
	void Start () {
		if (Application.platform == RuntimePlatform.Android) {
			UnityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
			currentActivity = UnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity");
			context = currentActivity.Call<AndroidJavaObject> ("getApplicationContext");
		}
	}
	public void SetToast(string data){
		if (Application.platform == RuntimePlatform.Android) {
			this.data = data;
			currentActivity.Call("runOnUiThread",new AndroidJavaRunnable(ShowToast));
		}
	}
	void ShowToast(){
		AndroidJavaClass Toast = new AndroidJavaClass ("android.widget.Toast");
		AndroidJavaObject javaString = new AndroidJavaObject ("java.lang.String", data);
		AndroidJavaObject toast = Toast.CallStatic<AndroidJavaObject> ("makeText", context, javaString, Toast.GetStatic<int> ("LENGTH_SHORT"));
		toast.Call ("show");
	}
}

 

转载于:https://my.oschina.net/niaoxiaoniaoDA/blog/797707

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值