상세 컨텐츠

본문 제목

Packaging Air for Android APK > 50MB? 에어(air) 액션스크립트 안드로이드 개발 확장파일 올리기 확장파일 참조 관련

ADOBE/ ActionScript

by AlrepondTech 2020. 9. 23. 03:21

본문

반응형

 

 

=================================

=================================

=================================

 

 

 

출처: https://forums.adobe.com/thread/1040074

 

distropolis 2012. 7. 24 오전 8:30

I need to package an Android app that is about 66MB.  The Google Play store allows for expansion files to be used to work around the 50MB APK size limit.

I am currently using Flash Pro CS6 to package the APK. 

 

Is there a way to package and refference the expansion files that Google allows developers to use? 

 

Here is Google's info on this:

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

평균 사용자 등급: 평가 없음 (0 등급)

  • 1. Re: Packaging Air for Android APK > 50MB?Really .... no one here has made an Android app over 50MB?
  • distropolis 2012. 7. 25 오전 8:06 (distropolis에 대한 응답)

  • FiveTomsDown 2012. 8. 30 오후 4:58 (distropolis에 대한 응답)I couldn't find any relevant info either, so I had to make my own downloader for the extra files.It was painful and barely works, but currently it's the only way I know how.
  • I hosted the files on a server I own, and downloaded the files to /sdcard/Android/MYAPPNAME as a .obb file (android file, just rename a zip/rar file to .obb)
  • Hi distropolis,
  •  
  • theoin 2012. 9. 27 오후 2:37 (FiveTomsDown에 대한 응답)


  • Thanks, confused, but greatful someone has successfully tacked this issue!
  • For instance, when I publish an .apk file from Flash Pro 6, there is one file - how did you split it up so that one part is the apk and the other parts get loaded and ... where do they get loaded to, how are they accessed?
  • I was wondering how you did this?
  • Hey FiveTomsDown,
  • 8. Re: Packaging Air for Android APK > 50MB?FiveTomsDown 2012. 9. 27 오후 3:22 (theoin에 대한 응답)

    - ZIP this folder up, rename it to .OBB (android version of ZIP)- using flash.filesystem.File, check if the user directory "Android/MYAPP" exists, if not, make it.- using the flash.filesystem.FileStream class, write the file asynchronously to the folder you created on the android storage
  • I really wish I could be more specific, I really do. But if you google a few of those terms, like FZIP and ByteArray, it should at least send you in the right direction
  • - using FZIP or a similar class solution, extract the data from the .OBB file in runtime to use the assets
  • - Load the .OBB file from the server using a ByteArray method
  • - store the .OBB online on a server
  • - in the original SWF, load large media files (audio and images), externally from a folder
  • But here's a run down of what I did
  • I can't tell you exactly how I did it, due to a contract I had to sign for the project I did it on.
  •  
  • 9. Re: Packaging Air for Android APK > 50MB?theoin 2012. 9. 27 오후 3:37 (FiveTomsDown에 대한 응답)

  • Thanks again.
  • Once I give this a try, if successful, I'll post details.
  • That's really kind of you FiveTomsDown!
  •  
  • 10. Re: Packaging Air for Android APK > 50MB?hi theoin,was your try succesful? It could save my life 
  •  
  • TheArx 2012. 11. 1 오후 5:14 (theoin에 대한 응답)
  • 11. Re: Packaging Air for Android APK > 50MB?myavast1 2012. 11. 17 오후 5:56 (distropolis에 대한 응답)
  • Hope it helps.
  • As another user stated it, I created my own downloader in Flash CS6 for a list of videos I needed.
  •  
import flash.net.URLRequestHeader;

import flash.net.URLLoader;

import flash.net.URLLoaderDataFormat;

import flash.net.URLRequest;

import flash.filesystem.FileStream;

import flash.filesystem.File;

import flash.filesystem.FileMode;

import flash.utils.ByteArray;

import flash.events.ProgressEvent;

import flash.display.Loader;

import flash.events.IOErrorEvent;

import flash.net.NetworkInfo;

import flash.net.NetworkInterface;

For each file I posted this to my server:

    var fileRequest: URLRequest;

var urlLoader: URLLoader;

var header: URLRequestHeader = new URLRequestHeader("Content-Length", "0");

var header2: URLRequestHeader = new URLRequestHeader("Content-Type", fileMimeType);

fileRequest = new URLRequest(fileURL); //video URL

