Any Documentation For Expansion File Support In Build 2013.1082?

http://developer.coronalabs.com/release/2013/1082/

“Android: Expansion file support” is listed in the notes for the CoronaSDK 2013.1082 daily build. I can not find any documentation or guides on how to use that.

Is there any documentation covering expansion files?

It’s a “build.settings” option. You can find documentation on how to enable expansion file support here…

http://docs.coronalabs.com/daily/guide/distribution/buildSettings/index.html#expansion-files

If you set the “usesExpansionFile” to true in your “build.settings” file, then the Corona Simulator will automatically create a *.obb file (ie: the expansion file) when you build for Google Play.  That *.obb file contains all of your project’s assets, except your compiled Lua scripts.

Note that expansion file support also requires you to add Google Licensing (LVL) support as well, which you can set in the “config.lua” file.  This is because Google Licensing provides the URLs needed to download the expansion file’s from Google Play, which Corona or Google Play will automatically download for you.  Documentation on how to set up Google Licensing can be found here…

http://docs.coronalabs.com/daily/api/library/licensing/index.html

So, the only thing you need to do is set up your “build.settings” and “config.lua” file.  You don’t have to add any code to your “main.lua” file… unless of course you want to verify your app is not pirated via our “license” API, which is recommended if it is a paid app.  I suggest that you try to get our Google Licensing sample app working first, then attempt to get expansion file support working afterwards.

The simplest way to test expansion file support is to upload your expansion file with a new version of your APK to Google Play, but not publish it.  When you install your new APK to your Android device, it will automatically download the expansion file from Google Play on startup… although I find it sometimes takes Google Play a couple of hours to realize the change, so you may have to wait a bit.  If you feel more daring, then you can install the expansion file to your Android device directly via Android SDK tool “ddms” using its “File Explorer”.  Google provides some instructions on how to do this via the link below, just note that the path can vary between different devices.

http://developer.android.com/google/play/expansion-files.html#Testing

Anyways, I hope the above helps you out.

We’ll have a more formal announcement of this feature later this week.

@ Josh - we are trying to implement this right now and having trouble figuring out what’s happening. We followed all the directions abover, loaded the APK directly into our device, then ran it. We keep getting a black screen with errors such as the following, which vaguely indicates that some assets are missing?

We use 2013.1089.

Right now the entire process is a black box, and we can’t figure out how to debug it. To help me debug this some more:

  • How can I tell if it is even trying to download the expansion files?

  • According to all the documentations I have read, I am assuming that the expansion file  is downloaded when we launch the app. While the download is happening, what should the users see? a black screen?

thx!

