1. 程式人生 > >Unity3D 呼叫Android與IOS的剪貼簿

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

以免在跨平臺編譯時出現問題。