fileRequest.method = URLRequestMethod.GET;

fileRequest.contentType = fileMimeType;

fileRequest.requestHeaders.push(header);

fileRequest.requestHeaders.push(header2);

urlLoader = new URLLoader();

urlLoader.addEventListener(Event.COMPLETE, onDownloadComplete);

urlLoader.addEventListener(ProgressEvent.PROGRESS, onDownloadProgress);

urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onDownloadError);

urlLoader.dataFormat = URLLoaderDataFormat.BINARY;

urlLoader.load(fileRequest);

On successful download save to phone

function onDownloadComplete(evt: Event): void {

    //download complete handler

    var dataD: ByteArray = evt.target.data;

    var fileStream: FileStream = new FileStream();

    var dFile: File = File.applicationStorageDirectory;

    dFile = dFile.resolvePath(fileName);

    fileStream.open(dFile, FileMode.WRITE);

    fileStream.writeBytes(dataD, 0, dataD.length);

    fileStream.addEventListener(Event.COMPLETE, onSaveComplete);

    fileStream.addEventListener(ProgressEvent.PROGRESS, onSaveProgress);

    downloadNextFile();

}

After videos were saved, I loaded them like this:

    //add video

    video = new Video();

video.name = "video";

connect_nc = new NetConnection();

connect_nc.connect(null);

stream_ns = new NetStream(connect_nc);

stream_ns.client = this;

stream_ns.client.onMetaData = onMetaDataFunc;

stream_ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);

video.attachNetStream(stream_ns);

//videos can have a width of 800 or 640

video.width = 880;

video.height = 480;

video.x = (SCENEWIDTH - video.width) / 2;

video.y = 0;

addChild(video);

//video path in device

var videoPath = File.applicationStorageDirectory;

videoPath = videoPath.resolvePath("test.mp4");

stream_ns.play(videoPath.url);

 

 

=================================

=================================

=================================

 

 

출처: https://plus.google.com/117271975527324598054/posts/gDojTpipBE8

AIR mobile app and the 50MB limit
#AIR   #Flashplatform   #mobile  

Let's start with iOS

you have a 50MB limit for OTA (Over The Air App Store download)
but technically there is no limits

I did some tests by embedding videos and produced 800MB+ IPA
that installed fine from iTunes on the Desktop and from Wi-Fi

so why would you want to support OTA 50MB limit ?

- to support 3G/4G download

otherwise your user will receive the message
"This Item is Over 50MB
You must connect to a Wi-Fi network
or use iTunes on your computer to download it."

- to support your own app store downloads

if you use the iOS Enterprise SDK you can basically
setup a web site with links such as

itms-services://?action=download-manifest&url=http://www.domain.com/update.plist

and tell your user to visit www.domain.com to either download or update
their enterprise IPA, without using the official Apple App Store, pretty neat

----

Let's continue with Android

you have a 50MB limit on the APK no matter what

but since 2012 the Android Market raised its limit to 4GB

so you could distribute a very big app, but that does not mean
you can distribute a 800MB APK "as is"

if your total app is as big as 800MB for example

you will distribute a 50MB APK
and one APK expansion file of 750MB

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

in short the rules are
- your APK can never be bigger than 50MB
- you can distribute APK expansion file of maximum 2GB
- you can distribute maximum 2 APK expansion files

----

Let's finnish with AIR =)

here we have 2 kind of problems

1st, we are a not native, something like APK expansions are not supported by default

2nd, because of the way our AS3 code is compiled to bytecode and then JIT-ed or AOT-ed
and because some app stores rules prevent you to dynamically interpret code at runtime
our "main app" HAVE TO fit into 50MB


Scenario 1

your AIR app produce an APK/IPA way bellow 50MB but you have a lot of static assets
like images, videos, sounds, etc.

you need to have a server to download those assets and dynamically load your assets
(Loader class, URLLoader class, Sound.load(), etc.)

you will be able to load SWF files but those must not contain any AS3 code at all

the technique is basic, load your assets from the server
one by one or from a zip file into your application storage directory,
and at runtime load your asset in memory from the local file system

this have the big advantage of allowing you to load/unload your assets in memory,
and keep under tight control the memory usage of your app


Scenario 2

your AIR app produce an APK/IPA under 50MB but that need to load SWF files
containing AS3 code

same as the first scenario, you will need first to download your SWF from a server
and save them in your application storage

