0

I am having trouble getting Unity to locate and read a video file located on the SD card of an Android Device.

When the video file is saved internally on the device itself the persistentDataPath can find and read the file for Unity (the file structure looks something like this: "Android/data/com.name.name/files/video.mp4"). However when the video file is on an SD card and WRITE_EXTERNAL_STORAGE permission is enabled my "File.Exists" returns false.

I believe the problem is that persistentDataPath doesn't point to the same location on the SD card. I've tried for several hours to find a successful file structure but have so far been unsuccessful. (some of the file structures I've tried are: "Android/data/com.name.name/files/video.mp4", "Android/com.name.name/files/video.mp4", "Android/data/com.name.name/video.mp4", "Android/com.name.name/video.mp4").

The only other thing that I can think of that would be causing this issue is for some reason persistentDataPath is ignoring the WRITE_EXTERNAL_STORAGE permission and is looking at its internal path where obviously the video file no longer exists.

c#:

private string videoFilePath;


private void Start()
{
    videoFilePath = Application.persistentDataPath + "/videos/video.mp4";

    if (File.Exists(videoFilePath)
        {
            gameObject.GetComponent<VideoPlayer>().url = 
            videoFilePath;
        }
        else
        {
            GameObject.Find("GUI Text").GetComponentInParent<Text>().text = 
            "Cant find selected video";
        }
}

AndroidManifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Java in c#:

GetAndroidContextExternalFilesDir()
{
    if (Application.platform == RuntimePlatform.Android)
    {
        try
        {
            using (AndroidJavaClass ajc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            {
                using (AndroidJavaObject ajo = ajc.GetStatic<AndroidJavaObject>("currentActivity"))
                {
                    path = ajo.Call<AndroidJavaObject>("getExternalFilesDir", null).Call<string>("getAbsolutePath");
                }
            }
        }
        catch (Exception e)
        {
            GameObject.Find("GUI Text").GetComponentInParent<Text>().text = "Error fetching native Android external storage dir: " + e.Message;
        }
    }
    return path;
}
Mike
  • 51
  • 1
  • 1
  • 4
  • The problem is that the path is different on different devices from different manufacturers.The duplicate shows what it looks like on some devices. This is only true for Android devices. You need to write Android Java plugin to read from an external card in Unity. – Programmer Jan 15 '18 at 21:42
  • Is it possible to explain that a little more? from the original post the example that was given for an Android SD card was "/storage/sdcard0/Android/data/com../files" which I believe is one of the file structures I've tried. You lose me at the Java plugin part. Is it truly that complex of an operation that it requires a plugin? – Mike Jan 15 '18 at 22:28
  • It is `"/storage/sdcard0/Android/data/com../files"` on some devices but like I said in my first comment, it is different on different Android devices from different companies. That's why you need a plugin to do this. You google for Java code to do this. There are many of them out there then compile it into jar or aar plugin and call it from C#. You can also do this with [`AndroidJavaClass`](https://docs.unity3d.com/ScriptReference/AndroidJavaClass.html) without java plugin but it is more complicated if you want to go this route. – Programmer Jan 16 '18 at 00:14
  • I believe I have found what you are describing and added it to my original post. I am now directly finding and calling the path to the external storage instead of using persistentDataPath, however this still is not working. I'm thinking now its has something to do with Unity not wanting to look at the SD card. – Mike Jan 16 '18 at 00:34

0 Answers0