bUseExternalFilesDir

bUseExternalFilesDir

#Overview

name: bUseExternalFilesDir

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 8 C++ source files. Also referenced in 1 C# build file meaning it may affect the build system logic.

#Summary

#Usage in the C++ source code

The purpose of bUseExternalFilesDir is to determine the storage location for Unreal Engine game files on Android devices. It is primarily used for managing file storage and access permissions in Android applications developed with Unreal Engine 5.

This setting variable is primarily used in the Android runtime settings and the Android-specific parts of the Unreal Engine’s launch module. It’s particularly relevant for the Android platform and affects how the engine handles file storage on Android devices.

The value of this variable is set in the Android Runtime Settings, which can be configured in the Unreal Engine editor. It’s defined as a UPROPERTY with the GlobalConfig flag, meaning it can be set in the project’s configuration files.

This variable interacts closely with other Android-specific settings, particularly:

  1. bPublicLogFiles: Determines whether log files should be placed in a publicly accessible directory.
  2. GInternalFilePath and GExternalFilePath: These variables store the paths for internal and external file storage.

Developers must be aware of the following when using this variable:

  1. It affects the storage location of game files, which can impact performance and storage permissions.
  2. It has different implications for shipping builds versus development builds.
  3. It may affect the need for certain Android permissions, particularly WRITE_EXTERNAL_STORAGE.