but here the difference, when you compile your app to APK/IPA the final app
will contain the bytecode of the external SWF for the AS3 part but not the asset part

for example, if you make a game and you have external file for level1.swf, level2.swf, etc.

and let's say level1.swf contains images, vectors drawing a bit of source code
and the SWF final size is 2MB
inside those 2MB the AS3 byte code could be only 100KB

that means when you "link" level1.swf to your main AIR app
100KB will be added to your final APK/IPA
100KB will be stripped from your level1.swf
and when your app load level1.swf in memory
it will automatically re-connect the AS3 byte code in the right place

but still, with all that your main APK/IPA size will still be limited to 50MB


see more details here
http://blogs.adobe.com/airodynamics/2013/03/08/external-hosting-of-secondary-swfs-for-air-apps-on-ios/

now this way of doing have a lot of gotchas

1st and foremost, once you load an external SWF you can not remove the AS3 byte code part from memory,
in fact you can not remove it or update it or replace it

you can do that with the static assets, if for ex your external SWF contains some images
and then you access the BitmapData, you will be able to remove from memory this BitmapData,
but then you will not be able to replace it with another bitmap

so the best way to see the loading of external SWF is to see them as a ONE TIME ONLY operation

2nd, this will not work for Flex applications.

and 3rd, no matter what the sum of all your external SWF AS3 bytecode and your main app bytecode can not exceed 50MB;
so in the case where you have a game loading 100 external levels and each level have 10MB of AS3 code, well that will not work.

----

My advise would be to avoid Scenario 2 at all cost, and favour loading/unloading assets dynamically
or building game levels dynamically based on external statics assets like XML + images

if you are in a case where the external assets need to be able to execute code
you have alternatives, maybe using JSON could work
or if JSON is a bit limited for your need you could try eden
see https://code.google.com/p/edenrr/

Also take a look at this old but good article about caching downloaded assets
http://www.mikechambers.com/blog/2007/03/19/simple-apollo-offline-caching-example/

last few tricks are about URLRequest

- when you use URLRequest to download a lot of assets under iOS
bare in mind that you can not change the timeout
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLRequestDefaults.html#idleTimeout

since iOS SDK 3.0 the imeout is set to 240 seconds (4 minutes!!!!)
http://stackoverflow.com/questions/2471475/iphone-sdk-url-request-not-timing-out?answertab=active#tab-top "A representative from Apple has divulged that SDK 3.0 and later enforce a minimum timeout of (you guessed it) four minutes:

https://devforums.apple.com/thread/25282

If you try to set a timeout value of less than 240 seconds, it gets clamped up to 240. If you need a shorter timeout, I cast my vote for St3fan's solution."

- if your external content is loaded inside StageWebViev
the URLRequestDefaults are not used, so you can not use useCache, cacheResponse, etc.

An ANE for android exist : http://extensionsforair.com/extensions/apk-expansion-files/ ... I want test it.

번역

 

Just a heads up they recently upped the OTA limit to 100 mb :) Android is still 50, though.

 

yep on the other post relating the story of why this post is almost 6 months old I added a comment about thatㅊ

 

 

=================================

=================================

=================================

 

 

출처: http://stackoverflow.com/questions/15232572/create-expansion-file-for-as3-android-air-app-flash-cs6

 

