私はAndroidでゲームエンジンを作成するためにエンジンで純粋なC++を使用しています。単一のJavaファイルはありません。基本的には外部メモリにのみ保存するゲームです。アセットデータをadb経由で外部SDカードに手動で移動すると、ゲームはすでに正常に動作し、安定しています。
adb push ..\..\Bin\Data /sdcard/Android/data/com.fantasyhaze.%SMALL_PACKAGE_NAME%/files/Data/
配信できないため、これは適切なソリューションではありません。したがって、次の構造でビルドプロセス中にapkファイルに移動されるAssetsフォルダーにassets-dataがあります。
Assets / Data / MoreFolders / Withsubfolders Assets / Data / EngineData.zip Assets / Data / ScriptData.zip
しかし、c++コードでそれらにアクセスするためにそれらのファイルがファイルシステムのどこにあるのかわかりません。
そこで、ファイルディレクトリへのパスを取得しようとしました。また、ネイティブアクティビティ状態のバグのため、通常のコードで情報を取得する必要があります。
// bug in 2.3 internalDataPath / externalDataPath = null using jni code instead
//FHZ_PRINTF("INTERNAL inter PATH = %s\n", state->activity->internalDataPath);
//FHZ_PRINTF("EXTERNAL inter PATH = %s\n", state->activity->externalDataPath);
android.os.Environment.getFilesDir()およびandroid.os.Environment.getExternalStorageState()に相当するc++コード
// getPath() - java
JNIEnv *jni_env = Core::HAZEOS::GetJNIEnv();
jclass cls_Env = jni_env->FindClass("android/app/NativeActivity");
jmethodID mid_getExtStorage = jni_env->GetMethodID(cls_Env, "getFilesDir","()Ljava/io/File;");
jobject obj_File = jni_env->CallObjectMethod( gstate->activity->clazz, mid_getExtStorage);
jclass cls_File = jni_env->FindClass("java/io/File");
jmethodID mid_getPath = jni_env->GetMethodID(cls_File, "getPath","()Ljava/lang/String;");
jstring obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
const char* path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("INTERNAL PATH = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);
// getCacheDir() - java
mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getCacheDir", "()Ljava/io/File;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL);
cls_File = jni_env->FindClass("java/io/File");
mid_getPath = jni_env->GetMethodID(cls_File, "getAbsolutePath", "()Ljava/lang/String;");
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("CACHE DIR = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);
// getExternalFilesDir() - java
mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL);
cls_File = jni_env->FindClass("java/io/File");
mid_getPath = jni_env->GetMethodID(cls_File, "getPath", "()Ljava/lang/String;");
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("EXTERNAL PATH = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);
//getPackageCodePath() - java
mid_getPath = jni_env->GetMethodID(cls_Env, "getPackageCodePath", "()Ljava/lang/String;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getPath);
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("Looked up package code path = %s\n", path);
これは非常にうまく機能し、結果として
内部パス=/data/data/com.fantasyhaze.rememory/files
CACHE DIR = /data/data/com.fantasyhaze.rememory/cache
外部パス=/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files
ルックアップされたパッケージコードパス=/mnt/asec/com.fantasyhaze.rememory-2/pkg.apk
しかし、アセットフォルダからのファイルはありません...
ファイルを読み取るには、通常の作業ディレクトリとしてフォルダにアクセスする必要があります。これはで可能です
/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files/Data
ただし、すべてのデータをアセットフォルダー(どこにある場合でも)からアセットマネージャーを介してこのフォルダーに移動すると、メモリの消費量が2倍になります。
資産>1GBは、資産> 2GBを意味しますが、これは意味がありません。それ以上に、assertフォルダーは、大きなpakファイルを使用する場合には不可能な小さなデータファイルに対してのみ、効果的に機能しないようです。たぶん、解凍システムを使用しているときにファイルにapkから直接アクセスしてから、リソースファイルをuzipすることができますが、とにかくapkパスを取得する必要があります。
だから私の質問:
- ファイルシステムのapkのAssetsフォルダーはどこにありますか?
- apkの場所または実行可能ファイルの場所を取得するためのコード(c ++)は何ですか?
- 通常のファイルを開く方法で直接アクセスできますか、それとも解凍した場合にのみアクセスできますか。開梱せずに使えるとしたらどうですか?
- SDカードがマウントされている場合に情報を取得するためのコード(c ++)は何ですか?
誰かが私を助けてくれることを願っています:)
編集:キャッシュディレクトリとパッケージディレクトリコード(およびその出力パス)を追加して、それを必要とする他のすべての人にソースを提供します。