I/SoundDecoder( 9770): ALL MPG123 DECODERS:
I/SoundDecoder( 9770):  generic
I/SoundDecoder( 9770):
I/SoundDecoder( 9770): SUPPORTED MPG123 DECODERS:
I/SoundDecoder( 9770):  generic
I/SoundDecoder( 9770):
I/OpenAL_SLES( 9770): alc_opensles_probe OpenSLES support not found.
I/SoundDecoder_SetError( 9770): MPG123: Seek not supported by stream. (code 23)
I/SoundDecoder_SetError( 9770): I/O error
D/AudioTrack( 9770): set(), Before createTrack().
I/SoundDecoder_SetError( 9770): WAV: Not a RIFF file.
D/AudioTrack( 9770): createTrack(), Before audioFlinger->createTrack().
I/SoundDecoder_SetError( 9770): OGG: Not valid Ogg Vorbis data.
I/SoundDecoder_SetError( 9770): Unsupported codec
D/AudioFlinger( 1208): createTrack(), Before thread->createTrack_l().
D/AudioFlinger( 1208): Track constructor name 4098, calling thread 9770
D/AudioFlinger( 1208): createTrack(), After thread->createTrack_l().
D/AudioTrack( 9770): createTrack(), After audioFlinger->createTrack().
D/AudioTrack( 9770): set(), After createTrack().
D/AudioTrack( 9770): set(), Before new AudioTrackThread().
D/AudioTrack( 9770): set(), After new AudioTrackThread().
I/AudioFlinger( 1208): addTrack_l (4098) 0x4b988 on thread 0x19128
V/AudioPolicyService( 1208): startOutput() tid 1405
V/AudioPolicyService( 1208): AudioPolicyService::startOutput() get Autolock, tid 1405
V/AudioPolicyManagerBase( 1208): startOutput() output 1, stream 3
V/AudioPolicyManagerBase( 1208): changeRefCount() stream 3, count 1
V/AudioPolicyManagerBase( 1208): getNewDevice() selected device 2
D/AudioPolicyManagerBase( 1208): setOutputDevice() output 1 device 2 delayMs 0 calling from virtual android::status_t android::AudioPolicyManagerBase::startOutput(android::audio_io_handle_t, android::AudioSystem::stream_type)
V/AudioPolicyManagerBase( 1208): setOutputDevice() setting same device 2 or null device for output 1
D/AudioPolicyManagerBase( 1208): volume after AudioSystem::linearToSpecifyHtcVolum: -1.000000
D/AudioPolicyManagerBase( 1208): volume after AudioSystem::linearToLog: 0.033113
I/SoundDecoder_SetError( 9770): MPG123: Seek not supported by stream. (code 23)
I/SoundDecoder_SetError( 9770): I/O error
I/SoundDecoder_SetError( 9770): WAV: Not a RIFF file.
I/SoundDecoder_SetError( 9770): OGG: Not valid Ogg Vorbis data.
I/SoundDecoder_SetError( 9770): Unsupported codec
I/Corona  ( 9770): Runtime error
I/Corona  ( 9770): ?:0: attempt to index upvalue ‘?’ (a nil value)
I/Corona  ( 9770): stack traceback:
I/Corona  ( 9770):     [C]: ?
I/Corona  ( 9770):     ?: in function ‘?’
I/Corona  ( 9770):     ?: in function ‘new’
I/Corona  ( 9770):     ?: in function ‘?’
I/Corona  ( 9770):     ?: in function ‘changeScene’
I/Corona  ( 9770):     ?: in function <?:733>
I/Corona  ( 9770):     ?: in main chunk
I/AudioHardwareMSM7X30( 1208): do_aic3254_control (1, 0, 0)
I/AudioHardwareMSM7X30( 1208): aic3254: change rx mode to 13
I/global  ( 9770): Default buffer size used in BufferedInputStream constructor. It would be better to be explicit if an 8k buffer is required.
 

Hey,

Did you upload the apk/expansion file onto Google Play?

akao,

No, the black screen and error is not normal.  The download screen communicates with Google Play to retrieve the expansion file and I find that it takes a few hours until Google’s servers responds with the newest changes made to the app in the Android Developer Console.  So just wait a bit and give it another try.

If you don’t want to wait, you can copy the expansion file to your Android device yourself via the Android SDK tool “ddms”.  That tool has a “File Explorer” under the “Device” menu that allows you to create the expansion file directory and copy your files to the device.  Unfortunately, the path can vary between different devices.  On my Galaxy Nexus device, this would be the expansion file directory path…

   /mnt/sdcard/Android/obb/<my.package.name>/

Now, end-users would not normally see the download screen.  When you buy/download an app from Google Play, the Google Play app will normally download the expansion file 1st and then download the APK 2nd.  The app would not show up in the app listing screen until both files are downloaded, which means everything is ready to go.  That said, Google does threaten that Google Play will not always automatically download the expansion file and do not indicate when this will happen, so we’ve provided a download screen for this type of situation.  Also, the download screen will also appear if the expansion file has gone missing and it will also warn the user if the SD card is no longer mounted.  Also, your “main.lua” file will *not* be executed until after the expansion file has been downloaded (ie: after the download screen has finished doing its job).

Anyways, I hope that helps.  Like I said above, you probably just need to wait a few hours for Google Play to realize the change you’ve made.

We had a similar error.  Using a newer daily build solved it for us.

Also we’ve seen similar errors when we’ve made a mistake setting up the license key.

It’s a “build.settings” option. You can find documentation on how to enable expansion file support here…

http://docs.coronalabs.com/daily/guide/distribution/buildSettings/index.html#expansion-files

If you set the “usesExpansionFile” to true in your “build.settings” file, then the Corona Simulator will automatically create a *.obb file (ie: the expansion file) when you build for Google Play.  That *.obb file contains all of your project’s assets, except your compiled Lua scripts.

Note that expansion file support also requires you to add Google Licensing (LVL) support as well, which you can set in the “config.lua” file.  This is because Google Licensing provides the URLs needed to download the expansion file’s from Google Play, which Corona or Google Play will automatically download for you.  Documentation on how to set up Google Licensing can be found here…

http://docs.coronalabs.com/daily/api/library/licensing/index.html

