download the ane : APKExpansionFilesv2.2.2  

if your app exceeded 50MB, you can add one or two expansion files ("main" and "patch") on Google Play Developer Console, each file can be up to 2GB.


if you want use the jobb tool (in the Android SDK)
encrypt your folder with the cmd
C:\Android\sdk\tools\jobb -d C:\folder\yourFolder\ -o C:\folder\air.com.example.MyApp\main.1000020.air.com.example.MyApp.obb -k secret-key -pn air.com.example.MyApp -pv 1000020
X

Android Obb is an application that lets you create Obb files for Android

Windows

or use this App for Windows

in your app
import flash.display.Sprite;
import flash.filesystem.File;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import com.nativeExtensions.apkExpansionFiles.APKCompleteEvent;
import com.nativeExtensions.apkExpansionFiles.APKExpansionFiles;
public function Main() {
  addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(evt:Event):void {
  var apkExpansionFiles:APKExpansionFiles = new APKExpansionFiles();
  apkExpansionFiles.addEventListener(APKCompleteEvent.APK_COMPLETE, onComplete);
  var BASE64_PUBLIC_KEY:String = "your_public_key";
  var mainVersion:String="1000020"; // the version of the APK that the file was uploaded
  var mainSize:String="18772022"; // the length of the file in bytes
  var mountMain:Boolean=true; // mount the obb file
  var secretKeyMain:String="secret-key"; //the secret jobb key
  //var patchVersion:String="1000020"; // the version of the APK that the file was uploaded
  //var patchSize:String="19619894"; // the length of the file in bytes
  //var mountPatch:Boolean=true; // mount the obb file
  //var secretKeyPatch:String="secret-key"; //the secret jobb key
  apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, true, mainVersion, mainSize, mountMain, secretKeyMain);
  //apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, true, mainVersion, mainSize, mountMain, secretKeyMain, patchVersion, patchSize, mountPatch, secretKeyPatch);
}
private function onComplete(e:APKCompleteEvent):void {
  var loader:Loader = new Loader();
  //var getExternalStorageDirectory:String = e.params.getExternalStorageDirectory; // the shared storage space
  var file:File = new File(e.params.outputDirMain+"myImage.jpg"); // the outpout Main folder
  //var file:File = new File(e.params.outputDirPatch+"myImage.jpg"); // the outpout Patch folder
  var request:URLRequest = new URLRequest(file.url);
  loader.load(request);
  this.addChild(loader);
}
- BASE64_PUBLIC_KEY : available on the Google Play Developer Console, see Services and APIs, it is recommended to encrypt the public key with an actionscript obfuscator.
- it is also recommended to encrypt the secretKeyMain and the secretKeyPatch with an actionscript obfuscator.

and in the app-desciptor.xml
<android>
  <colorDepth>16bit</colorDepth>
  <manifestAdditions>
    <![CDATA[
      <manifest>
        <uses-sdk android:minSdkVersion="9" /><!-- if you use jobb tool -->
        <uses-permission android:name="android.permission.PERMISSION_NAME" />
        <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <application android:enabled="true">
          <activity android:launchMode="singleTop">
            <intent-filter>
              <action android:name="android.intent.action.MAIN"/>
              <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
          </activity>
          <service android:name="com.apk.expansion.downloader.APKDownloaderService" />
          <receiver android:name="com.apk.expansion.downloader.APKAlarmReceiver" />
          <activity android:name="com.apk.expansion.downloader.APKDownloaderActivity"
          android:theme="@android:style/Theme.Dialog"
          android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
        </application>
      </manifest>
    ]]>
  </manifestAdditions>
</android>
<extensions>
  <extensionID>com.nativeExtensions.APKExpansionFiles</extensionID>
</extensions>