Best practices when using this variable include:

  1. Consider the target Android API level, as storage permissions have changed in newer Android versions.
  2. For shipping builds, carefully consider the implications of using external storage versus internal storage.
  3. Ensure that the choice aligns with the game’s storage needs and the Android platform’s security model.
  4. Test the application thoroughly with both settings (true and false) to ensure proper functionality in all scenarios.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:3047, section: [/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Android/AndroidRuntimeSettings/Classes/AndroidRuntimeSettings.h:268

Scope (from outer to inner):

file
class        class UAndroidRuntimeSettings : public UObject

Source code excerpt:

	// You should also check this if you need to save you game progress without requesting runtime WRITE_EXTERNAL_STORAGE permission in android api 23+
	UPROPERTY(GlobalConfig, EditAnywhere, Category = "APK Packaging", Meta = (DisplayName = "Use ExternalFilesDir for UnrealGame files?"))
	bool bUseExternalFilesDir;

	// If checked, log files will always be placed in a publicly available directory (either /sdcard/Android or /sdcard/UnrealGame).
	// You may require WRITE_EXTERNAL_STORAGE permission if you do not use ExternalFilesDir checkbox in android api 23+
	UPROPERTY(GlobalConfig, EditAnywhere, Category = "APK Packaging", Meta = (DisplayName = "Make log files always publicly accessible?"))
	bool bPublicLogFiles;

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp:1792

Scope (from outer to inner):

file
function     JNI_METHOD void Java_com_epicgames_unreal_GameActivity_nativeSetGlobalActivity

Source code excerpt:


//This function is declared in the Java-defined class, GameActivity.java: "public native void nativeSetGlobalActivity();"
JNI_METHOD void Java_com_epicgames_unreal_GameActivity_nativeSetGlobalActivity(JNIEnv* jenv, jobject thiz, jboolean bUseExternalFilesDir, jboolean bPublicLogFiles, jstring internalFilePath, jstring externalFilePath, jboolean bOBBinAPK, jstring APKFilename /*, jobject googleServices*/)
{
	STANDALONE_DEBUG_LOG(TEXT("nativeSetGlobalActivity(unreal): Entering unreal nativeSetGlobalActivity, GameActivityThis=%p\n"), FJavaWrapper::GameActivityThis);
	if (FJavaWrapper::GameActivityThis != nullptr)
	{
		STANDALONE_DEBUG_LOG(TEXT("nativeSetGlobalActivity(unreal): Error GameActivityThis is already set GameActivityThis=%p\n"), FJavaWrapper::GameActivityThis);
		//jenv->DeleteGlobalRef(FJavaWrapper::GameActivityThis);

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp:1809

Scope (from outer to inner):

file
function     JNI_METHOD void Java_com_epicgames_unreal_GameActivity_nativeSetGlobalActivity

Source code excerpt:

			check(false);
		}
		STANDALONE_DEBUG_LOG(TEXT("nativeSetGlobalActivity(unreal): jenv=%p, set GameActivityThis=%p, bUseExternalFilesDir=%d, bOBBinAPK=%d\n"), jenv, FJavaWrapper::GameActivityThis, bUseExternalFilesDir, bOBBinAPK);

		// This call is only to set the correct GameActivityThis
		FAndroidApplication::InitializeJavaEnv(GJavaVM, JNI_CURRENT_VERSION, FJavaWrapper::GameActivityThis);

		// @todo split GooglePlay, this needs to be passed in to this function
		FJavaWrapper::GoogleServicesThis = FJavaWrapper::GameActivityThis;

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp:1827

Scope (from outer to inner):

file
function     JNI_METHOD void Java_com_epicgames_unreal_GameActivity_nativeSetGlobalActivity

Source code excerpt:

		GExternalFilePath = FJavaHelper::FStringFromParam(jenv, externalFilePath);

		if (bUseExternalFilesDir)
		{
#if UE_BUILD_SHIPPING
			GFilePathBase = GInternalFilePath;
			GOverrideAndroidLogDir = bPublicLogFiles;
#else
			GFilePathBase = GExternalFilePath;

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp:2174

Scope (from outer to inner):

file
function     JNI_METHOD void Java_com_epicgames_makeaar_GameActivityForMakeAAR_nativeSetGlobalActivity

Source code excerpt:

}
#if USE_ANDROID_STANDALONE
JNI_METHOD void Java_com_epicgames_makeaar_GameActivityForMakeAAR_nativeSetGlobalActivity(JNIEnv* jenv, jobject thiz, jboolean bUseExternalFilesDir, jboolean bPublicLogFiles, jstring internalFilePath, jstring externalFilePath, jboolean bOBBinAPK, jstring APKFilename /*, jobject googleServices*/)
{
	STANDALONE_DEBUG_LOG(TEXT("nativeSetGlobalActivity: Entering makeaar nativeSetGlobalActivity, GameActivityThis=%p\n"), FJavaWrapper::GameActivityThis);
	if (FJavaWrapper::GameActivityThis != nullptr)
	{
		STANDALONE_DEBUG_LOG(TEXT("nativeSetGlobalActivity(makeaar): Error GameActivityThis is already set GameActivityThis=%p\n"), FJavaWrapper::GameActivityThis);
		//jenv->DeleteGlobalRef(FJavaWrapper::GameActivityThis);

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp:2191

Scope (from outer to inner):

file
function     JNI_METHOD void Java_com_epicgames_makeaar_GameActivityForMakeAAR_nativeSetGlobalActivity

Source code excerpt:

			check(false);
		}
		STANDALONE_DEBUG_LOG(TEXT("nativeSetGlobalActivity(makeaar): jenv=%p, set GameActivityThis=%p, bUseExternalFilesDir=%d, bOBBinAPK=%d\n"), jenv, FJavaWrapper::GameActivityThis, bUseExternalFilesDir, bOBBinAPK);
		// This call is only to set the correct GameActivityThis
		FAndroidApplication::InitializeJavaEnv(GJavaVM, JNI_CURRENT_VERSION, FJavaWrapper::GameActivityThis);
		// Rescan methods since we are switching to the makeaar version of GameActivity
		FJavaWrapper::FindClassesAndMethods(jenv);
		// @todo split GooglePlay, this needs to be passed in to this function
		FJavaWrapper::GoogleServicesThis = FJavaWrapper::GameActivityThis;

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp:2206

Scope (from outer to inner):

file
function     JNI_METHOD void Java_com_epicgames_makeaar_GameActivityForMakeAAR_nativeSetGlobalActivity

Source code excerpt:

		GInternalFilePath = FJavaHelper::FStringFromParam(jenv, internalFilePath);
		GExternalFilePath = FJavaHelper::FStringFromParam(jenv, externalFilePath);
		if (bUseExternalFilesDir)
		{
#if UE_BUILD_SHIPPING
			GFilePathBase = GInternalFilePath;
			GOverrideAndroidLogDir = bPublicLogFiles;
#else
			GFilePathBase = GExternalFilePath;

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp:2220

Scope (from outer to inner):

file
function     JNI_METHOD void Java_com_epicgames_makeaar_GameActivityForMakeAAR_nativeSetGlobalActivity

Source code excerpt:

	}
	// DO NOT CALL, we have already handled logic above...
	// Java_com_epicgames_unreal_GameActivity_nativeSetGlobalActivity(jenv, thiz, bUseExternalFilesDir, bPublicLogFiles, internalFilePath, externalFilePath, bOBBinAPK, APKFilename);
}
#endif // USE_ANDROID_STANDALONE

void FJavaWrapper::SetupEmbeddedCommunication(JNIEnv* Env)
{
#if BUILD_EMBEDDED_APP

#References in C# build files

This variable is referenced in the following C# build files:

Location: <Workspace>/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEDeployAndroid.cs:452

			// we check this a lot, so make it easy 
			bool bUseExternalFilesDir;
			Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bUseExternalFilesDir", out bUseExternalFilesDir);

			return bUseExternalFilesDir;
		}

		public List<string> GetTargetOculusMobileDevices(ConfigHierarchy Ini)
		{