ES2.Exists not working with files

Discussion and help for Easy Save 3
Post Reply
FatPanda
Posts: 4
Joined: Mon Feb 26, 2018 7:54 pm

ES2.Exists not working with files

Post by FatPanda »

Hi, I´m trying to use ES2.Exists to get a specific file in Android devices, this is the path: "/data/data/com.PocketRocket.Monkeynauts/files/" and this is the file "SAVE_FILE.bytes"
When I use ES2.Exists using only the path as a paramater, it returns true (so the directory indeed exists), but when I try to get the path and the file it returns false, even though I double checked that the file exists in my phone.
Also, when I use ES2.GetFiles with the same path, the array length is zero, like there are no files in that path (I even try to put pdf files and other files inside the path just to check, and still no luck).

This returns false with the path: /data/data/com.PocketRocket.Monkeynauts/files/

Code: Select all

 public bool FileExistsInPath(string path)
        {
            Debug.Log("Exist in " + path + "SAVE_FILE.bytes");
            if (ES2.Exists(path + "SAVE_FILE.bytes"))
            {
                return true;
            }
            return false;
        }
This returns true with the path: /data/data/com.PocketRocket.Monkeynauts/files/

Code: Select all

public bool PathExists(string path)
        {
            Debug.Log("Path exists: " + path);
            if (ES2.Exists(path))
            {
                return true;
            }
            return false;
        }
And the file array is zero:

Code: Select all