if you want use a zip file
import flash.display.Sprite;
import flash.filesystem.File;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import com.nativeExtensions.apkExpansionFiles.APKCompleteEvent;
import com.nativeExtensions.apkExpansionFiles.APKExpansionFiles;
public function Main() {
  addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(evt:Event):void {
  var apkExpansionFiles:APKExpansionFiles = new APKExpansionFiles();
  apkExpansionFiles.addEventListener(APKCompleteEvent.APK_COMPLETE, onComplete);
  var BASE64_PUBLIC_KEY:String = "your_public_key";
  var outputDir:String="/Android/data/"; // the outpout folder
  var mainVersion:String="1000020"; // the version of the APK that the file was uploaded
  var mainSize:String="18682320"; // the length of the file in bytes
  var mainUnzip:Boolean=true; // unzip the file
  //var patchVersion:String="1000020"; // the version of the APK that the file was uploaded
  //var patchSize:String="14923834"; // the length of the file in bytes
  //var patchUnzip:Boolean=true; // unzip the file
  apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, false, mainVersion, mainSize, mainUnzip, outputDir); // only main obb file
  //apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, false, mainVersion, mainSize, mainUnzip, outputDir, patchVersion, patchSize, patchUnzip); // main and patch obb files
}
private function onComplete(e:APKCompleteEvent):void {
  var loader:Loader = new Loader();
  //var getExternalStorageDirectory:String = e.params.getExternalStorageDirectory; // the shared storage space
  var file:File = new File(e.params.outputDirMain+"myImage.jpg"); // the outpout Main folder
  //var file:File = new File(e.params.outputDirPatch+"myImage.jpg"); // the outpout Patch folder
  var request:URLRequest = new URLRequest(file.url);
  loader.load(request);
  this.addChild(loader);
}



if you don't want use jobb or zip files, if your obb is a swf for example
import flash.display.Sprite;
import flash.filesystem.File;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import com.nativeExtensions.apkExpansionFiles.APKCompleteEvent;
import com.nativeExtensions.apkExpansionFiles.APKExpansionFiles;
public function Main() {
  addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private var mainVersion:String="1000020"; // the version of the APK that the file was uploaded
//private var patchVersion:String="1000020"; // the version of the APK that the file was uploaded
private function onAddedToStage(evt:Event):void {
  var apkExpansionFiles:APKExpansionFiles = new APKExpansionFiles();
  apkExpansionFiles.addEventListener(APKCompleteEvent.APK_COMPLETE, onComplete);
  var BASE64_PUBLIC_KEY:String = "your_public_key";
  var mainSize:String="18682320"; // the length of the file in bytes
  var mainUnzip:Boolean=false; // unzip the file
  //var patchSize:String="14923834"; // the length of the file in bytes
  //var patchUnzip:Boolean=false; // unzip the file
  apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, false, mainVersion, mainSize, mainUnzip); // only main obb file
  //apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, false, mainVersion, mainSize, mainUnzip, null, patchVersion, patchSize, patchUnzip); // main and patch obb files
}
private function onComplete(e:APKCompleteEvent):void {
  var mainObbFile:File = new File(e.params.getExternalStorageDirectory+"/Android/obb/"+e.params.packageName+"/main."+mainVersion+"."+e.params.packageName+".obb");
  var loader:Loader = new Loader();
  var request:URLRequest = new URLRequest(mainObbFile.url);
  loader.load(request);
  this.addChild(loader);
}





79 comments

Your native extension has a progress event?

The extension manages and greatly simplifies this process and performs the download with a minimal amount of code from you.

Hi,

Thanks a lot for these ANE.

I have a problem, i want to use the first method: "jobb tool to generate an obb file".

All its ok, i uploaded an APK and OBB to google Play console but when i download the app from the store (all its ok, its show that the size is 250mb). Its ok because its download 250mb but when i run it, show me these message:

ERROR_COULD_NOT_MOUNT

I have check the public key, mainVersion, mainSize, mountMain = true, and the secretKeyMain of the jobb tool command.

What means that could not mount? Why?

Thanks again!

One more thing, the obb file exist because i navigate into SD card and i see these folder structure:

Android/obb/air.xxx.xxxxx.xxx/main.xxx.xxx.xxxx.obb

Best regards!

jobb tool sometimes doesn't generate valid encrypted OBB file, I had the same problem with native Android application.
Copy your folder to the root of the C drive (C:\folder\yourFolder\).
Create a new folder (C:\folder\air.com.example.MyApp\) where the obb file is output.
It should work better.

Thank you very much pol!

Thank you for your work!
I am using your ane,but I am stuck.
The problem is when I package my project to apk then an error occur.
The error is

aapt tool failed:C:\Users\www.new-PC\AppData\Local\Temp\4466b6a7-2f1f-4efd-b512-
975ba6731a8f\res\layout\aneapkexpansionfiles.xml:34: error: Error: No resource f
ound that matches the given name (at 'text' with value '@string/oMB').

can you help me?

I have resolved! Thank you

I am facing issue in implementing obb file method. I am getting error message "ERROR_PERMISSION_DENIED!!!!"

Which is occuring as obb file is not mounted. I decompiled the jar files and found that parameters passed to mountobb function are not correct (storage.mountObb(obbDirMain, outputFolder, mount_main_listener);) The second parameter should be key which is used to used to encrypt the OBB. Due to this obb is not mounted.