I have created an AS3 mobile app and exported successfully through flash CS6.
In this .apk I have included my video files (going to be a presentation for Android Tablet). The total size of the .flvs alone is 64mb.
When I tried to upload to Google play I got the (expected) warning about the file size being >50mb.
I have spend two hours trying to find a fix, including using the jobb.bat , zipalign.bat , putting the files into the format of main.1.obb and many other options.
The Google website seems to think that I am using Eclipse (which I’m not I used Flash CS6), but I tried all those tools anyway, but yielded zero results.
I have tried http://developer.android.com/google/play/expansion-files.html -
But seems extremely complex and assumes I have eclipse. I even tried to import the “android-sdk\extras\google\play_apk_expansion” into Flash builder, but is not the right project extension.
I looked all over Stack Overflow to articles such as :
[How to attach a expansion file to an AS3/AIR application
– But no response as of yet
AS3 / AIR Google Play application id and expansion files access
- But no clear answer, and I don’t even know how this got the .obb file in the first place.
APK 50meg+ Expansion Packs and Flash
-But I don’t have a Amazon bucket account. Also not sure what android shared storage is.
Steps to create APK expansion file
– But is using older version of google ( I don’t have the “Add Extra Button” ) Also this is not from a Flash As3 project , and again relies on Eclipse.
APK 50meg+ Expansion Packs and Flash
-But this person already has the .obb file (HOW ?).
As you can see I have tried many different ways, but I can’t simple create the expansion way.
So in Short ;
android flash-cs6 mobile-application android-expansion-files


add a comment

1 Answer

activeoldestvotes

You don't have to prepare obb - no need to use jobb.
The easiest way to use expansion file for air app is to make one small swf as preloader and use it as a main apk and the other swf file (that will be loaded) with all big data is stored in obb file.
so:
preloader.swf -> apk
app.swf -> obb

In this scenario you don't have to make an obb file, you just upload new apk to google play and after uploading apk in expansion file section change 'no expansion file' to 'upload a new file' and select your app.swf file. Google will change swf to obb you don't need to do it.
When you upload your first apk for a new app you won't be able to add an obb file. You have to upload just apk and then add new version of apk - this enables obb option.
Now you have to load app.swf from apk in your preloader class. I'm using something like that:
And you can add a splash screen in preloader ;)
If you have to update obb file you have to also recompile apk with new mainVersion
If you ant to use zip file instead of swf, you have to upload a zip file, and in preloader you have to process it - unpack and use data from unpacked folder.
 

 

 

=================================

=================================

=================================

 

 

출처: http://pol2095.free.fr/Air_APKExpansionFiles

 

 APKExpansionFilesv2.1.ane

APKExpansionFilesv2.1.ane
0.59MB




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


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);
}

 

 


56 comments

Xleo77 04/11/13 19:37

Your native extension has a progress event?

 

pol2095 04/11/13 23:25

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

 

Pablo 07/11/13 22:38

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!

 

Pablo 07/11/13 22:44

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!

 

pol2095 08/11/13 12:27

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.

 

Pablo 09/11/13 09:04

Thank you very much pol! 

 

yxf 14/11/13 04:21

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?

 

yxf 14/11/13 07:40

I have resolved! Thank you

 

girish 15/11/13 08:36

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

 

pol2095 18/11/13 15:15

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.

 

Weaver 29/11/13 18:11

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.)

 

girish 09/12/13 10:58

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!!!!".

 

girish 02/01/14 15:07

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

 

Asaf 17/01/14 08:27

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

 

pol2095 22/01/14 18:54

@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).

 

Abdalla 18/02/14 22:16

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

 

Abdalla 19/02/14 10:16

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.

 

oriolc 12/03/14 17:15

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.

 

Mark 12/03/14 22:35

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?

 

oriolc 13/03/14 11:10

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...

 

Giovani 20/03/14 19:06

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

 

pol2095 23/03/14 15:12

@Giovani
What phone do you use and Android version ?

 

Giovani 24/03/14 21:12

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

 

Giovani 24/03/14 21:18

I use flash cc

 

Giovani 25/03/14 18:47

Nevermind, solved it

 

Giovani 27/03/14 19:44

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

 

greku 04/04/14 12:23

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...

 

greku 04/04/14 13:22

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??? 

 

pol2095 04/04/14 18:05

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 ?

 

greku 06/04/14 00:17

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...

 

greku 06/04/14 00:53

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

 

mamo 08/04/14 13:35

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.

 

Bill Kotsias 11/04/14 17:09

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...

 

Bill Kotsias 11/04/14 17:12

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...

 

Bill Kotsias 12/04/14 16:02

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!

 

James 15/04/14 12:23

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

 

James 15/04/14 23:11

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"

 

James 15/04/14 23:14

Any chance you could quickly check and re-upload?

 

pol2095 17/04/14 14:53

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

 

RW 23/04/14 14:43

Hi guys

At the moment all I am getting is 

Status: missing main: false patch: false
Failed



 

Rw 23/04/14 15:39

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.

 

Andrew 17/05/14 06:37

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

 

Vhutshilo 30/05/14 11:06

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;

            }
        }
    }
}

Tim 18/06/14 09:43

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!

 

Elvis 24/06/14 15:15

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

 

wko 26/06/14 15:19

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!

 

minimumforce 25/07/14 08:53

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).

 

Weaver 04/08/14 18:52

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?

 

Wastedmean 15/08/14 13:35

Hi pol2095,

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

 

Mike 01/09/14 22:01

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.

 

SebaSOFT 19/09/14 15:48

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()

 

