I have an iPhone game that I am working on an Android build for with a system where everything is dynamically instanced in a singular generic game scene and I divide the assets in different levels into their own AssetBundles to reduce upfront download size. There is a loading system in place to attempt to load the AssetBundle associated with the current level from the StreamingAssets directory, or my downloaded data, or just download it if it’s not found in either of those places.
I usually package these files with the game for test builds and throw them all into the StreamingAssets directory, this works find on the iPhone because I can access them simply at (Application.dataPath + “/Raw/” + fileName). However on my Android device I am having a difficult time locating these files. I’ve tried a couple different file paths with no success and admittedly I’m something of a novice when it comes to Android development so I am just sort of wandering through this. I can see via debug test in adb that Application.dataPath on the Android is “/data/app/[installed apk name].apk/” and by opening my built apk as an archive I can see the correct bundles reside in the “assets” directory but (Application.dataPath + “/assets/” + fileName) fails to find them correctly. After researching a bit I also tried (Application.dataPath + “!/assets/” + fileName) with the same results.
I’m thinking now that either there is an issue with how I am checking the validity of a file using System.IO.FileInfo:
FileInfo fileInfo = new FileInfo(filePath);
if (fileInfo == null || fileInfo.Exists == false) {
// File not found.
}
I’ve also noticed that when receiving debug text featureing the Application.dataPath from logcat the installed name of the apk is different than the name of the apk I built with Unity, although I assume this is normal behavior.
Does anyone have any file IO experience on Android and feel like pointing me in the right direction? It would be much appreciated.
Thank you for taking the time to read this long winded post.
So I was never able to figure out if it is possible to use the System.IO.FileInfo class to check the existence of a file that is added to your Android .APK file through the StreamingAssets directory. At this point I really doubt it’s possible at all. The reason for this is that the .APK file is an archive, as you may know you can open a .APK file using any archiving utility (WinRAR for example) to inspect it’s contents as I touched on above. So the FileInfo class apparently does not support archives like this.
Fortunately the WWW class does support a URI in the style of a JAR URL. So instead I am just pointing my WWW object at the location where the file might be (using the correct JAR URL syntax) and seeing if I come back with an error.
This forums post was extremely insightful in showing how exactly to open a file from the StreamingAssets folder. I’m kind of surprised that this issue isn’t better documented, but hopefully in the future this post will save someone a lot of time.
In review:
Don’t use System.IO.FileInfo to access files that are archived in your .APK
WWW is your best friend.
The correct URI to access StreamingAssets on Android devices is: “jar:file://” + Application.dataPath + “!/assets/” + fileName
I may be a little late to the party, but it I managed to do it without WWW, @mpavlinsky.
Streaming Assets remain uncompressed in APK/OBB archive, so they can be read directly - if you know their offset and size. And once you do such approach is ~10 times faster (on my device at least), does not suffer memory duplication issue (WWW does) and can be used synchronously (not in a coroutine) and in any thread.
Long story short, I created Better Streaming Assets plugin that does exactly that, comes for free and is open source.
@gwiazdorrr Hello and thank you for the code. Can you help me a little ? Lets say I have a StreamingAssets folder with a video “name.mp4” in it, and I build the application with binary split(with obb). How can I get the path to the video inside the obb file. Thanks.