【Unity】persistentDataPathなどを使用せずにAndroidのフォルダパスを取得する【Android】

facebookのUnityユーザー助け合い所にて、Write AccessをInternal OnlyからExternal(SDCard)にしたら、もともと保存していたデータにアクセスできなくなったという話が出ています。
この件は前々から自分も気になっていたので、AndroidSDKから直接パスを取得できないか試してみました。
幸いUnityには直接AndroidのAPIを参照する、AndroidJavaClassやAndroidJavaObjectがあるため、プラグインなどを作らなくても取得できます。

詳しくは、公式ページの

http://docs-jp.unity3d.com/Documentation/Manual/PluginsForAndroid.html
こちらを参照してもらえると、キャッシュディレクトリを直接取得する例が載っています。

それでは、今回試してみたコードです。
追記:一応ちゃんと終了処理もおこなうコードに修正しました。
usingを使わない場合は、必要なくなったタイミングでAndroidJavaClassもしくはAndroidJavaObjectにあるDispose()を呼び出してください。
シュウリョウ ショリ ダイジ!

using UnityEngine;
using System.Collections;

public class AndroidPath : MonoBehaviour
{
	private string _FilesDir;
	private string _CacheDir;
	private string _ExternalFilesDir;
	private string _ExternalCacheDir;

	// Use this for initialization
	void Start ()
	{
#if !UNITY_EDITOR && UNITY_ANDROID
		using( AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer") )
		{
			using( AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity") )
			{
				using( AndroidJavaObject filesDir = currentActivity.Call<AndroidJavaObject>( "getFilesDir" ) )
				{
					_FilesDir = filesDir.Call<string>( "getCanonicalPath" );
				}

				using( AndroidJavaObject cacheDir = currentActivity.Call<AndroidJavaObject>( "getCacheDir" ) )
				{
					_CacheDir = cacheDir.Call<string>( "getCanonicalPath" );
				}

				using( AndroidJavaObject externalFilesDir = currentActivity.Call<AndroidJavaObject>("getExternalFilesDir",null ) )
				{
					_ExternalFilesDir = externalFilesDir.Call<string>("getCanonicalPath");
				}

				using( AndroidJavaObject externalCacheDir = currentActivity.Call<AndroidJavaObject>("getExternalCacheDir" ) )
				{
					_ExternalCacheDir = externalCacheDir.Call<string>("getCanonicalPath");
				}
			}
		}
#endif
	}

	void OnGUI()
	{
		GUILayout.Label( "getFilesDir : " + _FilesDir );
		GUILayout.Label( "getCacheDir : " + _CacheDir );
		GUILayout.Label( "getExternalFilesDir : " + _ExternalFilesDir );
		GUILayout.Label( "getExternalCacheDir : " + _ExternalCacheDir );
	}
}

主にやっていることは、現在アクティビティからgetFilesDirなどを介して、パスを取得しているだけです。
getFilesDirなどは、Fileインスタンスを返してくるため、さらにgetCanonicalPathでstringで取得しなおすようにしています。

どのメソッドがどのパスを返すかなど、より詳しくは、
http://techbooster.org/android/application/16004/
こちらのページが参考になりました。

ちなみに、Environmentの場合は、

AndroidJavaClass environment= new AndroidJavaClass("android.os.Environment");

bool isExternalStorageEmulated = environment.CallStatic<bool>("isExternalStorageEmulated" );

という感じにアクセスできます。
Androidのリファレンスはこちら
http://developer.android.com/reference/packages.html

実機のNexus7で試したところ

Internal Only
InternalOnly

External(SDCard)
External

と、どちらも変わりなく取得できているようです。

※ちなみに、Development Buildにチェックをつけると
persistentDataPathなどはWrite Accessに関係なくストレージを指す。
なんていう罠もあったりしますので気をつけてくださいね。

Unityのアセット販売中!

Arbor 2

ステートマシンの状態遷移やパラメータはエディタで編集でき、
ゲームロジックに依存するステートの挙動はスクリプトで記述可能なエディタ拡張。

詳細はこちら

Nostalgia 2

RPGツクールVXやWOLF RPGエディターのオートタイルに準拠したエディタ拡張。

詳細はこちら

オススメ!