So, the only thing you need to do is set up your “build.settings” and “config.lua” file.  You don’t have to add any code to your “main.lua” file… unless of course you want to verify your app is not pirated via our “license” API, which is recommended if it is a paid app.  I suggest that you try to get our Google Licensing sample app working first, then attempt to get expansion file support working afterwards.

The simplest way to test expansion file support is to upload your expansion file with a new version of your APK to Google Play, but not publish it.  When you install your new APK to your Android device, it will automatically download the expansion file from Google Play on startup… although I find it sometimes takes Google Play a couple of hours to realize the change, so you may have to wait a bit.  If you feel more daring, then you can install the expansion file to your Android device directly via Android SDK tool “ddms” using its “File Explorer”.  Google provides some instructions on how to do this via the link below, just note that the path can vary between different devices.

http://developer.android.com/google/play/expansion-files.html#Testing

Anyways, I hope the above helps you out.

We’ll have a more formal announcement of this feature later this week.

@ mateosolares - can you tell me which version of the daily build you are using?

@ Josh -

Thanks for the speedy and thorough response. Based on the info in your comment, we were able to run a successful test by manually placing the expansion file onto the device, but downloading the app from the store still isn’t working properly (though we can now see that the app is listed with the correct number of MBs).  We are going to do a fresh build and try again. Will let you know if we have more luck this time.

akao,

I’m wondering if you are running into a Google Licensing error.  Try adding the following code to the top of your “main.lua” file to see if your app is receiving a valid response from Google’s licensing service.

local function onGoogleLicensingResponse(event) print("@@@ event.name = " .. tostring(event.name)) print("@@@ event.provider = " .. tostring(event.provider)) print("@@@ event.isVerified = " .. tostring(event.isVerified)) print("@@@ event.isError = " .. tostring(event.isError)) print("@@@ event.errorType = " .. tostring(event.errorType)) print("@@@ event.response = " .. tostring(event.response)) print("@@@ event.expiration = " .. tostring(event.expiration)) end if system.getInfo("targetAppStore") == "google" then local licensing = require("licensing") licensing.init("google") licensing.verify(onGoogleLicensingResponse) end

The results of the above test will be printed to the Android log which you can view via Android SDK tool “adb logcat” or “ddms”.  I’m thinking that there must be a licensing error that we’re not correctly handling.  Google’s licensing service is supposed to provide Corona the URL to download the expansion file on startup and for some reason your app is not receiving it.  I know we’ve tested for error conditions before, but perhaps you’ve found an edge case that we need to handle.

Unfortunately now we are also getting the same problem. We needed to create a new test application and this app is not working.

We assumed we would just have to wait for google servers to update but it’s been about 24 hours now. (Our first app started working after two hours or so)  If we manually put the odb file in place the app loads.

@akao, we were using build 2013.1088 when it was working.

@Joshua Quick

I’ve tried the code above but I had to comment the "if system.getInfo(“targetAppStore”) == “google” "  bit because on the device system.getInfo(“targetAppStore”)  returns “none”.

[lua]

local function onGoogleLicensingResponse(event)
   print("@@@ event.name = " … tostring(event.name))
   print("@@@ event.provider = " … tostring(event.provider))
   print("@@@ event.isVerified = " … tostring(event.isVerified))
   print("@@@ event.isError = " … tostring(event.isError))
   print("@@@ event.errorType = " … tostring(event.errorType))
   print("@@@ event.response = " … tostring(event.response))
   print("@@@ event.expiration = " … tostring(event.expiration))
end
print ("target store == " … system.getInfo(“targetAppStore”))

– if system.getInfo(“targetAppStore”) == “google” then
   local licensing = require(“licensing”)
   licensing.init(“google”)
   licensing.verify(onGoogleLicensingResponse)
– end

[/lua]

Results in the following

I/Corona  ( 3063): target store == none
I/Corona  ( 3063): @@@ event.name = licensing
I/Corona  ( 3063): @@@ event.provider = google
I/Corona  ( 3063): @@@ event.isVerified = true
I/Corona  ( 3063): @@@ event.isError = nil
I/Corona  ( 3063): @@@ event.errorType = nil
I/Corona  ( 3063): @@@ event.response = Licensed
I/Corona  ( 3063): @@@ event.expiration = 1366685567611

If target app store is returning “none”, then there is your problem.  Corona will not attempt to communicate with Google’s servers to download the expansion file unless your are targeting “Google Play”.  The reason is because expansion file support is a Google Play only feature.  As in, Google Play is responsible for hosting the file.