Can you please update the ane after fixing this issue.

thanks

The second parameter is not an error, I have not change the variable name but it work.

Your application does not have permission to use this OBB. This could be because the OBB indicates it's owned by a different package or some other error.

I am having the same problem as 'yxf' above. How did he resolve it?

Also, have any of you encountered this issue:
https://code.google.com/p/android/issues/detail?id=61881
(Looks like the one 'girish' is facing.)

I have resolved the problem, the problem was with jobb command to generate obb. Instead of using (-pn air.com.example.MyApp ), i was using (-pn com.example.MyApp) due to which i was facing "ERROR_PERMISSION_DENIED!!!!".

hi,

I am facing below issue, have anyone got and fixed this
Install the apk and launch the game from same screen(select open instead of Done).
Observe that downloading pop up gets appeared.
After completing 5 % download press device home key.
Again from home screen click on the game icon.
Observe that downloading UI window disappears.

The same behaviour occured in sample application also.

I have found that download activity is destroyed in this scenario. I am facing difficulty in fixing this as I can't make changes in lib. If possible, can you provide me the source code, so that I can try something to fix this issue.

Thanks
girish

Hi,
When running the app I get "Looking for resources to download" than the app crashes " unfortunately the app has stopped "
any Ideas?

Thanks,
Asaf

@girish
Adobe Air destroy the native activity when you click on the game icon, "<activity android:launchMode="singleTop">" should solve this problem.

@Asaf
"Looking for resources to download" : the size or the version of your obb is not correct (the version of your obb is available on Google play).

Hi,

Thank you for this great ane.
I was really grateful when I found a free ane for this important issue.

However I did not get it to work yet.
I get this in ddms, and the application freezes with a window written (Appname \n res/raw/icon.jpg)
The file I uploaded is a zip file.
Here is a ddms log.

Any help will be greatly appreciated.

02-18 23:02:59.984: W/LVLDL(1288): Aborting request for download main.1002000.air.appid.obb: too many redirects
02-18 23:02:59.984: W/System.err(1288): com.google.android.vending.expansion.downloader.impl.DownloadThread$StopRequest: too many redirects
02-18 23:02:59.992: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.handleRedirect(DownloadThread.java:775)
02-18 23:02:59.992: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.handleExceptionalStatus(DownloadThread.java:735)
02-18 23:02:59.992: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.executeDownload(DownloadThread.java:299)
02-18 23:02:59.992: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.run(DownloadThread.java:236)
02-18 23:02:59.992: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloaderService.onHandleIntent(DownloaderService.java:1078)
02-18 23:03:00.031: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.CustomIntentService$ServiceHandler.handleMessage(CustomIntentService.java:104)
02-18 23:03:00.031: W/System.err(1288): at android.os.Handler.dispatchMessage(Handler.java:99)
02-18 23:03:00.031: W/System.err(1288): at android.os.Looper.loop(Looper.java:130)
02-18 23:03:00.031: W/System.err(1288): at android.os.HandlerThread.run(HandlerThread.java:60)
02-18 23:03:00.062: I/StatusBarManagerService(1781): UPDATE-appname: res/raw/icon.jpg , 0x108008a
02-18 23:03:00.375: I/StatusBarManagerService(1781): UPDATE-appname: Connecting to the download server , 0x1080082
02-18 23:03:00.757: W/LVLDL(1288): Aborting request for download main.1002000.air.appid.obb: too many redirects
02-18 23:03:00.757: W/System.err(1288): com.google.android.vending.expansion.downloader.impl.DownloadThread$StopRequest: too many redirects
02-18 23:03:00.757: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.handleRedirect(DownloadThread.java:775)
02-18 23:03:00.757: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.handleExceptionalStatus(DownloadThread.java:735)
02-18 23:03:00.757: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.executeDownload(DownloadThread.java:299)
02-18 23:03:00.757: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloadThread.run(DownloadThread.java:236)
02-18 23:03:00.757: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.DownloaderService.onHandleIntent(DownloaderService.java:1078)
02-18 23:03:00.757: W/System.err(1288): at com.google.android.vending.expansion.downloader.impl.CustomIntentService$ServiceHandler.handleMessage(CustomIntentService.java:104)
02-18 23:03:00.757: W/System.err(1288): at android.os.Handler.dispatchMessage(Handler.java:99)
02-18 23:03:00.757: W/System.err(1288): at android.os.Looper.loop(Looper.java:130)
02-18 23:03:00.757: W/System.err(1288): at android.os.HandlerThread.run(HandlerThread.java:60)
02-18 23:03:00.812: I/StatusBarManagerService(1781): UPDATE-appname: res/raw/icon.jpg , 0x108008a

