文档章节

Unity3d调用Android的Toast方法

DA_kotori
 DA_kotori
发布于 2016/12/01 11:03
字数 1537
阅读 523
收藏 5

由于我刚刚学习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");
	}
}

 

© 著作权归作者所有

DA_kotori
粉丝 2
博文 3
码字总数 2228
作品 0
杭州
Android工程师
私信 提问
加载中

评论(1)

岳希波
学习。。
Unity加入Android广告小结

在Unity游戏加入广告大致有以下几种方式: 导入Android Jar包 导出游戏为Android项目(在Build时选中Google Android Project,这种方法可以参考将Unity3D游戏移植到Android平台上) 使用Uni...

andong777
09/29
0
0
Unity导入Android后,Android传递消息让Unity实现ShareREC进行录像录像方法不执行。

我的项目是使用ShareREC让Unity进行录像,直接使用Unity录像是可以录像的。但当我讲Unity项目导入Android之后,利用Unity与Android的交互,当Android点击按钮的时候发送消息给Unity让其进行录...

张无影
2016/12/02
301
0
Unity 3D与Android Studio安卓交互之-导出jar包

u3d与安卓 jar 包交互 Chinar 教程效果: import android.support.v7.app.AppCompatActivity;import android.os.Bundle; import com.unity3d.player.UnityPlayer;import com.unity3d.player.......

chinar-yunxi
2018/04/12
0
0
Android Studio安卓导出aar包与Unity 3D交互

Unity与安卓aar 包交互 Chinar 教程效果: import android.support.v7.app.AppCompatActivity;import android.os.Bundle; import com.unity3d.player.UnityPlayer;import com.unity3d.playe......

chinar-yunxi
2018/04/19
0
0
[Unity3D]Unity+Android交互教程——让手机"动"起来

想要用Unity实现一个二维码扫描的功能,然后网上找插件,找到一个貌似叫EasyCodeScanner,但下载下来用用,真不好使,一导入运行就报错,调好错了再运行发现点按钮没反应,反复试了几遍发现还...

丁小未
2014/04/26
17K
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 如果是个帅小伙你愿意和他出去吗

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《Ghost 》游戏《死亡搁浅》原声 《Ghost 》游戏(《死亡搁浅》原声) - Au/Ra / Alan Walker 手机党少年们想听歌,请使劲儿戳...

小小编辑
42分钟前
67
5
java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部