How to create a save file on android 11?

The save system stopped working after updating to android 11.

Hi, have you figured it out?

I ran into similar frustration, but I’ve come up with a workaround for my project. To be clear, the issue I was seeing was that APK’s built on someone else’s machine would run just fine on my Android 11, but not when built from my machine. (My project needs to save some initial data during startup, and doesn’t load properly otherwise.)

At first I thought this was an issue with the way I had installed Android Studio, even though I followed UE4’s (outdated) documentation. It turns out, it doesn’t matter if I use Android Studio 3.5.3 (the documentation’s recommendation) or 4.1.3 (the current latest), so that was a rather misleading rabbit hole.

The actual issue (in my case) is that SDK 30 (for Android 11) enforces an application sandbox mode (see the warning on https://developer.android.com/training/data-storage/use-cases#opt-out-in-production-app), and UE4 hasn’t been updated to play nicely with this. So you need to specifically target SDK 29 or earlier. For whatever reason I wasn’t able to do this from UE4 settings—it either ignored my changes, or else I was doing it wrong, because it always wound up targeting SDK 30 (thereby causing this permission issue).

To see if you have the same issue, run your project on an Android 11 device and check the ā€œlogcatā€ (either from adb or via Android Studio), and look for the following error: java.lang.IllegalArgumentException: Primary directory UE4Game not allowed for content.

My current workaround is to Package the project for Android in the regular way (from UE4, File → Package Project → Android), but then to load the resulting Android project (Intermediate → Android → gradle) via Android Studio and manually change the ā€œtargetSdkVersionā€ to 29. This can be done in Android Studio by opening the ā€œbuild.gradleā€ file from the Project explorer (and then look under ā€œGradle Scriptsā€). Be sure to open ā€œbuild.gradle (Module: app.app)ā€, not the project ā€œbuild.gradle (Project: app)ā€ file. It probably wouldn’t hurt to run Build → Clean Project at this point, though it might not be necessary. After that my project runs fine! Granted, it’s not a difficult workaround, but it would be nice to have an actual solution via UE4.

Anyway, I hope this helps resolve your issue! It sounds like it might be the same as mine. It was certainly hard enough to track down that I thought it worth posting here.

(One final note: I seem to have better success with Android Studio 4.1, rather than the outdate version that UE4 documentation insists on. I think maybe my local Gradle version wasn’t wanting to play nicely with the outdated version of Android Studio 3.5.3, and I didn’t want to bother trying to mess with it when I already had a workaround. In other words, I can confirm that I can build the UE4 project and debug C++ code via Android Studio 4.1, so I’m not sure why I would need to use the older version.)

2 Likes

Many thanks

I found this while trouble shooting the other day, and it was the realisation that I needed to be on 29 that solved my issues. I had to search to find this again just to say - thank you, AxiomRL.

As an aside, found a weird issue where Unreal would not build to API 29 for me while 30 was installed. If anyone else has this issue - I uninstalled android 11 from Android Studio, fixed that issue.

But will google allow to upload if i uninstall API 30 and set target API to 29 ?
I mean i am in development still and i am having issue creating save files. And may be by the time i finished my project google may set minimum require API to 30, wouldn’t it ?

EDIT : I searched on internet and i found this link about android 11 Android 11ģ˜ ģ €ģž„ģ†Œ ģ—…ė°ģ“ķŠø Ā |Ā  Android ź°œė°œģž Ā |Ā  Android Developers , Seems from android 11 they are terminating access to external dir. and they’ve added called ā€œscoped storageā€ functionality.
I am no export in any programing, i am just blue print user, so you guys might understand if this is root problem of files not saving on android.

Anybody come up with proper solution to android 11 game save issue???

Brother sdk 30 is compulsory by google now… How you managed to save game in android 11??
Iam really stuck here

Brother have you sorted the problem related to android 11 saving? Iam badly stuck here

Using Unreal 4.27 here, targeting API 32.

The solution with Unreal Plugin Language from this article worked for me. Now, saving works on both Shipping and Development builds on the Quest 3.

For UE 4.27, I had to modify the script to replace unreal with ue4.


I also had no idea where that script was supposed to go, and the UPL doc page is useless on that regard.

So, here goes.

Modify your game module build settings

On your game module’s .Build.cs file, inside the public GameName(...) : base(Target) construction function, add the following:

if (Target.Platform == UnrealTargetPlatform.Android)
{
    string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
    AdditionalPropertiesForReceipt.Add("AndroidPlugin", Path.Combine(PluginPath, "AndroidDebugSaveFix_APL.xml"));
}

The xml file can have any name. Just make sure you use the same name here and on the file.

Add the xml file with the UPL script

Create an xml file on the same folder where the .Build.cs file is. Use the same name you typed there. In my example, it is AndroidDebugSaveFix_APL.xml. Then, add this to it:

<?xml version="1.0" encoding="utf-8"?>
<!--Haymaker android manifest modifications-->
<root xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- updates applied to AndroidManifest.xml -->
    <androidManifestUpdates>
        <loopElements tag="meta-data">
            <setStringFromAttribute  result="NameTagValue" tag="$" name="android:name"/>
            <setBoolIsEqual result="UseExternalFilesDirElement" arg1="$S(NameTagValue)" arg2="com.epicgames.ue4.GameActivity.bUseExternalFilesDir"/>
            <if condition="UseExternalFilesDirElement">
                <true>
                    <removeElement tag="$"/>
                </true>
            </if>
        </loopElements>

        <addElements tag="application">
            <meta-data android:name="com.epicgames.ue4.GameActivity.bUseExternalFilesDir" android:value="true" />
        </addElements>
    </androidManifestUpdates>
</root>

Remember to replace the two occurrences of ue4 with unreal if your project is on UE5.

To check if it worked, after you package your project for Android, open [ProjectDir]/Intermediate/Android/arm64/AndroidManifest.xml. Look for bUseExternalFilesDir and you should find

<meta-data android:name="com.epicgames.ue4.GameActivity.bUseExternalFilesDir" android:value="true" />

as the last entry in the <application> tag, right before the line with </application>.

  • If it contains android:value="false", it didn’t work at all.
  • If you find two occurrences of bUseExternalFilesDir, the script added one, but failed to remove the original. It’s likely looking for the wrong name. Make sure whether you need ue4 or unreal by looking at the other com.epicgames.X.GameActivity entries in AndroidManifest.xml.
1 Like