I am sorry, the above problem have been solved by re-uploading the apk with new version number and uploading the obb again.
Of course I updated the version number in my apk code also.
I do not understand, but now it works.

Hi,

I am developing a android app with a expansion file after some days I got it works, but now I have a problem, I think related with the expansion file, normally works but sometimes the screen doesn't change from black and I have to minimize and enter again to the app to see everything.

I've checked the sdk console and when I got the error log says:

03-12 16:35:18.601: W/System.err(25260): java.lang.IllegalArgumentException: Make sure the SurfaceView or associated SurfaceHolder has a valid Surface
03-12 16:35:18.601: W/System.err(25260): at com.google.android.gles_jni.EGLImpl._eglCreateWindowSurface(Native Method)
03-12 16:35:18.601: W/System.err(25260): at com.google.android.gles_jni.EGLImpl.eglCreateWindowSurface(EGLImpl.java:92)
03-12 16:35:18.601: W/System.err(25260): at com.adobe.air.FlashEGL.CreateWindowSurface(FlashEGL.java:571)
03-12 16:35:18.601: W/System.err(25260): at com.adobe.air.customHandler.callTimeoutFunction(Native Method)
03-12 16:35:18.601: W/System.err(25260): at com.adobe.air.customHandler.callTimeoutFunction(Native Method)
03-12 16:35:18.601: W/System.err(25260): at com.adobe.air.customHandler.handleMessage(customHandler.java:22)
03-12 16:35:18.601: W/System.err(25260): at android.os.Handler.dispatchMessage(Handler.java:99)
03-12 16:35:18.601: W/System.err(25260): at android.os.Looper.loop(Looper.java:137)
03-12 16:35:18.601: W/System.err(25260): at android.app.ActivityThread.main(ActivityThread.java:5493)
03-12 16:35:18.601: W/System.err(25260): at java.lang.reflect.Method.invokeNative(Native Method)
03-12 16:35:18.601: W/System.err(25260): at java.lang.reflect.Method.invoke(Method.java:525)
03-12 16:35:18.601: W/System.err(25260): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
03-12 16:35:18.601: W/System.err(25260): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
03-12 16:35:18.601: W/System.err(25260): at dalvik.system.NativeStart.main(Native Method)

I don't know what the SurfaceView is... Any idea?

Any help will be greatly appreciated.

Hi - thanks for making this available. I went to try it out and in my app when I make the apkExpansionFiles.expansionFilesDelivered call nothing happens... no error messages - nothing. I have the manifest updated as shown and the ANE is included correctly in the package. Anyone else run into this?

Mark, Are you using flash?
If you are using flash you have to be sure what your manifest says when you publish the app because the flash publish dialog rewrites the manifest.

1- Write the correct manifest
2- Without open the publish target settings, publish the app.
3- Then it works...

The APKCompleteEvent.APK_COMPLETE doesnt call the function, any ideas?

@Giovani
What phone do you use and Android version ?

Tested on Sansumg Galaxy Tab (2.3)
Motorola razr i (4.2)

I use flash cc

Nevermind, solved it

Sorry to bother again everything works fine the first time I open after instalation, it downloads the main.obb file, extract it(zip) and load the files I want, but if I cole the app, when I open it again nothing happens, I only get a box with the app name and the oncomplete function is never called

I have same problem as Giovani. When I first run app, id downloads main expansion, and everything runs ok. But when I run app second time, it hangs on ane intent with app name on black box and nothing else happens...

Ok... there is a bad solution for above problem.
Check if proper folder with expansion package files exists. If true launch app, if false launch APKExpansionFiles ane and download package...

But i think that ane should check if folder exists and dispatch complete event, or some different event so you can react properly :>

P.s. Pol2095 - do You have sources of your ANE on github, so people could fork???

I use the Google downloader library, it's a google bug not a bug of my ane, but I don't have this bug, it's strange. You use a jobb file or a zip file.
The size and the version of your obb are correct ?

I'm using zip file. Size and version are correct, as package is downloaded from google play correctly at first run.

I have another problem. On some devices when using files from downloaded package, screen stays black :D But, if i use files packaged with app, or copied manualy to device, then everything is ok :D
I'm using pureMVC as code pattern...

Ok. Black screen was caused by "containsVideo" bug, that was supposed to be fixed sinse AIR 3.8/3.9 :P