Sheamus 07/10/14 10:56

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.

 

Matan 14/10/14 09:14

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

 

Matan 14/10/14 09:15

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

 

Sagar 30/10/14 13:02

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. 

 

DavidF 14/11/14 20:57

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

 

 

반응형

 

728x90

 

=================================

=================================

=================================

 

 

 

출처: https://forums.adobe.com/thread/1241069

Hello Support,

We are building a new version of an app pubished on PlayStore (built with Adobe AIR) and need to embed higher resolution images. This results in my app apk file size which is over 100 MB.

Google allows to upload apks that are <= 50 MB. For apps which require more storage capacity than this limit, expansion files are needed.

 

Can you please inform us about how to incorporate these expansion files with an AIR app?

Is there a native extension or a built-in feature to prepare the expansion files and surpass the limit?

 

I've looked in the forums & there is no definite answer or solution.

 

If this is not possible at present, can you please add it to the wishlist for the next version of Adobe AIR SDK? Or perhaps, release a free/paid native-extension which enables this.

Thanks!

 

평가 미흡(1 / 5)평가 평균 미만(2 / 5)평가 평균(3 / 5)평가 평균 초과(4 / 5)평가 탁월(5 / 5)

public class Main extends Sprite

{

    public
    function Main(): void

    {

        stage.scaleMode = StageScaleMode.NO_SCALE;

        stage.align = StageAlign.TOP_LEFT;

        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

    }

    private
    function onAddedToStage(evt: Event): void

    {

        addChild(Console.GetInstance());

        Console.Trace("Start");

        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 = "1302000"; // the version of the APK that the file was uploaded

        var mainSize: String = "10639971"; // the length of the file in bytes

        var mainUnzip: Boolean = true; // unzip the file

        //var patchVersion:String=”1000024″; // 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, mainVersion, mainSize, mainUnzip, outputDir); // only main obb file

        //apkExpansionFiles.expansionFilesDelivered(BASE64_PUBLIC_KEY, mainVersion, mainSize, mainUnzip, outputDir, patchVersion, patchSize, patchUnzip); // main and patch obb files

    }

    private
    function onComplete(e: APKCompleteEvent): void

    {

        Console.Trace("onComplete");

        for (var key: Object in e.params)

        {

            Console.Trace("Key : " + key + ", Value : " + e.params[key]);

        }

        var conteneurImage: Loader = new Loader();

        var fileName: String = e.params.outputDirMain + "asset/2048-2.png";

        Console.Trace("File name = " + fileName);

        var file: File = new File(fileName); // the outpout Main folder

        Console.Trace("File exists? = " + file.exists);

        //var file:File = new File(e.params.outputDirPatch+”myImage.jpg”);    // the outpout Patch folder

        var image: URLRequest = new URLRequest(file.url);

        conteneurImage.load(image);

        conteneurImage.scaleX = 0.3;

        conteneurImage.scaleY = 0.3;

        var secondImageContainer: Loader = new Loader();

        fileName = e.params.outputDirMain + "asset/2048.png";

        file = new File(fileName);

        image = new URLRequest(file.url);

        secondImageContainer.load(image);

        secondImageContainer.scaleX = 0.3;

        secondImageContainer.scaleY = 0.3;

        secondImageContainer.y = 614;

        this.addChildAt(conteneurImage, 0);

        this.addChildAt(secondImageContainer, 1);

    }

}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Hello,

 

I ran in the same size issue but made my own solution : create a obb (you can put anything you want in it) which in my case is pretty much a zip.

At start, I have some version checking blablabla but in the end what it does is unzip the part needed of the obb on the external storage (yes its easily accessible but there is no code or sensitive data in here).

It works fine.

 

BUT most of the content are swf files I need to load/unload at runtime for performance reason (Memory, ...), problem is now that they are on external storage I get a

*** Security Sandbox Violation ***

which tells me I try to access an incompatible context.

So I set the context in the loader, I then get :

Security sandbox violation: local SWF files cannot use the LoaderContext.securityDomain property.

Seems logical but how can you not be local on a phone (except if you redownload every swf every time : unacceptable).

 

I tried to write in the app directory but it seems it is forbidden on Android, whatever permission you use (which makes sense maybe).

I know I could use Loader.loadBytes to avoid Security violation, maybe that's my next step, although I don't know if it will allow unloading nicely (freeing memory) and loading as fast and swf access working the same (getting subclip properties in them, using ApplicationDomain to create new symbol etc).