When you build for Android via the Corona Simulator, you’ll need to select “Google Play” from the Target App Store drop down box.

@Joshua   

Thank you for the prompt reply!   Yes we are certainly setting the target app store to google play.  If I go right back to daily build 2013.1082 the app does start the download.  If I use daily build 2013.1093 it does not.

@akao , perhaps try build 2013.1082 and see if you get the same results as us?

Same here, with 1088 I got the black screen, “adb logcat” showed me an error - maybe an assets “loadingMsgImage” is missing in the newer builds?

V/Corona  (27714): > Class.forName: network.LuaLoader

V/Corona  (27714): < Class.forName: network.LuaLoader

V/Corona  (27714): Loading via reflection: network.LuaLoader

I/dalvikvm(27714): Total arena pages for JIT: 11

I/Corona  (27714): Runtime error

I/Corona  (27714): ?:0: attempt to index field ‘loadingMsgImage’ (a nil value)

I/Corona  (27714): stack traceback:

I/Corona  (27714):     [C]: ?

I/Corona  (27714):     ?: in main chunk

I/Corona  (27714):     [C]: in function ‘require’

I/Corona  (27714):     ?: in function ‘require’

I/Corona  (27714):     ?: in main chunk

With 1082 the loading window is shown.

Ok, right now it doesn’t download the expansion file and throws an alert saying “Network Error: This application requires Internet access to download its resources …”, even when the device is connected to the Internet and the browser works.

But I guess this could be an alert that in reality warns me that my resource file on Google Play is not available yet and I need to wait some more hours…

[EDIT]

Works like a charm now, so the error “Network Error: This application requires Internet access to download its resources …” really meant that Google Play did not grant access to the uploaded expansion file for the first few hours.

[EDIT]

Now tried with 1086, works fine, too. So the regression might have happened in 1087 when the Google licensing module was fixed.

Best,

Andreas

Everyone,

We took a look at this and you’re right, we did break it by mistake in daily build #1088.  The issue was that system.getInfo(“targetAppStore”) and store.target was always returning “none” instead of the targeted app store.  This would prevent Corona from automatically downloading the expansion file on startup, but if you copied the expansion file to the appropriate external storage directory then it would work, which akao has mentioned.

That said, the only issue with the above is that the download screen would be skipped and Corona would attempt to load the “main.lua” file without an expansion file… meaning none of your asset files were there.  This will likely cause Lua runtime errors to occur in your main.lua code because the expected assets are missing, which is the most likely case as to why you are seeing a black screen.  Normally we do not load the main.lua until the expansion file was found which we only check for when targeting Google Play.

The above issue will be fixed in the next daily build.  Sorry about the inconvenience and confusion.  If it scores any points with you, the reason it broke was because we completely refactored our Android build code to support optional plugins which we’re beta testing now.  :)

@ Josh - thanks for the info. We are using #1089, and that would explain why it’s not working for us.

We look forward to trying with with the new daily build.

Just to confirm that it looks like it’s working for us now, using build 2013.1094.

Thank you very much.

We can confirm that it’s working for us using 2013.1094 as well.

@josh - Thanks!

@ Josh - we are trying to implement this right now and having trouble figuring out what’s happening. We followed all the directions abover, loaded the APK directly into our device, then ran it. We keep getting a black screen with errors such as the following, which vaguely indicates that some assets are missing?

We use 2013.1089.

Right now the entire process is a black box, and we can’t figure out how to debug it. To help me debug this some more:

  • How can I tell if it is even trying to download the expansion files?

  • According to all the documentations I have read, I am assuming that the expansion file  is downloaded when we launch the app. While the download is happening, what should the users see? a black screen?

thx!

