チラ裏。本当のメモです。あしからず
UnityでAndroidを開発している時の試行錯誤の末路。
AndroidのMainActivityを生成するときのテンプレート(UnityPlayerNativeActivity)をカスタマイズし、
UnityのC#からAndroid標準のファイルChoserを呼び出してファイルパスを取得できるようにやったときのめも。うまくいっている気はする。
呼び出され側
<Unity_home>\Editor\Data\PlaybackEngines\androidplayer\com\unity3d\player のUnityPlayerNatieActivity.javaを編集
package com.unity3d.player; import android.app.NativeActivity; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.net.Uri; import android.content.Intent; public class UnityPlayerNativeActivity extends NativeActivity { private static final int REQUEST_GALLERY = 0; private boolean isRoad = false; private String filepath = null; protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code // Setup activity layout @Override protected void onCreate (Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().takeSurface(null); setTheme(android.R.style.Theme_NoTitleBar_Fullscreen); getWindow().setFormat(PixelFormat.RGB_565); mUnityPlayer = new UnityPlayer(this); if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true)) getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(mUnityPlayer); mUnityPlayer.requestFocus(); } // Quit Unity @Override protected void onDestroy () { mUnityPlayer.quit(); super.onDestroy(); } // Pause Unity @Override protected void onPause() { super.onPause(); mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() { super.onResume(); mUnityPlayer.resume(); } // This ensures the layout will be correct. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mUnityPlayer.configurationChanged(newConfig); } // Notify Unity of the focus change. @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mUnityPlayer.windowFocusChanged(hasFocus); } // For some reason the multiple keyevent type is not supported by the ndk. // Force event injection by overriding dispatchKeyEvent(). @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_MULTIPLE) return mUnityPlayer.injectEvent(event); return super.dispatchKeyEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } /*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } // Extend public void pickPhoto() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, REQUEST_GALLERY); isRoad = true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub if(requestCode == REQUEST_GALLERY && resultCode == RESULT_OK) { try { String[] columns = { MediaColumns.DATA }; Cursor cursor = getContentResolver().query(data.getData(), columns, null, null, null); if (cursor.moveToFirst()) { File file = new File(cursor.getString(0)); filepath = file.getAbsolutePath(); } } catch (Exception e) { filepath = null; } finally { isRoad = false; } } } public boolean isRoading() { return isRoad; } public String getPath() { return filepath; } }
呼び出す側
using UnityEngine;
using System.Collections;
public class PickPhoto : MonoBehaviour {
private static string activity = "com.unity3d.player.UnityPlayer";
enum PpState {PICKSTART, PICKING, DEFAULT};
private PpState state = PpState.DEFAULT;
private AndroidJavaClass cUnityPlayer;
private AndroidJavaObject oCurrentActivity;
// Use this for initialization
void Start () {
// Find the UnityPlayer and get the static current activity
cUnityPlayer = new AndroidJavaClass (activity);
oCurrentActivity = cUnityPlayer.GetStatic<AndroidJavaObject> ("currentActivity");
}
// Update is called once per frame
void Update () {
switch (state) {
case PpState.PICKING:
if(!IsRoading()) {
state = PpState.DEFAULT;
SetImage(GetPath());
}
break;
case PpState.PICKSTART:
PickStart();
state = PpState.PICKING;
break;
case PpState.DEFAULT:
if (Input.GetMouseButtonDown(0)) {
state = PpState.PICKSTART;
}
break;
}
}
void PickStart() {
oCurrentActivity.Call("pickPhoto");
}
bool IsRoading() {
return oCurrentActivity.Call<bool>("isRoading");
}
string GetPath() {
return oCurrentActivity.Call<string>("getPath");
}
void SetImage(string filepath) {
// Debug.Log("path:" + GetPath());
GameObject go = GameObject.Find("GameMaster");
go.GetComponent<GMSelectChara>().setImage(filepath);
}
}