public void GetAllFilesInFolder(string path)
        {
            string[] files = ES2.GetFiles(path);
            Debug.Log("Files size: " + files.Length);
            for (int i = 0; i < files.Length; i++)
            {
                Debug.Log("File name: " + files[i]);
            }
What can cause this problem? Is an Android problem?
Thanks for the help and this great asset!
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: ES2.Exists not working with files

Post by Joel »

Hi there,

If you need to include files with a project, traditionally you put them in the Resources folder, or put them in the Streaming Assets folder.

To see what is happening with your project however, could you do a couple of things for me?
  1. Run Debug.Log(Application.persistentDataPath); on your device, and let me know what this outputs.
  2. Run ES2.Save(123, "myFile.txt?tag=myTag"), and then see if ES2.GetFiles still returns an empty array.
All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
FatPanda
Posts: 4
Joined: Mon Feb 26, 2018 7:54 pm

Re: ES2.Exists not working with files

Post by FatPanda »

Hi, thanks for the reply.
Yes I just did the tests you asked me and here are the results:

1.- Running Debug.Log(Application.persistentDataPath); points to = /storage/sdcard0/Android/data/com.PocketRocket.Monkeynauts/files
2.- On the second test, I made this method where path = "/data/data/com.PocketRocket.Monkeynauts/files/":

Code: Select all

public void GetAllFilesInFolder(string path)
        {
            ES2.Save(123, "myFile.txt?tag=myTag");
            ES2.Save(321, path + "myFile2.txt?tag=myTag");
            string[] files = ES2.GetFiles(Application.persistentDataPath + "/"); 
            string[] files2 = ES2.GetFiles(path);

            Debug.Log("Files size: " + files.Length);
            for (int i = 0; i < files.Length; i++)
            {
                Debug.Log("File name: " + files[i]);
            }

            Debug.Log("Files 2 size: " + files2.Length);
            for (int i = 0; i < files2.Length; i++)
            {
                Debug.Log("File 2 name: " + files2[i]);
            }
        }


Both Files and Files2 have size = 1, the name of the file in "Files" is myFile.txt and "Files2" is myFile2.txt, so I think it works fine, the problem is I couldn´t find myFile2.txt in my phone (both internal and external memory).

Sorry for not making myself clear last time I wrote. The "SAVE_FILE.bytes" is the save file created by Easy Save, so I don´t need to include it in my project, as it´s created automatically when the app is opened.

The problem I have (I think) is described here http://www.moodkie.com/forum/viewtopic.php?f=5&t=1249 and I´m trying to implement the solution you sugested in that post:
Joel wrote:No problem, I always try my best to help even when it's not fully under our control.

You can use ES2.Exists to determine if your save exists at a given path. So if you have access to a device which has this issue, you should be able to use it with your filename appended to the paths above to see if they exist. Note you will need to replace mycompany, mygame and the uuid with your own where applicable.

You might also want to check if the original location was on the SD card, as Unity might be suddenly forcing it to use internal storage even when you've told it to use external storage. The location of this is:
/storage/sdcard0/Android/data/com.<companyname>.<productname>/files
You should then be able to use ES2.Rename to change the path of the old file to the new Application.persistentDataPath.

All the best,
Joel
The problem is that I´m sure that my save file is here "/data/data/com.PocketRocket.Monkeynauts/files/SAVE_FILE.bytes", and ES2.Exists with that path outputs false, but "/data/data/com.PocketRocket.Monkeynauts/files/" outputs true.

Also I have checked the list of possible paths and it still returns false:

Code: Select all

/data/data/com.PocketRocket.Monkeynauts/files
/data/user/0/com.PocketRocket.Monkeynauts/files
/data/user/11/com.PocketRocket.Monkeynauts/files
Thanks again for your help.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: ES2.Exists not working with files

Post by Joel »

Would you be able to show me the code you use to save the file, so I can try to replicate it fully at my end?

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
FatPanda
Posts: 4
Joined: Mon Feb 26, 2018 7:54 pm

Re: ES2.Exists not working with files

Post by FatPanda »

Yes, of course I can show some code. Basically we use a SaveManager to save any data with a tag:
SaveManager.cs

Code: Select all

using Misc.Constants;
using System.Collections.Generic;
using UnityEngine;

namespace Misc
{
    public class SaveManager : MonoBehaviour
    {
        private const string PASSWORD = "A12KOES28PAGA";

       //We save with password and a tag 
        private string GetFileNameAndSettings()
        {
	          return GetFileName()+"?encrypt=true&password=" + PASSWORD + "&tag=";
        }
        
        //We get the file name with the class SaveKeys
        private string GetFileName()
        {
                return SaveKeys.SAVE_FILE_NAME.Value + ".bytes";
        }

        //Just showing some methods to save, we have a lot of tags, but basically every method is the same
        
       //Method to save coins with the coins tag
        public void SaveCoins(decimal coins) 
        {
            ES2.Save(coins, GetFileNameAndSettings() + SaveKeys.COINS.Value);
        }
        //Load coins with the coins tag
        public decimal LoadCoins() 
        {
            decimal coins = 3000;//Default coins
            if (ES2.Exists(GetFileNameAndSettings() + SaveKeys.COINS.Value)) 
            {
                coins = ES2.Load<decimal>(GetFileNameAndSettings() + SaveKeys.COINS.Value);
            }
            return coins;
        }

       //Save diamonds with diamonds tag
	public void SaveDiamonds(decimal diamonds)
        {
	     ES2.Save (diamonds, GetFileNameAndSettings() + SaveKeys.DIAMONDS.Value);
        }
	
        //Load diamonds with the diamonds tag
        public decimal LoadDiamonds()
        {
	    decimal diamonds = 0;
	    if (ES2.Exists(GetFileNameAndSettings() +SaveKeys.DIAMONDS.Value))
            {
		diamonds = ES2.Load<decimal> (GetFileNameAndSettings() + SaveKeys.DIAMONDS.Value);
	    }
	    return diamonds;
	 }
    }
}
Then we have the SaveKeys.cs, this class basically holds all the tags we use:
SaveKeys.cs:

Code: Select all

namespace Misc.Constants 
{
    public sealed class SaveKeys 
    {
        public static readonly SaveKeys SAVE_FILE_NAME = new SaveKeys("SAVE_FILE");
        public static readonly SaveKeys COINS = new SaveKeys("COINS");
	public static readonly SaveKeys DIAMONDS = new SaveKeys ("DIAMONDS");

        private SaveKeys(string value) 
        {
            Value = value;
        }

        public string Value { get; private set; }   
    }
}
We use it like this:

Code: Select all

public SaveManager saveManager;

saveManager.SaveCoins(100);
coins = saveManager.LoadCoins();
If this helps, in Unity we have these settings:
Install Location: Prefer External
Internet Acces: Auto
Write Permission: Internal

And our AndroidManifest has these permissions:

Code: Select all

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.unity3d.player" android:installLocation="preferExternal">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Thanks again for the help!.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: ES2.Exists not working with files

Post by Joel »

Hi there,

What value are you using for SaveKeys.SAVE_FILE_NAME.Value? With the current manifest, if this isn't an absolute path it will be writing to the SD card, not the path you're trying to read from.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
FatPanda
Posts: 4
Joined: Mon Feb 26, 2018 7:54 pm

Re: ES2.Exists not working with files

Post by FatPanda »

The value for SaveKeys.SAVE_FILE_NAME.Value is "SAVE_FILE".
We started the project with Unity 5.6, but we upgraded to Unity 2017.2.03f to support Android 8.0, that´s when some testers (not all, maybe 1 of 10) reported that their save data was deleted and had to start all over again. We think is because we upgraded Unity and it changed the paths.
As a temporal workaround we changed the path to: Application.persistentDataPath + "/MonkeynautsSave/" + SaveKeys.SAVE_FILE_NAME.Value + ".bytes"; so we have better control over the folder where it saves.
Do you think this change would resolve this issue in future updates we make to the game or do you know if this issue was solved?. We don´t want our users to lose their save data when we launch the game or update the game.
You mentioned that if this isn´t an absolute path it will be writing to the SD card, but, shouldn´t "ES2.Exist" be able to read that file int that path?
Thanks again for the help again, and sorry for the trouble.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: ES2.Exists not working with files

Post by Joel »

Hi there,

If you specify a relative path, Easy Save automatically prepends Unity's Application.persistentDataPath, so essentially your absolute path is exactly the same as specifying a relative path. Also note that the path which changed was Application.persistentDataPath.

With your current AndroidManifest, this will not be /data/data/com.PocketRocket.Monkeynauts/files/ because it specifies the permission android.permission.WRITE_EXTERNAL_STORAGE. This also means that if they remove the SD card, the data will be lost.

Unity should not change the Application.persistentDataPath again, but if you're worried about it, you might want to change your AndroidManifest to write to internal storage, and use the path /data/data/com.PocketRocket.Monkeynauts/files/.

You may be better off asking about this on the Unity forums however, as we're only going on what we've read, and we've not been able to replicate this at our end before. Unity staff should have a better idea of what is happening.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply