Search Unity

Android Settings - Write Access: Internal Only vs External

Discussion in 'Android' started by TitanUnity, Aug 10, 2016.

  1. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    180
    Hi,

    Our game has been using the 'Other Settings' > 'Write Access' > 'Internal Only' option since launch several months ago. We chose this option because selecting the 'External (SDCard)' option was presenting our users with a scary message on app load requesting access to "Files, Photos and Media."

    Internal.PNG

    Until recently, 'Internal Only' has worked well for us. A few days ago we launched a major update to our game. Some users that have installed our update reported the game wouldn't start properly. After running some tests and working directly with these users, we've confirmed that the issue is caused because the game fails to load the user's save file from internal storage. Specifically, these are users that have switched the default storage location on their device from Internal Storage to SD Card.

    It seems that after these users install our update, the game fails to load the original Internal file and is unable to write a new one to their external storage because our Write Access value is defined as 'Internal Only'.

    Since I have no way to prevent users from changing their default install location, it leaves us in a pickle... if we leave our Write Access on 'Internal Only', many users that are using external storage SD cards will not be able to start the game. If we change our Write Access to 'External SD Card' we will reintroduce that scary permission message, and potentially strand the Internal storage save files of our existing players. We haven't done extensive testing on the consequences of switch Write Access to 'External SDCard' yet, but would prefer to leave things on the 'Internal Only' option as it seems like the safer bet.

    I'm looking for a recommendation on how to handle these users, and help understanding the Write Access option. Are we missing something obvious that would prevent this problem? Is anyone else encountering this issue?

    We're currently using Unity 5.3.6p1.
     
    SweatyChair likes this.
  2. Deleted User

    Deleted User

    Guest

  3. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    180
    I haven't investigated that avenue because I'm not sure what the intended behavior is for the Write Access options. Specifically, how is the 'Internal Only' option to supposed to work if a player has selected the default storage location as their External SD Card? One player for example said this:

    Once the player makes this change, our game doesn't have permission to write to that location and fails to start. Telling our players that they must use internal storage isn't good enough since the vast majority of users that encounter this problem will likely never communicate with us, worse they will probably rate us poorly on the App Store and Play Store.

    We could definitely use some clarity from Unity on best practices to handle this situation.
     
  4. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @TitanUnity : we are using Android APIs to get the path to files directory. If the user switches the storage in the phone settings - it will likely cause the game data to disappear.

    The issue sounds interesting and not related to the thread by @CDDelta . If you could try it and find the reproduction steps - that would be very helpful.

    Please keep in mind the behavior can be different across Android versions: before KitKat and after.
     
  5. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    180
    @Yury-Habets Many of our users have confirmed the following steps to recreate this problem:

    1. Have the game installed normally to Internal Storage (everything works fine)
    2. Switch the default storage location to the SD Card via Settings > Storage > Default Location
    3. Grab ANY future update to our game from the Play Store
    4. Game won't start

    Our test builds have revealed that the game start fails because it's unable to find a save file, and then when our logic would instruct it to create a new empty save, the app doesn't have permission to create a new one in the external save location since our Write Access is set to 'Internal Only'. The worst part is as you've mentioned, even if we did have permission to write to the SD Card, that's definitely bad since it would create a new save file and the user would think they've lost all their data.
     
  6. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Could you submit a bug report please? Sounds like something we may want to fix.
     
  7. charnold

    charnold

    Joined:
    Mar 31, 2014
    Posts:
    31
    Hi, any news about this?

    Problem here: Application.persistentDataPath is

    /storage/emulated/0/Android/data/bundleIdentifier/files (when the app is built with Unity 5.3.6p1) and

    /data/data/bundleIdentifier/files (when the app is built with Unity 5.3.5p6)

    Write Access is set to Internal only.

    Correction: I only had this problem, because I made 2 apps, that shared one data folder (sharedUserId) and weren't built with the same Unity version (one app was built with Unity5.3.5p6 and the other with 5.3.6p1). Building both apps with the same Unity version solved my problem.
     
    Last edited: Aug 28, 2016
  8. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @charnold sounds strange because there were no Android changes in 5.3.6p1. How does it work in latest 5.4? Could you submit a bug report please? Thank you!
     
  9. IceStormRUS

    IceStormRUS

    Joined:
    Sep 13, 2016
    Posts:
    4
    We have some problems on Unty 5.4.1f1. Write access set to "Internal Only"? but unity try write to sd card, even when thone have not it.

    When i try download asset bundle logcat on device show:

    W/Unity (14911): (Filename: ./Runtime/AssetBundles/AssetBundleLoadFromStreamAsyncOperation.cpp Line: 269)
    D/Unity (14911): CreateDirectory '/storage/emulated/0/Android/data/com.******/files' failed:
    W/Unity (14911): Failed to create temporary cache directory 'Temp/2dc1eecc7afdd474680306c89933d0fb'

    Also UnityEngine.Application.persistentDataPath return empty string

    int work fine on Unity 5.3.5 and broked after upgrade to 5.3.6
    (sorry for my english)
     
  10. Asse1

    Asse1

    Joined:
    Jan 9, 2013
    Posts:
    89
    Same here, but the stacktrace is slightly different:

    Code (CSharp):
    1. 09-15 11:18:26.810: W/Unity(14545): (Filename:  Line: 313)
    2. 09-15 11:18:26.810: W/Unity(14545): Failed to create temporary cache directory 'mem:/CAB-9f8ddd7e42604dae8468ba31208e976a380e904707c4047d9a2e90fa3914ede1'
    Also there are no missing assets in the game after loading has finished so maybe this message points to a third party SDK which tried to create temp files.

    This happened after updating to Unity 5.4.1f1.
     
  11. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    180
  12. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    180
    Just to follow up, we're still seeing problems with this issue. Unity Performance Report tools have shed even more light on this issue:

    We're seeing a ton of these errors:
    UnauthorizedAccessException: Access to the path "/mnt/internal_sd/Android/data/OUR_SAVE_FILE_PATH" is denied.

    Subsequently we're seeing a lot of these errors:

    Code (CSharp):
    1. System.IO.Directory.CreateDirectory (System.String path)
    2. ES2DirectoryUtility.CreateDirectory (System.String path)
    3. ES2FileStream.CreateStorageStream ()
    4. ES2FileStream.Store ()
    5. ES2Writer.Save (Boolean checkForOverwrite)
    6. ES2Writer.Save ()
    7. ES2.Save[Int32] (Int32 param, System.String identifier)
    8. SaveManager+<LoadAll>c__Iterator4D.MoveNext ()
    9. UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress)
    10. UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    11. <StartRoutine>c__Iterator42:MoveNext()
    12. UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    13. GameManager:Start()
    It seems that we just don't have access to the save location and as a result users are getting hung at game start. This is a critical issue for us and has been on going for several releases.

    Any updates on this report would be helpful. Our current live version is using the Unity 5.4.1p1
     
  13. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @TitanUnity it's close to impossible to verify an issue if the bug report has no project attached.
    Could you attach a project to your bug report? A small one is really appreciated.
    In addition, we need the exact specification of the device you are testing on.
     
  14. BrainAndBrain

    BrainAndBrain

    Joined:
    Nov 27, 2014
    Posts:
    115
    So glad I found this thread, as I too am having this issue on Unity 5.4.0f3. Game Performance in analytics is reporting a huge number of errors that take two forms:

    UnauthorizedAccessException: Access to the path "/saveFileName" is denied.

    And:

    UnauthorizedAccessException: Access to the path "/storage/sdcard1/Android/data/com.company.appname/files/saveFileName" is denied.

    Both are only happening on Android 4.x and 5.x, and I'm not able to reproduce it on my own devices (running Android 7).

    In Player Settings, the "Install Location" is set to "Automatic," and "Write Access" is set to "Internal Only." Our manifest file does not contain "WRITE_EXTERNAL_STORAGE", due to both the message it displays to users and Google's review of the game which required us to justify its usage (which for the game itself, is unnecessary).

    I'm working through the issue with a very kind player, but other players may not be so patient. A fix or some guidance would be hugely appreciated!

    - David
     
  15. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    180
    I hope to get a repo project going soon, but it will take me some time to recreate the exact scenario in a new project.
     
  16. BrainAndBrain

    BrainAndBrain

    Joined:
    Nov 27, 2014
    Posts:
    115
    Do you think forcing internal would fix this? I don't mind forcing it if need be; I just don't want players to get the error.
     
  17. IceStormRUS

    IceStormRUS

    Joined:
    Sep 13, 2016
    Posts:
    4
    It's very strange but looks like a error gone after upgrading UnityAds to UnityAds 2.0
    May be new version add something to android manifest file. Now our application have access to read save file and asset bundle caching work fine too.
     
  18. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    180
    @Yury-Habets We're starting to learn more about this issue but still have more digging to do. We've discovered that some devices have the option to set a default storage location and other devices do not:

    In Unity Performance Tools, we've see loads of write permission errors from 'Huawei' devices and others. What we found was that these devices allow the user to set the default storage location. Unfortunately none of our testing devices in house have this option so it's making it difficult to experiment. (We're looking to get our hands on some)

    Huawei with Default Storage Option
    default_storage.png

    Other Devices without Default Storage Option
    Screenshot_2016-10-10-16-28-22.png default2.jpg

    Bottom-line: It seems that when a user has their default storage location set to SD Card, but we have our game settings set to 'Internal Only' storage, the users experience write permission problems like this:
    Save2.JPG

    And this:
    save3.JPG
    Currently this is our strongest theory but as I mentioned since we don't have the device to test on we can't prove it's the cause. We'll do our best to get more details.
     
    SweatyChair likes this.
  19. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @TitanUnity I appreciate your investigations. However for the bug to be able to be processed by QAs, could you make sure you:
    - attach your project to the bug report
    - have the exact device models (preferably with build fingerprint) mentioned
    - describe the reproduction steps

    Thank you!
     
  20. Hudelf

    Hudelf

    Joined:
    Jun 16, 2015
    Posts:
    4
    Yury-Habets likes this.
  21. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Thanks! I've asked QAs to process this bug as soon as possible, we'll take a look into it when confirmed.
     
  22. sevensails

    sevensails

    Joined:
    Aug 22, 2013
    Posts:
    483
    I have the same problem here :

    I got some info from Unity Performance Monitor Report.

    1. unique_device_models:["ARMv7 VFPv3 NEON"]
      1. 0:"ARMv7 VFPv3 NEON"
    2. unique_graphics_devices:["VideoCore IV HW", "NVIDIA Tegra 3", "PowerVR SGX 540", "GC1000 core"]
      1. 0:"VideoCore IV HW"
      2. 1:"NVIDIA Tegra 3"
      3. 2:"PowerVR SGX 540"
      4. 3:"GC1000 core"
    3. unique_platforms:["Android OS 4.2.2 / API-17 (JDQ39/I9082XXUBMK5)",…]
      1. 0:"Android OS 4.2.2 / API-17 (JDQ39/I9082XXUBMK5)"
      2. 1:"Android OS 4.2.1 / API-17 (JOP40D/WW_epad-10.6.1.27.5-20130902)"
      3. 2:"Android OS 4.2.2 / API-17 (JDQ39/P5100XXDMJ2)"
      4. 3:"Android OS 4.2.2 / API-17 (JDQ39/T110XXUANI7)"
      5. 4:"Android OS 4.2.2 / API-17 (JDQ39/T110UEUANK2)"
    Please everybody let me know if there is a workaround or fix available.

    Thanks
     
  23. sevensails

    sevensails

    Joined:
    Aug 22, 2013
    Posts:
    483
    On 5.4.3 release notes we have this :

    • Android: Return internal temporary cache and persistent data paths when external paths are unavailable. (826201)

    It seems this bug was fixed! Anybody knows when this will be ported to 5.5 beta?
     
    CanisLupus likes this.
  24. sevensails

    sevensails

    Joined:
    Aug 22, 2013
    Posts:
    483
    No it's not fixed!

    I updated a old game to Unity 5.4.3 and made a new Android Build and now I have users complaining the game is not working anymore.

    In performance reporting I found a lot of
    "UnauthorizedAccessException: Access to the path "/storage/sdcard0/Android/data/com.sevensails.queensgarden2mobile/files/save.sav" is denied."

    Why? Please... Anybody have any advice of how to avoid this? Where I can save to fully avoid this error?
     
  25. sevensails

    sevensails

    Joined:
    Aug 22, 2013
    Posts:
    483
    "/storage/sdcard0/Android/data/" is the defaul internal storage folder, isn't it?

    How the access to this could be denied? I added READ_INTERNAL READ_EXTERNAL and WRITE_EXTERNAL permissions to Android Manifest and sent a new build to my user and it still does not works. The game fails to save. The user is using Android 4.1.2 on a Samsung Galaxy Note 2.

    Any advice?
     
  26. Hudelf

    Hudelf

    Joined:
    Jun 16, 2015
    Posts:
    4
    We're actually very curious to know what the actual change was here. We've been getting reports of lost data from users since we updated to this version, and would love to get more details from a dev on what exactly changed to try and track down if this is the source of our issue.

    Paging @Yury-Habets if you're still monitoring this thread. :)
     
  27. silmarill

    silmarill

    Joined:
    Jul 13, 2013
    Posts:
    10
    Confirm this bug!

    We F***ed up release becouse of this issue.

    Unity vers: 5.4.0f3

    Device: lenovo tab 2 a10-30, android 5.1

    Some adb logs:

    After downloading bundle

    W/Unity (16718): Failed to create temporary cache directory 'Temp/baa93760e66dd4bf7b8c848a3f091daa'
    W/Unity (16718):
    W/Unity (16718): (Filename: Line: 313)

    Before sharing image

    I/Unity (16718): Media Share
    I/Unity (16718):
    I/Unity (16718): (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 42)
    I/Unity (16718):
    I/Unity (16718): UnauthorizedAccessException: Access to the path "/SaltanSkazki.png" is denied.
    I/Unity (16718): at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) [0x00000] in <filename unknown>:0
    I/Unity (16718): at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize) [0x00000] in <filename unknown>:0
    I/Unity (16718): at System.IO.File.Create (System.String path, Int32 bufferSize) [0x00000] in <filename unknown>:0
    I/Unity (16718): at System.IO.File.Create (System.String path) [0x00000] in <filename unknown>:0
    I/Unity (16718): at System.IO.File.WriteAllBytes (System.String path, System.Byte[] bytes) [0x00000] in <filename unknown>:0
    I/Unity (16718): at btnShare+<SaveAndShare>c__Iterator26.MoveNext () [0x00000] in <filename unknown>:0
    I/Unity (16718): at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00000] in <filename unknown>:0
    I/Unity (16718):
    I/Unity (16718): (Filename: Line: -1)
    I/Unity (16718):


    After recors and save sound
    I/Unity (23813): (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 42)
    I/Unity (23813):
    I/Unity (23813): ArgumentException: Path is empty
    I/Unity (23813): at System.IO.Directory.CreateDirectory (System.String path) [0x00000] in <filename unknown>:0
    I/Unity (23813): at SavWav.Save (System.String filename, UnityEngine.AudioClip clip) [0x00000] in <filename unknown>:0
    I/Unity (23813): at Mic.RecordStopAndSave (System.String nameEnd) [0x00000] in <filename unknown>:0
    I/Unity (23813): at SettingsController.btnRecStart (Int32 parentID) [0x00000] in <filename unknown>:0
    I/Unity (23813): at UnityEngine.Events.InvokableCall`1[System.Int32].Invoke (System.Object[] args) [0x00000] in <filename unknown>:0
    I/Unity (23813): at UnityEngine.Events.CachedInvokableCall`1[System.Int32].Invoke (System.Object[] args) [0x00000] in <filename unknown>:0
    I/Unity (23813): at UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0
    I/Unity (23813): at UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0
    I/Unity (23813): at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <filename unknown>:0
    I/Unity (23813): at UnityEngine.UI.Button.Press () [0x00000] in <filename unknown>

    Please fix it ASAP.
     
  28. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @Hudelf I do follow :)
    Related thread: https://forum.unity3d.com/threads/playerprefs-persist-between-installs-on-android.434886/
    Also pinging @JuliusM as he's been developing stuff around the issue.

    I must say that we don't have a clear repro of the new issues at the moment.
    (the one you and @TitanUnity orinigally posted here was reproduced, but we could do nothing about it)

    The paths/access thing is a bit complicated because it has multiple dimensions:
    - the access option in the Player settings
    - the permissions
    - android version (kitkat+ does not need WRITE_EXTERNAL_STORAGE to save to private directories on the SD card)
    - some strange devices having this additional option in the application settings

    The less you mess up around this - the less chances you are going to hit issues.

    However, a new bug report of losing saves is appreciated, with a project and steps to reproduce.
     
  29. lloydg

    lloydg

    Joined:
    Mar 23, 2015
    Posts:
    36
  30. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @lloydg - bug report is very much appreciated.
    We haven't confirmed this issue yet.
     
  31. lloydg

    lloydg

    Joined:
    Mar 23, 2015
    Posts:
    36
    Last edited: Jan 10, 2017
    Yury-Habets likes this.
  32. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @lloydg please add the info on which devices you've been using - it's also crucial.
     
    lloydg likes this.
  33. lloydg

    lloydg

    Joined:
    Mar 23, 2015
    Posts:
    36
    Hi @Yury-Habets , I had put some details in the report but here are more on the device I used:

    Tested using a: Samsung Galaxy S5 (SM-G900I)

    Not sure how to update the report with this.
     
    Last edited: Jan 11, 2017
    Yury-Habets likes this.
  34. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    You can probably reply with an email. :)
     
    lloydg likes this.
  35. lloydg

    lloydg

    Joined:
    Mar 23, 2015
    Posts:
    36
    Thanks, yes, talking to someone now from QA about the issue.

    It is looking like Unity is meant to automatically move your files to the new location, but that is not happening.
     
  36. CoopOwnz

    CoopOwnz

    Joined:
    Oct 6, 2016
    Posts:
    74
    I released update to my app and am coming across the same problem as the OP. Last release was working fine.
    Build settings are Install Location: 'Prefer External'
    Write Access: 'Internal Only'

    How did the OP resolve this issue?

    UnauthorizedAccessException: Access to the path "/mnt/internal_sd/Android/data/blackjack.allin1.com/files/bj_allin1_data.dat" is denied.

    I am unable to recreate this on my device and I haven't had any users contact me about it yet but have a hundred or so logs of this error.
     
    Last edited: Jan 31, 2017
    SkutteOleg likes this.
  37. lloydg

    lloydg

    Joined:
    Mar 23, 2015
    Posts:
    36
    Hi @CoopOwnz

    They wont be fixing it:

    https://fogbugz.unity3d.com/default.asp?869140_ubgf7jh2881lr0ir

     
  38. CoopOwnz

    CoopOwnz

    Joined:
    Oct 6, 2016
    Posts:
    74
  39. OriginalCoder

    OriginalCoder

    Joined:
    Jun 9, 2015
    Posts:
    4
    We are still getting issues with 5.5.1p3 and reports of savegames not working, with this in the game performance portal:

    UnauthorizedAccessException: Access to the path "/storage/emulated/0/Android/data/<packagename>/files/PersistentData.dat" is denied.

    We have the WRITE_EXTERNAL_STORAGE permission in the manifest to avoid past issues with people forcing install to SDCard, and have always had install location set to 'prefer external'.

    Currently we've had the report from the following device:

    Android OS 4.4.2 / API-19 (KOT49H/1436345823)
     
  40. nanomo

    nanomo

    Joined:
    Mar 13, 2013
    Posts:
    1
    Im having the same problem with a tablet with Android 4.4.2, the app works fine on a samsung s7 with android 6.0.1

    Unity: 5.5.0.f3
    Setup of the player:
    Install location: Force Internal
    Write permission: Internal

    App is installed in disk device

    The code executed its related to a file opening:

    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Create(Application.persistentDataPath + "/partidas.dat");
    Partidas partida = new Partidas();
    partida.totalPartidas = totalPartidas;
    bf.Serialize(file, partida);
    file.Close();
     
    Last edited: Feb 18, 2017
  41. Tanek

    Tanek

    Joined:
    Apr 19, 2016
    Posts:
    45
    I'd like to thank everyone in this thread (especially @TitanUnity ) for their efforts in debugging this issue, everything I read here was very helpful.
    I think there are two issues here:
    1. I can confirm that one issue is related to Huawei storage setting, I just debugged it with a very helpful player of our game and his Huawei device has default storage location to the SD Card (via Settings > Storage > Default Location), this setting is turned on as soon as you plug in an SD Card. This causes our app to be unable to save the generated database and the savegame, thus preventing him from being able to play. In our game version currently in production, I always use Application.persistentDataPath to access data directory, I think that simply this Huawei customization makes Unity return the path on SDCard, which is unaccessible because our game doesn't ask for "Write External" permission. I am trying to fix this issue (with a release today or Tomorrow, I hope) by using a different approach by calling internal directories and testing them for write permission. More info here: http://answers.unity3d.com/questions/998752/unauthorizedaccessexception-access-to-the-path-is-1.html , there is also an example script here: https://gist.github.com/gering/f37082d8dd45a3ae4f2c . Many thanks to @TheGering for this.
    2. The second issue is related to the "usual" Application.persistentDataPath ( /storage/emulated/0/Android/data/[bundleIdentifier]/files/ ) which on some devices seems to have not write permission. I don't think it's strictly related to Unity version updates as we never went from Unity 5.2 to Unity 5.5 (we did all the "middle" steps during last months, updating to Unity 5.5 with last week release), also because that's an issue about losing savegames and not about having troubles with write permission. I think this issue is pretty bad and dangerous, as no developer should be instructed by documentation to call a Unity method (Application.persistentDataPath) which can instead have unexpected behavior on some devices. I am trying to fix this issue with the same fix I am implementing in the previous case, as the savegame directory will be tested for write permission.

    As soon as I'll have our new version in production I'll post here the results.

    I hope this helps, if anyone has further question feel free to ask, I spent the last 2 days debugging this and I found few detailed info online, so I decided to reply here with my discoveries (and also to thank you all :) ).
     
  42. Tanek

    Tanek

    Joined:
    Apr 19, 2016
    Posts:
    45
    I can confirm that the above solution works for both the issues I outlined: we are in production from this morning and both cases are solved.

    To recap even more:
    • a Huawei device with the UnauthorizedAccessException because of the Application.persistentDataPath was hijacked by the "default storage location" setting
      AND
    • a device with a custom ROM which was getting unexplainable UnauthorizedAccessException on internal directory even though using Application.persistentDataPath
    are now running without problems our game, thanks to the above implementation (which of course replaces all the Application.persistentDataPath calls in my code).

    PS: of course I still believe those issues could, and should, be tackled from Unity, I don't think it's a wise idea to have an Application.persistentDataPath that maybe works on Android.
     
    IcyHammer likes this.
  43. stevenatunity

    stevenatunity

    Joined:
    Apr 17, 2015
    Posts:
    114
    @Tanek If I am only using playerprefs for saving does this issue still present a problem? Thanks :)
     
  44. Tanek

    Tanek

    Joined:
    Apr 19, 2016
    Posts:
    45
    @stevenatunity I am sorry but I don't know if playerPrefs can be affected by this issue: those are handled internally by Unity and you don't have to (and can not) explicitly call Application.persistentDataPath to declare where to save them.
     
  45. stevenatunity

    stevenatunity

    Joined:
    Apr 17, 2015
    Posts:
    114
    @Tanek thank you. Great work on this problem!
     
  46. CoopOwnz

    CoopOwnz

    Joined:
    Oct 6, 2016
    Posts:
    74
    @Tanek The example github script you posted I think may be what I need. However, I'm a bit confused about something. Since my app does not have permissions to write external then all of the external storage paths that are returned in the script will always fail. Does this mean that if the user has the app on external storage that it may still be able to find an internal path to store the file?
     
  47. Tanek

    Tanek

    Joined:
    Apr 19, 2016
    Posts:
    45
    @CoopOwnz don't worry, the script checks each directory by trying to write 1 byte on it, that means that the external paths will always be null from the getter of "persistentDataPathExternal" and they will never be returned nor used if you follow the script logic (using the getter for the "best" persistent data path available).

    Our game in production does not have permission to write on external and currently we have no issues with this workaround.
     
  48. JuliusM

    JuliusM

    Unity Technologies

    Joined:
    Apr 17, 2013
    Posts:
    835
    In Unity 5.4 starting with Unity 5.4.2p1 the Application.persistentDataPath should work the same as in the code provided by @Tanek. We also try to create a dummy file to check if the path can be accessed. Any Unity 5.4 version released after 5.4.2p1 should not have any issues related to Application.persistentDataPath.

    We also use a dummy file to determine Application.persistentDataPath in Unity 5.5 (and all newer versions) starting with Unity 5.5.0f1, however it is possible that in Unity 5.5 your previously saved files won't be in the path returned by the Application.persistentDataPath. This is the reason why. In Unity 5.2 and previous versions, when the write access was set to internal only (which means the application did not request the WRITE_EXTERNAL_STORAGE permission), Application.persistentDataPath was always returning the internal path. But because Android 4.4 and newer Android versions do not need WRITE_EXTERNAL_STORAGE permission to access external path, we've started to return the external path if we considered it available. This would automatically make your previously saved files to "disappear" because they would be in a different path than what is returned by the Application.persistentDataPath. To solve this issue we have added code to copy your files from the previous location to the new one (if it has changed) when the app made with the new Unity version is started for the first time. We do this only once to make sure that new files written to the new path are not overwritten by old files. This copying behaviour was added to Unity 5.3 and 5.4, but NOT Unity 5.5. This means that if you have published your game with Unity 5.2 and now will release an update with Unity 5.5, your saved files won't be present in the path returned by the Application.persistentDataPath. The best solution to this problem is to manually copy your saved files from the internal path to the new path on the first run after updating your app to Unity 5.5. Then you will be able to continue to use Application.persistentDataPath and won't have to change your scripts.
    You can get the internal path (which was always returned in Unity 5.2) like this
    Code (CSharp):
    1. string GetInternalPath()
    2. {
    3.     AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    4.     AndroidJavaObject activity = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
    5.     return activity.Call<AndroidJavaObject>("getFilesDir").Call<string>("getPath");
    6. }
     
    SweatyChair and Yury-Habets like this.
  49. CoopOwnz

    CoopOwnz

    Joined:
    Oct 6, 2016
    Posts:
    74
    Thank you so much for helping to clear some of this up. HOWEVER, my last release was with Unity 5.4 and I am still getting exceptions like this daily:
    I have my write access set to internal. Now I understand why the persistentDataPath is sometimes returning an external path still because of what you said above. However, it should not return an external path in some of these situations since their device is obviously not allowing access to that path. Here is the simple code I use:
    Code (CSharp):
    1. FileStream file;
    2.         if (File.Exists(Application.persistentDataPath + Path.DirectorySeparatorChar + "bj_allin1_data.dat"))
    3.         {
    4.             file = File.Open(Application.persistentDataPath + Path.DirectorySeparatorChar + "bj_allin1_data.dat", FileMode.Open);
    5.         }
    6.         else
    7.         {
    8.             file = File.Create(Application.persistentDataPath + Path.DirectorySeparatorChar + "bj_allin1_data.dat");
    9.         }
    My next release is about to be with Unity 5.5. PLEASE if you can help in any way with this exception I would very much appreciate it. I've been searching for answers for a while.
     
  50. Singlecore

    Singlecore

    Joined:
    Sep 22, 2012
    Posts:
    8
    It's good to hear that.
    But according to the articles of @sevensails and @CoopOwnz, it still happens with the newer versions.
    I'm using Unity 5.3 for my game but I want to solve this problem. Should I update Unity to 5.4.x or not?