Expansion File Support for Android

Expansion File Support for Android

As of Daily Build 1082, we’re happy to announce support for Google Play expansion files that will vastly simplify your mobile app development. Why would you want to use expansion files? It turns out that Google Play has a 50MB size limit on APK files. They have this limit so that when the user has to update their app, they don’t have to download all the asset files again, which can take up a long time. To combat this, Google also lets you upload expansion files. These files aren’t meant to be updated since they can be up to 2GB in size.
Downloading an Expansion File

We’ve tried to make it as simple as possible for you to use. Corona SDK will package everything except your Lua scripts into the expansion file, name it properly, and then put it in the correct format. All of this is done locally so even if you have 2GB worth of asset files you won’t have to worry about a slow internet connection. All you have to do is to put a setting in the build.settings file, put your licensing key into config.lua file, and then upload your APK and expansion files onto Google Play. Here are is a sample build.settings file:

Notice the line that says usesExpansionFile = true which will build the expansion file for you to upload ONLY if your build target is the Google Play store. You should also add those 3 permissions so that we can download the expansion files for you. You’ll need add 3 permissions so that we can automatically download the expansion files for you. The android.permission.INTERNET permission lets us download the expansion files from Google’s servers. The expansion files have to be saved in a specific location on external storage so that’s why we need the android.permission.WRITE_EXTERNAL_STORAGE permission. That leaves us with the final permission: com.android.vending.CHECK_LICENSE. In order for us to get the URL to download the expansion file, we have to go through Google Play’s Application Licensing Service. Let’s take a look at config.lua to see how we have to set up licensing.

All you have to do is to put your key into the appropriate section of config.lua and you’re done. This key lets us check with Google’s servers to see which files we need to download and see if we need to download anything new or missing.

If you had to write your application natively in Java, then there are a lot of situations you have have to think about before you can even start your application.

  • What if the user doesn’t have enough space on their external storage? I better check to make sure they have the space.
  • What if the user doesn’t even have their external storage mounted? Looks like I’ll have to check on that first.
  • What if the user doesn’t have a network connection? I better warn them.  
  • What if I updated my APK without updating my expansion file? Guess I’ll need to update my code to use the correct expansion files.
  • What if the user wipes their external storage?  I’ll have to download the files again in a download screen which has to work on all orientations and look good.
  • What if the network fails in the middle of a download? I’ll have to let the user retry the download.
  • What if the user leaves the application while the download is happening? I’ll have to handle the user exiting the app.
  • How will the user know when the expansion files have been downloaded? I’ll need to implement notifications.
  • How do I even make the expansion files? I’ll have to do a ton of research on how to package them.
  • Where should I download the expansion files to? More research time.
  • What can I do to make my life easier? Use Corona SDK!

All of these situations and more are handled by Corona SDK, so you don’t have to even think about them.

Time to go wild with your asset files!