So my best solution would be to be able to load a swf on Android "normally" (loader.load) even if it's external storage (ie different directory than application), I just couldn't get around the security issue so far.

Any help welcome.

 

Btw isn't it ironic that I can do whatever I want in the external storage of my application (read/create/writte/delete files and folders) but NOT be able to load them as normal swf afterwards... 

 

 

Edit : just in case you ask : I unzip on "disk" and not just in memory because

1) keeping all the needed swf for the game in memory all along would be too large (150Mo of swf), same with keeping the full obb in memory.

2) unzipping every time I need to load one of them would be too slow, so having a direct access is required.

Also since I can delete the obb file and put a tag version after I unzipped it, this solution has no drawbacks except accessibility to the files for end-user but like I said : not so much of a problem for what I chosed to put there.

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Thats what I did.. which seems silly, one having AIR and rights to read/write/whatever in a folder, should be able to load swf from that folder with no Security issue..

 

So when I load a file I load it twice 

- I load the file with a File

- then I load the byteArray resulting with a Loader loadBytes

What a waste..

 

Works on Android, verified.

Now I am going to check how memory is freed well or not when unloading those file at runtimes on Android (can't have the whole kept in memory all along as said), used to work great when it was Loader.load...

 

PS :

about the obb :

- I just cannot open the full obb to memory every time I need a file in it (way too large).

- loading files in it by stream specifing start pos and end pos in obb seems too much maintenance to me

- parsing for markers in it seems also a bit too slow (although I didn't try)

All in all I prefer to have the file output to "disk" on first launch/patch to get a faster access with no mem issue afterwards, only issue is this "SecurityDomain" which really shouldn't apply in air, in a read/write directory if u ask me (since you can do it anyway, just dirtier/slower).

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Ha thats great!

Well now that I have done my own fixing (even if dirty), I feel a bit lazy to change my solution but maybe I'll give it a try 

 

Some questions though :

Total Obb size is right now 198Mo and should grow a bit bigger by the time its released.

It is accessed often, for small files (like 500Ko, but depends on files and device resolution) and this needs to happen during gameplay, so the whole loading takes <200 ms, so there is just a small freeze when clicking on the stuffs that launch the next wave (yes it has some similitude to a TD), or any other action. Which is totally the case with normal loaders in a local environment even on poor Android devices. Full unloading is necessary too of course.

Can you confirm opening the obb (cant keep 198Mo in Memory, I can keep a reference to some infos but not data), finding and loading a file in it with your ane is that fast ?

 

I'm sorry if I seem insisting on that point, just seems to me a poor device would have a hard time doing that. Maybe if files position+sizes are written as a header in obb and kept in memory for fast finding, anyway let me know.

 

 

=================================

=================================

=================================

 

 

출처: http://stackoverflow.com/questions/13752671/cannot-access-expansion-file-deployed-with-app

Cannot access expansion file deployed with app

I have an AS3/AIR application for deploying on Google Play. The app has an expansion file attached to it. The expansion file is named "main.1000000.air.com.mycompany.myapp12.obb" and it is downloaded along with the app properly.

The problem is I cannot access the expansion file any way I tried, like:

File.applicationStorageDirectory.resolvePath('Android/obb/main.1000000.air.com.mycompany.myapp12.obb');
File.applicationStorageDirectory.resolvePath('/Android/obb/main.1000000.air.com.mycompany.myapp12.obb');
File.applicationStorageDirectory.resolvePath('main.1000000.air.com.mycompany.myapp12.obb');
File.applicationStorageDirectory.resolvePath('/main.1000000.air.com.mycompany.myapp12.obb');

and similar variations. I cannot access the file even when the path while developing on Windows seems to be right. When deployed, I just got the "not found" error in my catch block with the supplied File url property: "app-storage:/Android/obb/main.1000000.air.com.mycompany.myapp12.obb" . I have been looking for the solution and trying various approaches for several days, but I am stuck. Developed on ASUS EEE PAD.

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Try this:

var path : String = "Android/obb/air.com.mycompany.myappli";
var filename : String = "main.1000000.air.com.mycompany.myappli.obb";
var file : File = File.documentsDirectory.resolvePath(path + "/" + filename);
if (file.exists)
{ ... }

Hope this help

 

 

=================================

=================================

=================================

 

 

반응형


관련글 더보기

댓글 영역