Share single file between many android apps (Unity)

Hi,
I have two apps (this same project) with two different package names:

com.app.test1
com.app.test2

And I have two methods:

    public void AddToFile(string value)
    {
        var path = Path.Combine(URL, fileName);

        using (var fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
        {
            using (var sw = new StreamWriter(fs))
            {
                sw.WriteLine(value);

                Debug.Log("AddToFile!");
            }
        }

        LoadFromFile();
    }


    public void LoadFromFile()
    {
        var path = Path.Combine(URL, fileName);

        if (!File.Exists(path))
        {
            Debug.Log("File not exists!");
            return;
        }

        using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (var sr = new StreamReader(fs))
            {
                var text = sr.ReadToEnd();
                fileValue.text = text;

                Debug.Log("LoadFromFile!");
            }
        }
    }

And everything works fine for one app. I can load file I can add some text to existing file (or create new one), but when I try to open this same file from second app I have an error:

System.UnauthorizedAccessException - "Access to the path PATH is denied"

Unity Version: 2021.3.4f1
Target platform: Android 11

I also add permissions to the android manifest (read/write).
Any sugestions?

to what path you are saving?

if its some public path, like downloads/ or so, i think it should work.

Yes, It is a public folder:

    private string URL => Path.Combine(GetAndroidInternalFilesDir(), "Download");


//I found this solution in web:
    private static string GetAndroidInternalFilesDir()
    {
        string[] potentialDirectories = new string[]
        {
        "/mnt/sdcard",
        "/sdcard",
        "/storage/sdcard0",
        "/storage/sdcard1"
        };

        if (Application.platform == RuntimePlatform.Android)
        {
            for (int i = 0; i < potentialDirectories.Length; i++)
            {
                if (Directory.Exists(potentialDirectories[i]))
                {
                    return potentialDirectories[i];
                }
            }
        }

        Debug.LogError("Path not exists!");
        return "";
    }

As I said: If I use only one app - all works fine. But when I try to open this file via second app - I just see an error.

ah ok, not sure then, could try the force internal or force external player settings too, if any difference.
or maybe its more strict on the recent android versions?

Yes, I have few more lines in code:

        if (!hasExternalStorageRead)
            Permission.RequestUserPermission(Permission.ExternalStorageRead);

        if (!hasExternalStorageWrite)
            Permission.RequestUserPermission(Permission.ExternalStorageWrite);

        if (!hasManageExternalStorage)
            Permission.RequestUserPermission("android.permission.MANAGE_EXTERNAL_STORAGE");

In Android 11, they made life and access to such files difficult. As if files are protected for only one application.

could also check if this plugin somehow works from multiple apps
https://github.com/yasirkula/UnityNativeFilePicker

This works fine, but works with copies of the file. Which also boils down to the fact that I don’t have permission to delete the file and force me to create multiple copies. Additionally: However, it forces you to manually enter the path and select the file.

Probably due to the current security in Android 11 - this option is not available. If something changes, I will let you know or be ahead of my update :slight_smile:

Hey! Did you find a solution?

Newer versions of Android have introduced additional security measures for file access. This is not Unity’s fault. And unfortunately, I haven’t found any other solution than keeping access to the file in the cloud or the value in a database - on the network, anyway.

1 Like

Shame :frowning: I suppose the cloud option would be the most reliable anyways. Even if there was a method for sharing files locally on a device (I’m currently reading about Android’s ContentProvider, not sure ), who’s to say they won’t deprecate that in a future release, making your apps not work for your clients over night.