using UnityEngine; using System .Collections; using System .Runtime.InteropServices; using System ; public class CallJavaCode : MonoBehaviour { private IntPtr TwitterSampleActivityClass; // [1] private int ptr_getScreenName; // [2] private int ptr_auth; // [3] private int ptr_updateStatus; // [4] private string announceString; void Start (){ // attach our thread to the java vm; obviously the main thread is already attached but this is good practice.. JavaVM.AttachCurrentThread(); //Get TwitterSampleActivityClass Pointer // [5] IntPtr cls_Activity = JNI.FindClass("com/example/twittersample/TwitterSampleActivity"); Debug.Log ("cls_Activity = " + cls_Activity); int fid_Activity = JNI.GetStaticFieldID(cls_Activity, "twitterSampleActivity_", "Lcom/example/twittersample/TwitterSampleActivity;"); IntPtr obj_Activity = JNI.GetStaticObjectField(cls_Activity, fid_Activity); TwitterSampleActivityClass = JNI.NewGlobalRef(obj_Activity); ptr_auth = JNI.GetMethodID(cls_Activity, "auth", "()V"); // [6] ptr_getScreenName = JNI.GetMethodID(cls_Activity, "getScreenName", "()Ljava/lang/String;"); // [7] ptr_updateStatus = JNI.GetMethodID(cls_Activity, "updateStatus", "(Ljava/lang/String;)V"); // [8] announceString = ""; } private void auth(){ // [9] JNI.CallVoidMethod(TwitterSampleActivityClass, ptr_auth); } private string getScreenName(){ // [10] IntPtr str_GetScreenName = JNI.CallObjectMethod(TwitterSampleActivityClass, ptr_getScreenName); Debug.Log ("str_GetScreenName = " + str_GetScreenName); IntPtr stringPtr = JNI.GetStringUTFChars(str_GetScreenName, 0); Debug.Log ("stringPtr = " + stringPtr); String screenName = Marshal.PtrToStringAnsi(stringPtr); JNI.ReleaseStringUTFChars(str_GetScreenName, stringPtr); Debug.Log ("return value is = " + screenName); return screenName; } private void updateStatus(string message){ // [11] IntPtr encMessage = JNI.NewStringUTF(message); JNI.CallObjectMethod(TwitterSampleActivityClass, ptr_updateStatus,encMessage); } void OnGUI (){ resetButton(); if(makeButton("Auth Request")){ auth(); announceString = "auth completed"; } if(makeButton("get ScreenName")){ announceString = "screenname: " + getScreenName(); } if(makeButton("twit Hello")){ string message = "Hello from Unity"; announceString = "twitmsg: " + message; updateStatus(message); } showMessage(announceString); } int buttonX = 0; int buttonY = 0; void resetButton(){ buttonX = 0; buttonY = 0; } void showMessage(string message){ int labelW = 400; int labelH = 50; GUI.Label(new Rect(10,80,labelW,labelH), message); } bool makeButton(string label){ int buttonW = 150; int buttonH = 50; int buttonsInRow = 2; bool b = GUI.Button(new Rect(10+buttonX*(buttonW+5), 150+buttonY*(buttonH+5), buttonW, buttonH), label); buttonX++; if(buttonX==buttonsInRow){ buttonX = 0; buttonY++; } return b; } void _log(string logstring){ Debug.Log (logstring); } }
[1]では、Java側で実装したメインActivityクラス「TwitterSampleActivity」を参照するためのメンバ変数を定義します。[5]では、TwitterSampleActivityクラスを[1]で定義したメンバ変数と結び付ける処理を記述しています。
[2]では、TwitterSampleActivityクラス内の関数「getScreenName()」を参照するためのメンバ変数を定義します。[6]では、TwitterSampleActivityクラス内の関数「getScreenName()」と[2]で定義したメンバ変数を結び付ける処理を記述しています。
[3]では、TwitterSampleActivityクラス内の関数「auth()」を参照するためのメンバ変数を定義します。[7]では、TwitterSampleActivityクラス内の関数「auth()」と[3]で定義したメンバ変数を結び付ける処理を記述します。
[4]では、TwitterSampleActivityクラス内の関数「updateStatus()」を参照するためのメンバ変数を定義します。[8]では、TwitterSampleActivityクラス内の関数「updateStatus()」と[4]で定義したメンバ変数を結び付ける処理を記述します。
[9]では、[7]で結び付けたauth()関数をUnityのスクリプト内から呼び出すための関数を定義します。[10]では、[6]で結び付けたgetScreenName()関数をUnityのスクリプト内から呼び出すための関数を定義します。[11]では、[8]で結び付けたupdateStatus()関数をUnityのスクリプト内から呼び出すための関数を定義します。
BluetoothSampleのときと同じ手順でUnityとEclipseでプロジェクトをビルドし、APKファイルを生成します。
下図は実機端末上でビルドされたAPKファイルを実行したときのスクリーンショットです。サンプルアプリを起動したところです。スクリプトにより設置した各関数を呼び出すテスト用のボタンが設置されています。
Twitterにアプリからアクセスするためには、まずは認証を行う必要があります。「Auth Request」ボタンをクリックすると、Twitterの認証画面を開き、UnityからJavaで記述したコードに制御が移ります。すると、WebViewを設置した新しいActivityが開いてTwitterの認証画面が表示され、ログインおよび今回開発したアプリからのデータの読み書きの許可・不許可を選択できます。
ここで「許可」を選択し、アプリからTwitterにアクセスするための認証情報であるアクセストークンを要求します。今回開発したアプリからのデータの読み書きが許可されると表示される画面です。この後、アクセストークンがアプリ側に返されTwitterの認証画面を表示していたActivityが終了し、Unityアプリの画面に戻ります。
認証が無事成功することで「auth completed」というメッセージがUnity側に表示されることが確認できます。Unity側で処理結果をハンドリングできていることが確認できます。
認証済みの状態で「get ScreenName」ボタンを押すと、UnityからTwitter4J経由でTwitterからスクリーン名を取得し、Unity上に表示することが確認できます。
認証済みの状態で「twitter Hello」ボタンを押すと、UnityからTwitter4J経由でTwitterにひと言メッセージ「Hello from Unity」を送信できます。
「twitter Hello」ボタンで正常にメッセージを送信すると、当然ながら自分のタイムライン上にメッセージが確認できます。PCなどでTwitterのページを開いて正しく投稿できているか確認してみます。
以上で、UnityからAndroidネイティブ用の既存ライブラリを呼び出し、Webサービスにアクセスできました。例えばTwitter4Jを用いてTwitterと連携したゲームアプリを開発可能かと思います(例えば、ゲーム上でのアチーブメント(達成度)やアクティビティ(行動)をTwitter上に配信するなど)。
今回は例としてTwitterとTwitter4Jを用いましたが、Androidで利用可能なライブラリはたくさん存在するので多彩なアプリをUnityを用いながら実現できることがご理解いただけかと思いますので、試してみてはいかがでしょうか。
Copyright © ITmedia, Inc. All Rights Reserved.