Tags:
,
Perry Clarke
[email protected]
23 Comments
  • Graham Ranson
    Posted at 10:34h, 17 April

    I am happy to say that as of last night GMT we had the HD version of Forever Lost on the Play store with expansion files and it works flawlessly!

  • Stephen Lewis
    Posted at 13:16h, 17 April

    Cool. Now THAT is Coronification!

    What options are available, if any, for doing something similar on iOS, Kindle Fire, and Nook? Is this something Corona Cloud can or will support?

    • Walter
      Posted at 13:56h, 17 April

      Yup, coronification, baby!

      So this is actually a restriction unique to Google Play. You don’t need to worry about this for the other stores.

      • Andreas
        Posted at 06:04h, 18 April

        Hi Walter,

        this is great news, I already have a very nice app lined up to use this now for Google Play ( I even started to code my own content download system some weeks ago, but now this is obsolete ).

        Apart from that – the 50 MB restriction was still in place about two month ago for NOOK store & Samsung Apps, and I guess it still is. On the Android side only the Amazon Android Store is without the limit.

        Another thing: How do you support international localization? How do I put in the German / Japanese / Russian etc. texts for all these notifications? Or did you already implement the texts in all languages?

        Thanks & best,
        Andreas

      • TieLore
        Posted at 12:26h, 18 April

        Actually, last time I uploaded to NOOK, they had a 100MB limit. My game was over that limit, so it appears we need this option for NOOK as well.

  • Emanouel P
    Posted at 09:56h, 18 April

    Very good news indeed.

    Is a expansion file in zip format ?? and would the files in the expansion be placed into the same place in the program??

    thanks in advance

    • dchan
      Posted at 10:28h, 18 April

      The expansion file is in the Opaque Binary Blob(obb) format. It is created and placed in the same directory as your apk file by the simulator. On the device itself it is placed in external storage/Android/obb/package.name directory. You will need to upload your apk to Google or it won’t download automatically.

      • Emanouel P
        Posted at 21:53h, 18 April

        thanks for the info. how do i create that type of file and select what goes into it??

        • Joshua Quick
          Posted at 20:25h, 19 April

          The Corona Simulator will automatically create the expansion file for you as documented by this blog post. It only requires you to make changes to your “build.settings” and “config.lua” file.

          The Corona Simulator puts all of your project’s files inside of the expansion file “except” for your Lua scripts. The APK only contains your scripts and our compiled native code/plugins/libraries.

          You do not have the option to pick and choose what goes into the expansion file. This is to keep things simple for Corona developers.

  • Marc C
    Posted at 10:34h, 18 April

    Can someone tell me if Corona handles the case of checking if the device is out of memory when using the network.download api as well?

    • Joshua Quick
      Posted at 20:19h, 19 April

      Yes, Corona’s download screen will automatically inform the user if external storage is out of space. That said, normally Google Play will automatically download the expansion file for you when the end-user purchases your app, in which case, Google Play will do this check for us.

      Corona also always checks if external storage is mounted on startup (but only if expansion file support is enabled) and warns the user if it is not mounted. This check is done even after downloading the expansion file, because Corona will always do a file existence check. Your main.lua file will not get executed until it is mounted.

  • Jamie
    Posted at 10:54h, 18 April

    Great information! What does “these files aren’t meant to be updated” really mean for devs? The intent is clear, but the reality is less so. If we mess up something that went into the expansion files, is this something we can never repair, or can repair at the risk of annoying customers? How do we update apps when we explicitly do or do not want to update the expansion files? Thanks in advance

  • dittophantassy
    Posted at 13:42h, 18 April

    Is there a way to have resources (images, sounds, etc) both in the resource file and in the apk?
    say I want to update an image and I don’t want to make the user download the expansion file again, can I make the code point the image to a place inside the apk?
    Can I make the expansion file download optional?, like show the user a demo or a help screen if he doesn’t have a connection, or the disk space?
    thanks.

    • Joshua Quick
      Posted at 20:14h, 19 April

      If you need to update a resource file, then the best solution is to create a “patch” expansion file. What you would then have to do is upload a new version of your APK (with a new version code) and upload a “patch” expansion file, but tell the Android Developer Console to use the old “main” expansion file. This is the best way to handle it. Unfortunately, the Corona Simulator does not support the creation of “patch” expansion files, but you can easily do this yourself f you’re feeling a little adventurous. The following instructions indicate how to do this on Mac.

      1) Create a new directory to contain the patch’s files.
      2) Copy your update images and assets to this patch directory.
      3) Ipen a Terminal window and “cd” (ie: change directory) to that directory.
      4) Run the following command line to zip it.
      >> zip -r -0 ../patch.zip *
      5) Rename the zip file to the following…
      >> patch…obb

      I hope this helps.

  • Andreas
    Posted at 00:28h, 22 April

    Hi Joshua,

    how do you support international localization? How do I put in the German / Japanese / Russian etc. texts for all these notifications? Or did you already implement the texts in all languages?

    Thanks & best,
    Andreas

    • Andreas
      Posted at 00:31h, 23 April

      Hi,

      dchan answered this:

      Unfortunately at this time there is no localization for the expansion file download screen. The download screen is not often shown though because normally Google will automatically download the expansion files for you. The download screen only shows up if something goes wrong such as the user wiping their SD card.

      Best,
      Andreas

  • Glory
    Posted at 06:21h, 24 April

    Thanks for finally writing about >Expansion File Support
    for Android | Corona Labs <Loved it!

  • Matt
    Posted at 16:03h, 31 May

    Ok.. I followed this and have tried to build a Google Play with the latest 1134 build and it builds one big .apk file still. Is that correct?

    • Matt
      Posted at 17:24h, 31 May

      nevermind… my problem was a misspelling in the config.lua

  • mike kelly
    Posted at 13:05h, 19 March

    can someone tell me why this is generating an error:
    settings =
    {
    orientation =
    {
    default = “portrait”,
    supported =
    {
    “portrait”, “portraitUpsideDown”,
    },
    },
    android =
    {
    versionCode = “50”,
    usesExpansionFile = true,
    largeHeap = true,
    usesPermissions =
    {
    “android.permission.WRITE_EXTERNAL_STORAGE”,
    “android.permission.VIBRATE”,
    “android.permission.CLEAR_APP_USER_DATA”,
    “android.permission.CAMERA”,
    “android.permission.GET_TASKS”,
    “android.permission.INTERNAL_SYSTEM_WINDOW”,
    “android.permission.MODIFY_AUDIO_SETTINGS”,
    “android.permission.INSTALL_PACKAGES”,
    “android.permission.READ_EXTERNAL_STORAGE”,
    “android.permission.READ_FRAME_BUFFER”,
    “android.permission.RECORD_AUDIO”,
    “android.permission.SET_PROCESS_LIMIT”,
    “android.permission.INTERNET”,
    “com.android.vending.CHECK_LICENSE”,
    },
    usesFeatures =
    { name = “android.hardware.camera”, required = true },
    {name=”android.hardware.screen.portrait”, required = true},
    { name = “android.hardware.microphone”, required = true },
    { name = “android.hardware.location”, required = false },
    { name = “android.hardware.location.gps”, required = false },
    supportsScreens =
    {
    smallScreens = true,
    normalScreens = true,
    largeScreens = true,
    xlargelScreens = true,
    },

    },
    }

  • J. A. Whye
    Posted at 19:20h, 27 December

    You say, “All you have to do is to put your key into the appropriate section…”

    What key? Where do I find/generate that?

    Jay

  • Robert Phillips
    Posted at 08:23h, 20 January

    What happens if the user’s device does not have an external storage card?

    Cheers,

    Rob

  • Nanda
    Posted at 23:51h, 05 August

    We have an asset that needs to go into the main apk file and not into the extension file (obb). So is it possible to select which files go into apk and which go into the extension file since right now, all the assets are going into the obb file which is not what we want.