hi- pol.
i am using your ane. thanks. and i have same problem as Weaver.
i can't solved
can you help me?

The error is

aapt tool failed:C:\Users\www.new-PC\AppData\Local\Temp\4466b6a7-2f1f-4efd-b512-
975ba6731a8f\res\layout\aneapkexpansionfiles.xml:34: error: Error: No resource f
ound that matches the given name (at 'text' with value '@string/oMB').

i just active your ane but... error.

Dear pol,

How can I locally debug my app with Flash Builder?

I have done everything above as described - I am using the 2nd method (single main.obb = a zip with 2 folders in it). The app gets downloaded fine, when it opens it says that it's unzipping 62 files (correct). Then the app starts up but I can't hear any of the sounds that I zipped up.

This is my code:
override protected function stageInitialized():void {
var apkExpansionFiles:APKExpansionFiles = new APKExpansionFiles();
apkExpansionFiles.addEventListener(APKCompleteEvent.APK_COMPLETE, onComplete);
var BASE64_PUBLIC_KEY:String = "...";
var outputDir:String="/Android/data/"; // the outpout folder
var mainVersion:String="1000006"; // the version of the APK that the file was uploaded
var mainSize:String="36081528"; // the length of the file in bytes
var mainUnzip:Boolean=true; // unzip the file
apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, false, mainVersion, mainSize, mainUnzip, outputDir); // only main obb file
...
private function onComplete(e:APKCompleteEvent):void {
var file:File = new File(e.params.outputDirMain);
MusicManager.Path = file.url "mus/"; // before using expansion, it was just "mus/"
SField.SpeechFolder = file.url "speech/"; // before, it was just "speech/"
...

After having downloaded the app from Google Play, if I go into:
"Android/obb", there IS "air.gr.digitanet.dylanlydialite" (correct) but inside there is only "temp.main.1000006.air.gr.digitanet.dylanlydialite.obb" 0 bytes long. In "Android/data" there is NO "air.gr.digitanet.dylanlydialite"

If I try to debug from Flash Builder, I just get the "download failed because the resources could not be found" error, even if I manually add the "main.1000006.air.gr.digitanet.dylanlydialite.obb" inside "Android/obb/air.gr.digitanet.dylanlydialite"

Please, can you help?! Feeling a bit desperate here...

In my comment, there is a " " plus sign between "file.url" and "mus/", but it got eaten up somewhere, so there's not a bug there with my code...

GOD! Adding a debug-textfield in my app solved the frigging mystery!
'file.url' REMOVES the final "/" (forward slash) from e.params.outputDirMain.
So my code should have been:
MusicManager.Path = file.url 'plus' "/mus/";
SField.SpeechFolder = file.url 'plus' "/speech/";

THANKS POL. I will certainly donate a (small, sorry I am poor :-( ) amount as soon as my client pays me!

The ane doesn't work when I try to compile I get:
Error: unable to load SWC APKExpansionFilesv2.1.ane: unable to read files:


Looks like the current downloadable .ane file is corrupted. Trying to unzip it I get this error: "An attempt was made to move the file pointer before the beginning of the file"

Any chance you could quickly check and re-upload?

@James
I unzip the ane with 7-zip and I don't have Error.

Hi guys

At the moment all I am getting is

Status: missing main: false patch: false
Failed




Hi Guys, Thanks I finally manged to sort it. This was for one or two reason. Either The obb file was not available yet. IE it takes a while to get published and Two, because the OBB file was not created properly. make sure there are no Java exceptions when creating your OBB file. My only issue now is that once the COMPLETE status is triggered, then you call _expansionFiles.getStatus(1002005), again. BUT the status event never fires after this. If I restart the app the STATUS event never triggeres again.

The same error for me:

aapt tool failed:C:\Users\www.new-PC\AppData\Local\Temp\4466b6a7-2f1f-4efd-b512-
975ba6731a8f\res\layout\aneapkexpansionfiles.xml:34: error: Error: No resource f
ound that matches the given name (at 'text' with value '@string/oMB').

hwo i can fix that?
havent found a way online

HI, guys can you please help me here, im struggiling to get the APK file i wana install this program in any android devices, the program is as follows: Im using adobe flash(Air android)



package
{

import flash.display.MovieClip;
import com.adobe.nativeExtensions.Vibration;
import flash.events.*;
import fl.controls.*;


public class Vibration extends MovieClip
{
public var $vibrate= new Vibration();
public static var isSupported:Boolean;


public function Vibration()
{
// constructor code
if (Vibration.isSupported)
{
SetUpButtons();
}
else
{
trace("Vibration not Supported");

}
}

private function SetUpButtons():void
{
var $Button1:Button = new Button();
$Button1.move(140,150);
$Button1.addEventListener(MouseEvent.CLICK, HandleButtons);
addChild($Button1);

var $Button2:Button = new Button();
$Button2.move(140,350);
$Button2.addEventListener(MouseEvent.CLICK, HandleButtons);
addChild($Button2);

var $Button3:Button = new Button();
$Button3.move(140,550);
$Button3.addEventListener(MouseEvent.CLICK, HandleButtons);
addChild($Button3);




}
private function HandleButtons(evt:MouseEvent):void
{
switch (evt.currentTarget.name)
{
case "Button1" :
$vibrate.vibrate(300);
break;

case "Button2" :
$vibrate.vibrate(500);
break;

case "Button3" :
$vibrate.vibrate(900);
break;


}
}
}
}

Hi guys! I have a question. I initially had created an Adobe Air APK with my app that was 80MB. Now I created a loader app and I want to load my initial app's APK and add it on my loader. Which of the two options should I use? Should I create a jobb file or should I try to handle the file as a swf? Cheers!

The same error for me:

aapt tool failed:C:\Users\www.new-PC\AppData\Local\Temp\4466b6a7-2f1f-4efd-b512-
975ba6731a8f\res\layout\aneapkexpansionfiles.xml:34: error: Error: No resource f
ound that matches the given name (at 'text' with value '@string/oMB').

hwo i can fix that?
havent found a way online

Is it possible to hide/replace the “Please wait” dialog when the app is starting? In my case it is always displayed for a short time, even though the apk-expansion files are already downloaded.

Thanks for your help!

Hi guys!
I have a problem, i want to use the first method: "jobb tool to generate an obb file".
When i run it, show me these message:
ERROR_INTERNAL!!!!

and secon run it...
I only get a box with the app name.
Any help will be greatly appreciated.

Tested on pantech IM-A860S(4.1.2).


When I use this ANE (and only when I use this ANE), I stop getting MOUSE_UP events for the stage if a child is under the pointer. In other words, mouse event *bubbling* stops working.

Perhaps it's related to this problem: http://stackoverflow.com/questions/7880284/android-action-up-even-never-called
But it's hard to tell since I don't have access to the source code. Can I get a fix for this? Or get the source code to attempt to fix it myself?

Hi pol2095,

Thanks for the great ane. Could this ane please be recompiled with intel x86 support?

hey,

when I’m trying to export the build of the apk I get this:

Error occurred while packaging the application:

aapt tool failed:C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:34: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/oMB’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:44: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/oPC’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:88: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/text_button_pause’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:102: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/text_button_cancel’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:128: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/text_paused_cellular’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:135: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/text_paused_cellular_2′).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:148: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/text_button_resume_cellular’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\aneapkexpansionfiles.xml:156: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/text_button_wifi_settings’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\unziperror.xml:29: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/unzip_retry’).

