- Home /
[Android - Data save issues] Does the 'install location' determine the location of persistentDataPath?
Greetings.
We're having issues where players lose a portion of their data but not all of it. We suspect that it has to do with the location on disk for persistentDataPath
, maybe Unity is reporting an path with older data for some reason and so the game loads from that.
I was looking at the build options and saw settings for "Install location" and "Write access". My questions are:
How does the install location and persisetentDataPath play together? does the install location affect the persistentDataPath location on disk?
What does "Automatic" mean in the install location options? does it mean that Unity will try internal first and if it failed it tries external? (or vise versa)
How does "Write access" play with "install location"? If the game was installed internally, and write access was set to external, does that mean that the game won't be able to save to internal storage? (or vise versa)
Do I need to add any special manifest permissions values? (we already have 'WRITE_EXTERNAL_STORAGE')
Which is more reliable, to use internal or external write in the build options?
Any clarification on the subject, pointers, dos and donts, or tips on the proper/right way to deal with this would be much appreciated.
Thanks.
[EDIT]: Second answer here says that internal storage is intended for development only. and that users need to have their device rooted to be able to access it. Do both of these statements still hold true now? http://answers.unity3d.com/questions/203852/how-to-access-persistent-data-path-in-android-phon.html
[EDIT]: How does it make sense that Unity by default has "Prefer External" as an install location and "Internal Only" as write access? So if the game got installed externally, does that mean it has no permission to write, cause the permission is internal only? That makes no sense to me.
I'm no expert when it comes to Android. When i was involved in Android development i did some tests back then, First of all i think you should seperate two things: Install location and data storage path. The install location is just where the OS will store the AP$$anonymous$$. This location is only read by the OS (Android) to load and run your app. Every app has a secured internal data folder. No other app can access this folder.
If i remember correctly it's located in "/data/data/YOUR.BUNDL$$anonymous$$ID/". So each AP$$anonymous$$ has it's own subfolder (the bundle identifier). You can't view the content of the data folder from any file manager application unless you have root access to the device. Usually, when installed internal the apk was placed inside that folder.
The Application.persistentDataPath
path used to point to this folder: "/data/data/YOUR.BUNDL$$anonymous$$ID/files/", however i haven't checked that for a long time so it might have changed.
The "write access" setting usually just affects some android privileges. I'm not sure if the persistant data path will also be "external" (i.e. on the SD card) if the AP$$anonymous$$ is installed external. However i think that the AP$$anonymous$$ simply has no permissions to access anything outside of it's own folder. So "internal only" refers to app internal filesystem structure. If you select write access "external" you basically request the android privilege to get free access (read and write) to the whole SD card. This might be necessary if your app wants / needs to access user files or write such files in a user accessible folder.
Unless you specifically need such a feature you should keep the setting "Internal Only". This shouldn't restrict you from reading and writing files to the persistent data path which is a special folder just for your app.
I didn't write this as an answer since it's mainly based on my (probably outdated) experiance a few years ago.
The best thing i can suggest is create an app that prints out the content of "persistentDataPath" and "dataPath" and see what's the difference if you select "internal / external" for both install location and write access. I've once created my $$anonymous$$obileStats app which does print some states as well as those two folder paths. Though the app is two years old. The source is this: App.cs and Drawing.cs if you want to rebuild it.
edit Hmm i just saw that the source isn't the latest version ^^. It doesn't have the path information included ^^.
Hi vexe, we are having a similar problem with an updated app, default "Install location" and "Write access" settings. Printing the persistentDataPath, we realized it is returning two different values: /storage/emulated/0/Android/data/[bundle-identifier]/files and /data/user/0/[bundle-identifier]/files When we just install the app it prints one of those paths, and closing and restarting the app it shows the other path, and we are not able to notice when and why this value suddenly changes. We had this project ready to deploy and encountered this issue, so I would really appreciate any information you got about it, thanks in advance.
@Black_Demon For IOS it seems consistent. We ended up just writing a Java plugin that gives us back the internal path explicitly. If you don't like writing a plugin you could use unity's java reflection utils and call the function by string. I don't have the details currently at my disposal but should be easily available online.
I see, it seems the right way to go. I think I can find the information to do it, thanks for your quick response. Edit: I'm posting this function just in case someone find it useful, also if you got any thought about it, it'll be welcome. This function returns /data/data/[bundle-identifier]/files (or /data/user/0/[bundle-identifier]/files).
string GetAppDataPath() {
string appDataPath = "";
AndroidJavaObject filesDir;
using (AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer")
.GetStatic<AndroidJavaObject>("currentActivity")) {
filesDir = activity.Call<AndroidJavaObject>("getFilesDir");
}
appDataPath = filesDir.Call<string>("getAbsolutePath");
return appDataPath;
}
Answer by Mediaheads · Sep 24, 2017 at 07:21 PM
Man we're working on a big project with a custom Android launcher. All Android apps work like a charm as they all get installed in app/data... Unity apps however were a Royal pain in the arsch. Check the ADB output of installed packages. The last one is the Unity APK with standard settings.
package:/data/app/air.BimiiFarm-1.apk=air.BimiiFarm
package:/data/app/air.BimiiFood-1.apk=air.BimiiFood
package:/mnt/asec/nl.mediaheads.bimiiRekenen-1/pkg.apk=nl.mediaheads.bimiiRekenen
Output after we set the install location to: Force (?!) Internal
package:/data/app/nl.mediaheads.bimiirekenen-1.apk=nl.mediaheads.bimiirekenen
Took 8 hours to solve it trying to edit the AndroidManifest, adjusting laucher code... i'm not an expert but why put it on Prefer External?
Your answer
Follow this Question
Related Questions
Opening data file from asset folder 2 Answers
Application.CaptureScreenshot() does not save any image on Android while it does on Editor! 0 Answers
Application.persistentDataPath returning null on certain Android devices 2 Answers
Saving and loading to/from Android 1 Answer
SqliteException: Unable to open the database file - Ready-made DB Provided To Access 0 Answers