V系バンドマンがゲームを開発するんご

V系バンドマンの僕がゲームを開発してみるんご

【Android】【Unity】ギャラリーから画像を持ってきたい その3

前回の続きです。

前回の記事はこちら
vprog.hatenablog.com

前回、取得した画像パスをUnity側で取得してみましょ。
java側からunity側に送るには
UnityPlayer.UnitySendMessage
を、java側に記述すればいいそうです。

しかし、全部c#でできないのかな?って思って色々試してみました。

AndroidJavaProxyを使用します。

参考サイト
qiita.com

AndroidStudio
GalleryListener.javaを作成

public interface GalleryListener {
    public void onRestart();

    public void onStart();

    public void onResume();

    public void onPause();

    public void onStop();

    public void onActivityResult(int requestCode, int resultCode, Intent data);
}

AndroidStudio
GalleryActivity.java

    private static GalleryListener my_listener;
    public static void SetListener(GalleryListener listener)
    {
        my_listener = listener;
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult: " + requestCode + " : " + resultCode);
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode != RESULT_OK)
        {
            setResult(resultCode);
            finish();
            return;
        }
        if(my_listener != null) {
            my_listener.onActivityResult(requestCode, resultCode, data);
        }
        setResult(resultCode);
        finish();
    }

Unity
ActivityListener.cs

public class ActivityListener : AndroidJavaProxy
{
	public Action<int,int,AndroidJavaObject> onActivityResultEvent;

	public ActivityListener()
		: base("com.sample.samplegame.lib.GalleryListener")
	{
	}

	public void onRestart()
	{
	}

	public void onStart()
	{
	}

	public void onResume()
	{
	}

	public void onPause()
	{
	}

	public void onStop()
	{
	}

	public void onActivityResult(int requestCode, int resultCode, AndroidJavaObject data)
	{
		Debug.Log(requestCode + " : " + resultCode + " : " + data);

		onActivityResultEvent(requestCode, resultCode, data);
	}
}

Sample.cs

	private ActivityListener m_Listener;

	void Start () {
		using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.GalleryActivity")) {
			javaCalss.CallStatic ("SetListener", m_Listener = new ActivityListener() );
		}
        }
	void OnGUI(){
		if(GUILayout.Button("gallery", GUILayout.Width(300), GUILayout.Height(200))){
			using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.GalleryActivity")) {
				javaCalss.CallStatic ("OpenGallery" );
			}
		}
	}

実機で実行して、画像を選択するとUnityのログ側で出力されます。

では、画像パスもc#で取得してみましょう。

Unity
Sample.cs

	void Start () {
		using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.GalleryActivity")) {
			javaCalss.CallStatic ("SetListener", m_Listener = new ActivityListener() );
		}

		m_Listener .onActivityResultEvent = (int requestCode, int resultCode, AndroidJavaObject data) => {
			var d = data.Call<AndroidJavaObject>("getData");
			using( AndroidJavaClass dd = new AndroidJavaClass("android.provider.DocumentsContract") ){
				var strDocId = dd.CallStatic<string>("getDocumentId", d);
				var strSplittedDocId = strDocId.Split(":"[0]);
				var strId = strSplittedDocId[strSplittedDocId.Length - 1];
				using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
					using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) {
						var r = activity.Call<AndroidJavaObject>("getContentResolver");
						var c = r.Call<AndroidJavaObject>("query",
							new AndroidJavaClass("android.provider.MediaStore$Images$Media").GetStatic<AndroidJavaObject>("EXTERNAL_CONTENT_URI"),
							new string[]{
								new AndroidJavaClass("android.provider.MediaStore$MediaColumns").GetStatic<string>("DATA")
							},
							"_id=?",
							new string[]{strId},
							null
						);
						if(c.Call<bool>("moveToFirst")){
							m_ImagePath = c.Call<string>("getString",0);
							Debug.Log(m_ImagePath);
						}
						c.Call("close");
					}
				}
			}
                }
        }

これで画像パスがログに表示されました。

answers.unity3d.com

さて、パスを取得したのでパスからテクスチャを作成してみましょう。

Unity
Sample.cs

			var imageByte = System.IO.File.ReadAllBytes(m_ImagePath);
			var texture = new Texture2D(0,0);
			texture.LoadImage(imageByte);
			m_Picture.sprite = Sprite.Create( texture, new Rect(0f, 0f, t.width, t.height), Vector2.zero);

これで、テクスチャを作成して表示ができるようになったと思います。