C:\Users\M\AppData\Local\Temp\1d9178bf-244d-4880-ad43-a9b0cfb35564\res\layout\unziperror.xml:43: error: Error: No resource found that matches the given name (at ‘text’ with value ‘@string/unzip_exit’).

How do I solve it, I didn’t find any solution yet.. Thank you.

If for some reason the OBB file has a zip error, there is a bug in the code with the zip class trying to modify the activity from another Thread

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6024)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:820)
at android.view.View.requestLayout(View.java:16455)
at android.view.View.requestLayout(View.java:16455)
at android.view.View.requestLayout(View.java:16455)
at android.view.View.requestLayout(View.java:16455)
at android.view.ViewGroup.removeAllViews(ViewGroup.java:3972)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:341)
at android.app.Activity.setContentView(Activity.java:1929)
at com.apk.expansion.downloader.ZipHelper$1.run(ZipHelper.java:109)


you should use a Handler or View.post()

I get this crash report from google play:

java.lang.NullPointerException
in com.apk.expansion.downloader.APKDownloaderActivity.expansionFilesDelivered

java.lang.RuntimeException: Unable to start activity ComponentInfo{air..../com.apk.expansion.downloader.APKDownloaderActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2063)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2088)
at android.app.ActivityThread.access$600(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4744)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.apk.expansion.downloader.APKDownloaderActivity.expansionFilesDelivered(APKDownloaderActivity.java:181)
at com.apk.expansion.downloader.APKDownloaderActivity.onCreate(APKDownloaderActivity.java:435)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2027)
... 11 more

