Unity3D 呼叫Android與IOS的剪貼簿
Unity3D剪貼簿
最近遇到一個需要呼叫Android與IOS裝置本身剪貼簿的需求,就是在Unity中,要將文字複製到裝置本身的剪貼簿中,然後在其他應用程式中都能貼上。
最開始在網上查到的方式是使用Unity3D本身自帶的TextEditor 類進行使用,使用方法如下:
TextEditor te = new TextEditor();
te.content = new GUIContent(yourText);
te.OnFocus();
te.Copy();
期初在電腦上測試時是可以用的,然而這種到了Android和IOS裝置上卻坑了……完全沒反應T_T。在多方查詢之下,終無結果,所以能想到的方法就是在Unity中使用C#呼叫Android和IOS自身的介面分別實現。
ClipboardManager cm =(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
//複製到剪貼簿
cm.setText(message);
//從剪貼簿獲取文字
string text = cm.getText();
針對Android和IOS雙平臺
博主在踩了眾多的坑之後,終於將Android和IOS分別實現,於是通過這個剪貼簿例子到這裡來跟大家分享一下Unity3D呼叫Android和IOS的一些簡單的方法。
Unity3D呼叫Android剪貼簿
public class ClipboardTools {
public static ClipboardManager clipboard = null;
// 向剪貼簿中新增文字
public void copyTextToClipboard(final Context activity, final String str) throws Exception {
clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE);
ClipData textCd = ClipData.newPlainText("data" , str);
clipboard.setPrimaryClip(textCd);
}
// 從剪貼簿中獲取文字
public String getTextFromClipboard() {
if (clipboard != null && clipboard.hasPrimaryClip()
&& clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
ClipData cdText = clipboard.getPrimaryClip();
ClipData.Item item = cdText.getItemAt(0);
return item.getText().toString();
}
return "null";
}
}
Android複製
首先,Android剪貼簿的使用要通過從Activity中獲取ClipboardManager 服務,然後才能進行使用。在這裡我們先定義了一個靜態的ClipboardManager 引用:
public static ClipboardManager clipboard = null;
原因是當Unity3D對Android類(ClipboardTools)的方法掉用完後,可能會被垃圾回收,所以將ClipboardManager 定義為靜態才能通過getTextFromClipboard()方法獲取先前存入剪貼簿的文字。
對Android剪貼簿類ClipboardManager 的使用是固定的用法。
Android貼上
做好了複製,貼上模組就比較簡單了,固定的模式,博主在此處添加了一些 if 的邏輯判斷,是對剪貼簿中內容進行判斷,如:是否為文字,是否有內容等……但要注意的是,若沒有將ClipboardManager 設為靜態,則在呼叫完複製方法時,ClipboardTools類可能會被垃圾回收,那麼ClipboardManager 的引用會變為null,從新獲取不太方便,所以博主就將其設為靜態了。
Android剪貼簿專案匯入Unity3D
在Unity3D中呼叫Android的東西,首先要在Unity3D專案中建立好環境:
1. 在Untiy3D專案的Assets目錄下建立Plugins目錄。
2. 在Plugins目錄下建立Android目錄。
3. 在Android 目錄下建立bin目錄。
4. 在bin 目錄下放置你編寫的類的jar包。
前三步都是建立資料夾就沒什麼好說了,從第四步開始,這裡所說的Jar包僅僅是你所寫的那個類的jar包,並非整個Android專案的jar包,使用Eclipse編寫的同學可以在???中將Is Library勾上,就可以直接在Android專案下的bin資料夾下找到打好的Jar包。
第五步所說的Unity3D的 classes.jar 包,在你的Unity3D安裝目錄下的Editor\Data\PlaybackEngines\androidplayer\development\bin 目錄下,直接將其複製到你的Unity3D專案的bin 目錄下即可。
注:有些朋友可能進行了第五步後會出現Unity報錯,這時可以先不進行第五步看看能不能搞定,原因可能是因為配置問題,還待校驗……
Unity3D呼叫Android類與方法
在Unity3D中對Android類與方法的呼叫方法程式碼如下:
#if UNITY_ANDROID
AndroidJavaObject androidObject = new AndroidJavaObject("com.test.ClipboardTools");
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
if (activity == null)
return ;
// 複製到剪貼簿
androidObject.Call("copyTextToClipboard", activity, input);
// 從剪貼簿中獲取文字
String text =androidObject.Call<String>("getTextFromClipboard");
#endif
首先,或取出先前編寫的Android類的例項物件:
AndroidJavaObject androidClass = androidClass = new AndroidJavaObject("com.test.ClipboardTools");
要注意的是,後面的字串"com.test.ClipboardTools"是你Android專案的<類目錄> + <類名>,這個不能寫錯,寫錯就無法或取出你要的Android類。
接著,是獲取Android所需要的Activity物件,也就是Android 專案中 copyTextToClipboard 方法所需要的 Context 引數,由於我們的Android類沒有繼承於Activity 類,而對ClipboardManager 的使用又需要當前Android執行時主執行緒的Activity,所以博主採用的是從 Unity3D 中獲取後傳輸過去。
最後是對ClipboardManager 類的 “複製”、“獲取”兩個方法的呼叫。
#if UNITY_ANDROID 和 #endif 代表的是在指定的平臺才進行編譯,如此處的 UNITY_ANDROID 代表期間的程式碼只在Android平臺才進行編譯,若是直接使用,則可能在IOS平臺出現編譯異常,因為IOS平臺並沒有AndroidJavaObject 這種類的庫檔案。
Unity3D呼叫IOS剪貼簿
使用Unity3D呼叫IOS的剪貼簿相對容易,但是需要在MAC上進行編寫測試。
IOS對剪貼簿的使用
對IOS平臺的呼叫博主採用簡潔的方式,讓Unity3D呼叫C,再用C去呼叫IOS的方法。先附上兩個檔案的原始碼:
Clipboard.h 檔案 :
@ interface Clipboard : NSObject
extern "C"
{
/* compare the namelist with system processes */
void _copyTextToClipboard(const char *textList);
}
@end
Clipboard.mm 檔案 :
@implementation Clipboard
//將文字複製到IOS剪貼簿
- (void)objc_copyTextToClipboard : (NSString*)text
{
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = text;
}
@end
extern "C" {
static Clipboard *iosClipboard;
void _copyTextToClipboard(const char *textList)
{
NSString *text = [NSString stringWithUTF8String: textList] ;
if(iosClipboard == NULL)
{
iosClipboard = [[Clipboard alloc] init];
}
[iosClipboard objc_copyTextToClipboard: text];
}
}
.h檔案和.mm檔案需要放在Unity專案的Assets/Plugins/目錄下的任意目錄下。
與C相同,Object-C也是需要一個頭檔案負責定義,還有一個真正編寫內容的檔案,這個檔案可以有兩種字尾“.m"和”.mm",“.m"中只能編寫Object-C程式碼,而”.mm"中可以編寫C程式碼。
在Clipboard.h中,我們定義了一個C的方法,在Clipboard.mm中,我們實現了C的方法,並在其中呼叫了IOS的剪貼簿功能。程式碼挺簡單,就不進行一一解釋了。
這裡稍微發下牢騷:博主學習過數種程式語言,自信在學習一種新語言時不會寫至少能看懂,然而Object-C的出現碾碎了博主的現實,尼瑪,這方法定義到底是神馬意思?簡直反人類啊……
Unity3D對IOS類的呼叫
Unity3D對IOS的使用倒是比較簡單,不過也需要進行環境配置:
1. 在Untiy3D專案的Assets目錄下建立Plugins目錄。
2. 在Plugins目錄下建立IOS目錄。
3. 在IOS 目錄下放置".h"檔案和".mm"檔案。
然後是呼叫的C#原始碼:
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class ClipboardManager
{
#if UNITY_IPHONE
/* Interface to native implementation */
[DllImport ("__Internal")]
private static extern void _copyTextToClipboard(string text);
#endif
public static void CopyToClipboard( string input)
{
#if UNITY_ANDROID
// 對Android的呼叫
#elif UNITY_IPHONE
_copyTextToClipboard(input);
#endif
}
}
這是一個C#類,CopyToClipboard()方法是對剪貼簿的應用,大家可以看到,在ClipboardManager類裡面,定義了這種東西:
#if UNITY_IPHONE
/* Interface to native implementation */
[DllImport ("__Internal")]
private static extern void _copyTextToClipboard(string text);
#endif
這表示在IOS平臺的編譯上,會匯入Objcet-C編寫的IOS方法,這是固定的寫法,大概瞭解即可,不要忘了匯入庫檔案哦(using System.Runtime.InteropServices;)
在下面,就可以直接對IOS定義方法的呼叫了,不過博主還是推薦加上以下東西:
#if UNITY_ANDROID
#elif UNITY_IPHONE
#endif
以免在跨平臺編譯時出現問題。