I/SoundDecoder( 9770): ALL MPG123 DECODERS:
I/SoundDecoder( 9770):  generic
I/SoundDecoder( 9770):
I/SoundDecoder( 9770): SUPPORTED MPG123 DECODERS:
I/SoundDecoder( 9770):  generic
I/SoundDecoder( 9770):
I/OpenAL_SLES( 9770): alc_opensles_probe OpenSLES support not found.
I/SoundDecoder_SetError( 9770): MPG123: Seek not supported by stream. (code 23)
I/SoundDecoder_SetError( 9770): I/O error
D/AudioTrack( 9770): set(), Before createTrack().
I/SoundDecoder_SetError( 9770): WAV: Not a RIFF file.
D/AudioTrack( 9770): createTrack(), Before audioFlinger->createTrack().
I/SoundDecoder_SetError( 9770): OGG: Not valid Ogg Vorbis data.
I/SoundDecoder_SetError( 9770): Unsupported codec
D/AudioFlinger( 1208): createTrack(), Before thread->createTrack_l().
D/AudioFlinger( 1208): Track constructor name 4098, calling thread 9770
D/AudioFlinger( 1208): createTrack(), After thread->createTrack_l().
D/AudioTrack( 9770): createTrack(), After audioFlinger->createTrack().
D/AudioTrack( 9770): set(), After createTrack().
D/AudioTrack( 9770): set(), Before new AudioTrackThread().
D/AudioTrack( 9770): set(), After new AudioTrackThread().
I/AudioFlinger( 1208): addTrack_l (4098) 0x4b988 on thread 0x19128
V/AudioPolicyService( 1208): startOutput() tid 1405
V/AudioPolicyService( 1208): AudioPolicyService::startOutput() get Autolock, tid 1405
V/AudioPolicyManagerBase( 1208): startOutput() output 1, stream 3
V/AudioPolicyManagerBase( 1208): changeRefCount() stream 3, count 1
V/AudioPolicyManagerBase( 1208): getNewDevice() selected device 2
D/AudioPolicyManagerBase( 1208): setOutputDevice() output 1 device 2 delayMs 0 calling from virtual android::status_t android::AudioPolicyManagerBase::startOutput(android::audio_io_handle_t, android::AudioSystem::stream_type)
V/AudioPolicyManagerBase( 1208): setOutputDevice() setting same device 2 or null device for output 1
D/AudioPolicyManagerBase( 1208): volume after AudioSystem::linearToSpecifyHtcVolum: -1.000000
D/AudioPolicyManagerBase( 1208): volume after AudioSystem::linearToLog: 0.033113
I/SoundDecoder_SetError( 9770): MPG123: Seek not supported by stream. (code 23)
I/SoundDecoder_SetError( 9770): I/O error
I/SoundDecoder_SetError( 9770): WAV: Not a RIFF file.
I/SoundDecoder_SetError( 9770): OGG: Not valid Ogg Vorbis data.
I/SoundDecoder_SetError( 9770): Unsupported codec
I/Corona  ( 9770): Runtime error
I/Corona  ( 9770): ?:0: attempt to index upvalue ‘?’ (a nil value)
I/Corona  ( 9770): stack traceback:
I/Corona  ( 9770):     [C]: ?
I/Corona  ( 9770):     ?: in function ‘?’
I/Corona  ( 9770):     ?: in function ‘new’
I/Corona  ( 9770):     ?: in function ‘?’
I/Corona  ( 9770):     ?: in function ‘changeScene’
I/Corona  ( 9770):     ?: in function <?:733>
I/Corona  ( 9770):     ?: in main chunk
I/AudioHardwareMSM7X30( 1208): do_aic3254_control (1, 0, 0)
I/AudioHardwareMSM7X30( 1208): aic3254: change rx mode to 13
I/global  ( 9770): Default buffer size used in BufferedInputStream constructor. It would be better to be explicit if an 8k buffer is required.
 

Hey,

Did you upload the apk/expansion file onto Google Play?

akao,

No, the black screen and error is not normal.  The download screen communicates with Google Play to retrieve the expansion file and I find that it takes a few hours until Google’s servers responds with the newest changes made to the app in the Android Developer Console.  So just wait a bit and give it another try.

If you don’t want to wait, you can copy the expansion file to your Android device yourself via the Android SDK tool “ddms”.  That tool has a “File Explorer” under the “Device” menu that allows you to create the expansion file directory and copy your files to the device.  Unfortunately, the path can vary between different devices.  On my Galaxy Nexus device, this would be the expansion file directory path…

   /mnt/sdcard/Android/obb/<my.package.name>/

Now, end-users would not normally see the download screen.  When you buy/download an app from Google Play, the Google Play app will normally download the expansion file 1st and then download the APK 2nd.  The app would not show up in the app listing screen until both files are downloaded, which means everything is ready to go.  That said, Google does threaten that Google Play will not always automatically download the expansion file and do not indicate when this will happen, so we’ve provided a download screen for this type of situation.  Also, the download screen will also appear if the expansion file has gone missing and it will also warn the user if the SD card is no longer mounted.  Also, your “main.lua” file will *not* be executed until after the expansion file has been downloaded (ie: after the download screen has finished doing its job).

Anyways, I hope that helps.  Like I said above, you probably just need to wait a few hours for Google Play to realize the change you’ve made.