The app does not start. Most common on nexus 4.4 with android 4.4.

Hi,

Thanks for the great extension. Is there any way that you can publish the source. I'm getting crashes that I'd like to investigate/fix. Do you have an github profile?

Thanks,
Matan

Hi,

Thanks for the great extension. Is there any way that you can publish the source. I'm getting crashes that I'd like to investigate/fix. Do you have an github profile?

Thanks,
Matan

Hi, I am a noob to coding and android dev. Can someone please put step by step instructions on how to do this APK Expansion for AIR?

Our APP is 77 MB.

Please please help .. am stuck badly on this. Need to publish the App as soon as possible.


I get errors when compiling with Distriqt's Facebook ANE. Any Ideas?
failed:C:\...\AppData\Local\Ttemp\fd20db5d-cb00-44ac-919f-474b19053d9b\res\layout\aneapkexpansionfiles.xml:34 error: Error No resource found that matches the given name (at 'text' with vaue '@string/oMC')
and six similar messages after that

Hi, im done create obb with jobb, and now try to read video file inside obb.
Im using adobe flash professional CS6..bit confused about:

in your app
import flash.display.Sprite;
import flash.filesystem.File;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import com.nativeExtensions.apkExpansionFiles.APKCompleteEvent;
import com.nativeExtensions.apkExpansionFiles.APKExpansionFiles;
public function Main() {
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(evt:Event):void {
var apkExpansionFiles:APKExpansionFiles = new APKExpansionFiles();
apkExpansionFiles.addEventListener(APKCompleteEvent.APK_COMPLETE, onComplete);
var BASE64_PUBLIC_KEY:String = "your_public_key";
var mainVersion:String="1000020"; // the version of the APK that the file was uploaded
var mainSize:String="18772022"; // the length of the file in bytes
var mountMain:Boolean=true; // mount the obb file
var secretKeyMain:String="secret-key"; //the secret jobb key
//var patchVersion:String="1000020"; // the version of the APK that the file was uploaded
//var patchSize:String="19619894"; // the length of the file in bytes
//var mountPatch:Boolean=true; // mount the obb file
//var secretKeyPatch:String="secret-key"; //the secret jobb key
apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, true, mainVersion, mainSize, mountMain, secretKeyMain);
//apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, true, mainVersion, mainSize, mountMain, secretKeyMain, patchVersion, patchSize, mountPatch, secretKeyPatch);
}
private function onComplete(e:APKCompleteEvent):void {
var loader:Loader = new Loader();
//var getExternalStorageDirectory:String = e.params.getExternalStorageDirectory; // the shared storage space
var file:File = new File(e.params.outputDirMain "myImage.jpg"); // the outpout Main folder
//var file:File = new File(e.params.outputDirPatch "myImage.jpg"); // the outpout Patch folder
var request:URLRequest = new URLRequest(file.url);
loader.load(request);
this.addChild(loader);
}


tried to add document class with name obb and insert that code but got some error:
1013: The private attribute may be used only on class property definitions.

how to solve this?

@victor
remove private

Some info for people who are running into this problem:

failed:C:\...\fd20db5d-cb00-44ac-919f-474b19053d9b\res\layout\aneapkexpansionfiles.xml:34 error: Error No resource found that matches the given name (at 'text' with vaue '@string/oMC')

I discovered this happens with the latest AIR SDK 16, when using two ANEs that both contain a file named "strings.xml" inside. In my case, it was the Facebook ANE and this APK Extension file ANE.

If possible, removing one of those ANEs will make the error go away.

The real fix has to come from Adobe. Or maybe this ANE's author could rename "strings.xml" to something different.

Hi pol, would you offer different pricing for either support or sharing the sources of the ANE?

Thanks

Hi pol, thanks for the ANE. Sorry for the meager donation for now, but will be sure to add more later once I've cleared my Paypal. Your ANE has been a big help to me where Android has been a huge pain.

Currently, I upload my assets as a zip file which the Android Console converts into obb, then load them using your ANE and unzip the files in Android/data. Question: Is there a way where I can access my assets directly through the obb without unzipping them?

I can't use Android's jobb tool since my files are videos greater than 600MB, and even if I store them in a directory within the assets folder, the jobb tool still throws me the damn FAT error.

Any advice is greatly appreciated. Thanks!

Hi. Would I be able to stream a video file (mp4) from the mounted OBB file using the Video/NetStream/NetConnection classes?

Thanks.

an update of my ane is available (version 2.2), support x86 architecture now.
An app for Windows is available to create obb files.

