Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

Extra data files from Google Play

Discussion in 'Android' started by Daniel_Brauer, Mar 27, 2012.

  1. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    We've got a 200MB game that we currently deliver to Android devices via a sub-50MB .apk with the rest of the data loaded via asset bundles using WWW.LoadFromCacheOrDownload(). Our publisher hosts the bundles, and we load all of them close to startup. This takes a reasonable amount of time to download the first time, and then is nearly instantaneous on subsequent launches.

    We've been asked to support Google Play's new additional file hosting, so our new approach is:

    1. Build the initial .apk and asset bundles as usual, but record the sizes of all the asset bundles
    2. Concatenate all the asset bundles into one file. This is our .obb that Google hosts.
    3. Re-build the initial .apk, because Google Play requires that you know the exact size of your .obb ahead of time
    4. At runtime, we use Google's example code to ensure that the .obb is present, and download it if it isn't.
    5. Where we originally used WWW, we now use a BinaryReader and the new AssetBundle.CreateFromMemory() to load each bundle.

    We haven't tested this process with an actual published game, but even testing locally we're seeing two problems:

    1. It's very, very slow. Reading the binary isn't bad, but setting up the bundle seems to cost nearly a second per MB of bundle.
    2. If we build the whole game, we run out of memory and the app crashes after just a few bundles (~40MB) have been loaded.

    We must be doing something wrong, but this is new territory for us and we're not sure what to try next. Can anyone suggest a different approach that would get us similar performance to WWW.LoadFromCacheOrDownload()?
     
  2. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    Try this:
    http://forum.unity3d.com/threads/129042-Android-Builder-Tool

    And the previous thread it points to. It may help you out, although it doesn't yet support Google XAPK.

    Although can I ask a few questions, i'm trying to implement the Google Sample code myself and having trouble.

    Did you setup the Google Play libraries as described on their Dev Guide?
    Did you export them as jars and put them in your \Assets\Plugins\Android\libs?
    The libraries contain their own resources, how did you include this in your Unity project?
     
  3. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    I have received approval to release my sample code. Please do NOT sell or repackage this code. This is meant to be used by the community and for learning purposes only. However, feel free to use it in your free or sold projects if it helps. My only request is that if you make any improvements that you let me know so I can implement these improvements in my project as well. If you can improve on it, please post the new code.

    This was basically figured out through trial and error so I may have redundant steps (I'm not sure if the AndroidManifest.xml files need to match inside of Eclipse). However, in my tests it appears to be working. If there are any other improvements please let me know I'd be happy to get them updated.

    Some known issues I'd like to try to get fixed are:
    1) Fix the Downloader service leaking when the game starts.
    2) Fix the issue with the validation process.
    3) Get a better video solution rather than copying all of them out of the APK into a direct readable location. The built-in video player still plays even when the screen is locked for example. I also don't have audio control over the video so if the user disables audio in the game, the video audio will still play.

    http://dl.dropbox.com/u/602991/XAPKGeneric.zip
     
  4. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    Thanks very much Ferazel, I'm sure this will prove very helpful, I can already see our two versions are very similar.

    So it looks like you manually merged the strings of the Google Play Downloader library with the sample project string right?
     
  5. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    Yup, I just manually merged the XML strings into the one resource file so that the Floky installer would be able to merge the files properly.
     
  6. bpritchard

    bpritchard

    Joined:
    Jan 29, 2009
    Posts:
    444
    Ferazel,

    So this works with the new Google OBB service? We've been doing some working w/it and have gotten close but if we can use an off the shelf solution. Grabbing it now to give it a check!

    Thanks for posting this.
     
  7. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    bpritchard: Yeah, this will download using the XAPK Downloader Sample that Google provides (the downloaded apk files are put it into the OBB directory if that is what you are referring to).That's the idea, I mean it's not a one-step solution, but it should work. At least it works in my tests with those known issues. If you figure out how to properly shutdown the downloader service so that it doesn't leak (as per the logcat) or if you can use their validation async task please let me know and I will update the code.
     
    Last edited: Mar 27, 2012
  8. bpritchard

    bpritchard

    Joined:
    Jan 29, 2009
    Posts:
    444
    @ferazel,

    We'll take a look at it further. Does this also do the Download if there is not a file local (or for older API's that don't support the download of the obb's with the actual apk)?
     
  9. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    bpritchard: I've not been able to test downloading it with the initial download since the application that I'm testing it has not been deployed yet. So I'm not sure how it works with Google's automatic download service with Google Play. However, this downloader does indeed download it from Google's servers if the local file is not present. I think if the file was already there and downloaded from Google's servers the code returns a Download Not Needed response and the app progresses to the next phase of the installation (which in the case of the generic code is copying the streaming assets out of the xapk).

    Hope that helps.
     
  10. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
  11. rho21

    rho21

    Joined:
    Mar 28, 2012
    Posts:
    8
    I've been doing much the same thing as you, I think.

    In the file validation step, I'm finding that almost all of the CRCs fail to match. Is this the same problem you have, and have you got any leads? I'm thinking the problem may be that google's code calculates CRCs for the compressed data, but it looks as though the CRCs stored in the zip file are the correct values for the files once uncompressed.
     
  12. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    That is what I'm finding. However I assumed it may be because I'm/we're using Floky's tool to split the original apk outputted by Unity into two separate ones. I'm trying to find out at what point are the CRCs calculated and stored in the zip. Is it zipalign? apkbuilder?
     
  13. rho21

    rho21

    Joined:
    Mar 28, 2012
    Posts:
    8
    The CRCs in the data file appear to be unchanged from those in the file spat out by Unity, so I imagine it can't be Floky's fault (though it could still be Unity's).
    I tried taking my data file, extracting all the files and putting them into an uncompressed zip. I didn't bother using zipalign on it (this shouldn't be required for the obb files). The CRC check worked fine for this, which suggests that either google's code doesn't work with compressed archives, or zipalign causes the problem.
     
  14. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    Hmm, useful info.
    What happens when you do use zipalign on it? I just tried not using zipalign on our gameData apk and the verification still fails.
     
  15. rho21

    rho21

    Joined:
    Mar 28, 2012
    Posts:
    8
    I've not tried, I'm afraid, but I have managed to determine (after much searching) that the CRC value stored in zip files is for the uncompressed data. I'm pretty certain that the algorithm in Google's SampleDownloaderActivity code doesn't do any decompression, so will always get the wrong value for compressed data. I'm submitting a bug to google about this.

    In my data file, it looks as though all the files are either uncompressed or compressed using the Deflate algorithm. If Google don't fix this quickly, it should be easy enough to adjust the DownloaderActivity to inflate the compressed files before generating the CRC for them. (See java.util.zip.Inflater.) Handling big files might be inconvenient if the device is short of space on the SD card.

    Alternatively, perhaps we could just generate the CRC for the entire data file and test it against a value cached in the installer apk.
     
  16. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    I don't know where to respond now. My concern with combining it into the Floky thread is that if there is a problem with the installer there will be confusion on if it is for the Google XAPK installer or the one that Floky made.

    Anyways, my entire day was consumed by fixing an issue that the review process found with iOS and OS X today so I didn't get anytime to work on Android issues.... hopefully tomorrow... unless I get another rejection.

    My concern with caching a value in the installer APK is that we will need to make a deployment... set that value and then make another deployment. This was one of the reasons why I took out the size verification out of the downloader service to begin with as it is very cumbersome.
     
  17. rho21

    rho21

    Joined:
    Mar 28, 2012
    Posts:
    8
    Agreed, it's not ideal. It could be read from a file which is autogenerated by a new step in floky's tool, I suppose.
     
  18. Manu Jangra

    Manu Jangra

    Joined:
    Mar 29, 2012
    Posts:
    3
    Hi All,

    I have also same problem in using APKX.
    1st thing which format file should be upload on Android Play while uploading apk(Either in zip format or rar)
    2nd:
    if (crc.getValue() != entry.mCRC32)
    {
    Log.e(Constants.TAG, "CRC does not match for entry: "+ entry.mFileName);
    Log.e(Constants.TAG, "In file: " + entry.getZipFileName());
    return false;
    }
    returning false everytime.
    3rd:
    Downloader Service throwing exception.
    4th:
    How to use file which are in yourPackageName.oob folder(may be image,sound or mp4).
     
  19. rho21

    rho21

    Joined:
    Mar 28, 2012
    Posts:
    8
    Your installer apk must be in zip format. APKX files can be in whatever format you want. Google provide a support library for using zip format, plus the apk produced by Unity is already in zip format, so that's probably the easiest choice.

    Yes, as discussed above, this will happen for compressed files.

    Ideally you should read from the apkx files directly, without extracting files from them. This can be done under Unity (as in floky's tool) by making the apkx files in apk format and overriding getPackageCodePath() in your Unity activity. To access the apkx from java code outside Unity, you can address it directly; there are lots of examples in the market expansion package sample code.

    If you must unpack your files before using them, note that Google say "Do not save other data into your obb/ directory. If you must unpack some data, save it into the location specified by getExternalFilesDir()." (From http://developer.android.com/guide/market/expansion-files.html.)
     
    Last edited: Mar 29, 2012
  20. Manu Jangra

    Manu Jangra

    Joined:
    Mar 29, 2012
    Posts:
    3
    When I try to read the file with code:
    ZipResourceFile zrf;
    try {
    zrf = new ZipResourceFile("/mnt/sdcard/Android/obb/pkg.ver.main.obb");
    }
    media player not playing audio/video.

    ????????/
     
  21. rho21

    rho21

    Joined:
    Mar 28, 2012
    Posts:
    8
    It's not necessary, but it might be valuable to test for errors in the download. I don't know how likely these are

    Should that be /mnt/sdcard/Android/obb/<package name>/main.<version>.<package name>.obb ?
    If it's just streaming resources that are failing (such as audio and video), that might be the problem mentioned by Ferazel.

    I'm afraid I don't know much about this problem as it's not affected me yet.
     
  22. Manu Jangra

    Manu Jangra

    Joined:
    Mar 29, 2012
    Posts:
    3
    Application also throwing exception regarding to database is not closed.
    that is ::::
    Finalizing a Cursor that has not been deactivated or closed. database = /data/data/pkgName/databases/DownloadsDB, table = null, query = SELECT APKVERSION,_id,DOWNLOADSTATUS,DOWNLOADFLAGS FROM MetadataColumns LIMIT 1
     
  23. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    Yeah, our application uses a lot of video files to play and the built-in unity VideoPlayer doesn't work when you override the code path. So in my example code I made another Async task that copies the files that were put into the streaming assets folder into the getExternalDir() location and in your code for playing these video files back you just need to get the Application.getPersistentDataPath() + "/" + fileName when you perform a call to the Handheld.PlayFullScreenVideo().

    In regards to the Database issue I don't think I'm getting that exception when I'm performing my deployments. I will check on that today.
     
  24. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    After doing a deployment with my code, the Google sample does NOT work with Honeycomb (3.x) devices. It seems that the set progress method on the V11 notification was not tested properly because it doesn't work.

    In the CustomNotificationFactory.java make sure you do an API check for 14 or higher before starting the V11 notification because the SetProgress on the Notification.Builder class does NOT support this. Otherwise just use the V3 notification for anything less than ICS.
     
  25. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    Hey Ferazel, first off thanks again for supplying that code.

    I'm going to start looking at using your method for extracting and playing video files but I do have a question. Looking through the code at copyAssetsFromAPK it looks like it's copying everything that is in the assets folder in the APK, I'm not seeing how, or where, it is only copying video files?

    Also just to say that I'm not seeing the issue you are with 3.x devices. Weirdly enough I've found that the version of V11 I'm using doesn't call setProgress, that whole section of code is commented out with different code above it.
     
  26. ZowPac

    ZowPac

    Joined:
    Sep 25, 2009
    Posts:
    58
    Hi,

    I was thinking of trying out this code - while crossing my fingers that floky would have an xapk-enabled AndroidBuilder by the time I got to it, since I've been using it pretty successfully so far - plus I don't know that much about the Android ecosystem as yet.

    What's the status of the code - will there be another release sometime?
     
  27. Surreal

    Surreal

    Joined:
    Dec 10, 2011
    Posts:
    29
    Been following this thread, have not dived into the tool yet but considering it. We're seeing a lot of crashes with attempting to load large assetbundle files on Android -- is anyone aware of a documented limit?
     
  28. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    Sorry for the late response.
    After doing a manual APK extraction from the Floky installer I found out that all of the files that were in the Assets directory were the assets that were in the StreamingAssets folder in Unity. So I copy all of the files that are in the root asset directory out in order to get all the streaming assets out of the APK.
     
  29. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    On the Asset Store Unity has released a "Google Play OBB Downloader" and a "Google Play Application License Verification" has anyone used these yet?
     
  30. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    Wow good catch Haze! I can't believe the community missed this since they were released April 11th. I'm going to download it right now and see if I can take a look at it! Hopefully, this will resolve a problem with needing to extract videos as well as issues with the prime31 plugin not working properly for In-App Billing.

    Edit:
    Initial findings not promising since they do not handle splitting the apk at all. They are still recommending doing asset bundles to handle getting data outside of the APK. This is not a solution in my situation as loading data from an APK is slower (needing to unzip the file) as well as keeping that data in memory.

    Also they have the same bug in regards to the V11 notification. SetProgress is NOT available on API 11 it is only available on API14. So that will need to be fixed as well otherwise it will not function properly on Honeycomb (3.x) devices. Although I don't have a Honeycomb device to test it out on so maybe they did since their downloader activity seems to be quite a bit different.

    Their downloader activity is more advanced than the Google one. It will set the splash screen properly for the initial activity properly.
     
    Last edited: Apr 23, 2012
  31. Fehr

    Fehr

    Joined:
    Mar 3, 2011
    Posts:
    23
    Yeah, we're working with the "Google Play OBB Downloader" on the Asset Store now. Works a charm.

    The only current issues to Overcome for us are with accessing the obb files it produces on the sdcard, but otherwise its working well.
     
  32. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    Fehr - Are you resorting to using Asset Bundles then for your dynamically loaded resources? Or did you find a way to launch the Unity activity with a small resource footprint and somehow change the resource path at runtime? Are you playing any fullscreen videos?
     
  33. renardmf

    renardmf

    Joined:
    Jun 29, 2012
    Posts:
    47
    OK, last issue about the expansion apk resource not being found when I ran the installer app was because there was a delay in activating my file on google play.

    Also, got my videos to playback by storing them in the root of StreamingAssets folder and encoding them into mp4s manually.

    I ran into the problem with my game crashing if you started it in portrait mode using Unity's auto-rotation feature. Disabling seems to do the trick for now.

    Thanks again Ferazel for your great work!
     
    Last edited: Jul 5, 2012
  34. subsyaji

    subsyaji

    Joined:
    Aug 3, 2012
    Posts:
    1
    Thanks, helped me allot with validations fix..

    about "3>Get a better video solution rather than copying all of them out of the APK into a direct readable" it only copies the video files rather than all file the zip obb file?? How make it copying all files inside the zip to readable location in the unzip AsyncTask?
    thanks...

    I'm getting AsyncCopyFromAPKOperation(762): NumFiles in copy: 0 TotalCompressed: 0 TotalUncompressed: 0 in logcat... not able unzip single data. or not able to view the data in android/data/
     
    Last edited: Aug 3, 2012
  35. ATMEthan

    ATMEthan

    Joined:
    Dec 27, 2012
    Posts:
    54
    So this eclipse project allows me to use the main and patch obb files instead of hosting the second apk myself?
     
  36. tsondhi2006

    tsondhi2006

    Joined:
    Sep 4, 2016
    Posts:
    10
    can I use assetbundles on .asset files??