@nedudgi : you can stream video file (mp4) from the mounted OBB.

I'm using the latest version, I have put the obb file in its place (/sdcard/Android/obb/com.mydomain.myapp/main.1000000.com.mydomain.myapp.obb), and I still get the message "ERROR_COULD_NOT_MOUNT". I have created the obb with jobb, on the drive C as you mentioned in this earlier post: "pol2095 08/11/13 12:27".

Any help is appreciated.

Okay, it seems that the error messages we get are thrown by the OnObbStateChangeListener method of the StorageManager class on the native java side:

http://developer.android.com/reference/android/os/storage/OnObbStateChangeListener.html

Still, this doesn't get me closer to what's wrong with the OBB file. I tried to create OBB files without encryption, specifying no password on the as3 side, an empy string as a password, or null as pasword, but I was only able to get as far as "ERROR_INTERNAL"

So in the end I was able to get it working. I guess the trick was not to use encryption (only a guess though). The jobb command that worked for me was:

jobb -d c:\obbsource\ -o c:\obbdestination\main.1.com.mydomain.myapp.obb -pv 1 -pn com.mydomain.myapp

To my understanding the switch '-pv 1' specifies the MINIMUM version code that the APK needs to have to access this OBB.

In the as3 code I used this line to specify the secret key:

var secretKeyMain:String = null;//the secret jobb key

This all implies of course that the contents of your OBB file will be easy to decompile and access.


Tried compiling this on a Mac Pro, which is 64bit. Errors out with

"Error: Requested extension com.nativeExtensions.APKExpansionFiles is not supported for MacOS-x86."

But this is the 2.2 version you said had a patch for x86 anyway.

Any ideas?


When mounting the OBB -
if the user deletes the app, redownloads it from the store, it errors with
"ERROR_ALREADY_MOUNTED!!!!"

I cannot find a way to check if the OBB is already mounted from the AS3 side.

Hi! I was wondering if there is anyway to test this locally (not through google play store beta testing). Updating the app version on the platform takes a couple of hours each time.

Thanks!

@Martin: just copy the .obb file you created to /storage/emulated/0/Android/obb/com.yourdomain.yourapp/ and you can test locally without uploading.

So, I've implemented the ANE, tested it locally, successfully uploaded to Play, opted in for alpha testing, downloaded my game. Everything works fine.

According to Google, older Play apps don't always download the OBB automatically. The ANE is supposed to to take care of this.

To test this, I've deleted the OBB and re-launched my game. The ANE tries to authenticate my account, but fails with "Download failed because you may not have purchased this app". I have two google accounts linked to my phone. Could it be that the ANE is trying to auth the wrong account? If so, can I tell it which account to authenticate?

Thanks.

i have tired creating expansion files for my application Sorry but i dont understand how to do ... a short videos will help
thnk you

وا عتثق اخويا الله يخليك ... يوميا تندخل لهنا راه مفعفتش سيفذط شي اميل فيه الشرح
والله المعين

Hello,
I tried it and worked fine. Great work, thanks!! Now I mentioned that Air18 is required. Do you have a version for Air17 too??

I am currently using version 2.1 of the expansion files and have successfully used the ane on a previous build. Due to a the requirements of google for them to promote the app I have had to update the targetSdkVersion to 23 in the manifest.

<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23"/>

This has also required me to update my Adobe Air SDK to 20.0.196 to enable the apk to work on Marshmallow 6.0 devices. Without the ANE I have confirmed that the apk works as expected on Marshmallow devices. When I uploaded the app with the ADE/OBB to beta testing the app failed. In debug mode the last trace was "running ANE" before it crashes.

I can confirm that the an identical build with targetSdkVersion="22" worked on Android 6.0.

Is there anything that can be done to fix this issue?

Thanks, Ben



Hello! Thanks for the ane. But I have a problem.
Everything works fine on Android 4, but Android 5 and 6, the application goes down and is warning of "Looking for resources to download"


Please, help me.

Thank you

Hey, Can someone tell me how to add this extension? I was just forced to use adobe air from android studio but I am clueless how to add this extension. I searched around and found on adobe forums to add the .ane file to AS settings but There is no .ane file. Please help

The reason for some ciphered obb file could not be mounted. There a random solt when make obb file, an hashkey generated by PBKDF2WithHmacSHA1. the hashkey from bytes convert to hex string has a bug.
Android. ERROR_COULD_NOT_MOUNT while mounting complex ciphered obb file

Windows jobb app update
You can choose your Android SDK now

Name :


Email (not published) :


Comment :

Allowed markup: [html]