For many flash game designers and developers, Android platform is one of the best targets for them to monetize their games. However, without the native support from main advertisement platform like Admob, making money is becoming impossible with free android games. Start from Flash cs5.5, Flash Air gives us a method to use functions from outside native library. For example, we can control Android device volume or device display brightness by native Java code. As we make it as a native extension library, and we can call functions in this library from Flash.

With Flash Air native extensions, we can integrate Admob in flash games and publish them in google play and app store. In this tutorial, I will show some examples about how to write an Admob Flash Air native extensions, and how to put Admob Ads in the flash games.

What is native extension and ANE file?

Native extensions are Adobe Flash Air libraries that contain native code (Java for android) wrapped with an Actionscript API. Therefore, one native extension is made up with two part, native code library (jar for android) and Actionscript wrapper (swc file). As a result, all resources will be packaged into an ANE file. An ANE file is an archive file that contains the necessary libraries and resources for the native extension. In this example, I will create the native code library, Jar file exported from Android project. After that, I will build a simple Flex library to wrap the native library.
Step 1: Create Android Native Library JAR File
Step 2: Create Actionscript Native Extension Wrapper
Step 3: Create Default Native Library by Actionscript
Step 4: Build Native Extension ANE File
Step 5: Full Project Source Code

Create Android Native Extension for Flash Air

First of all, let’s talk about how to create an Flash Air Native extensions. Before we start to create the extension, we need to download Android SDK and setup Android development environment. Here is my working environment

  • Eclipse 4.2.2: build android native library
  • Android SDK r22: build android native library
  • Flash Build 4.6 or Flash Professional 6.0: build android native library and swc
  • Adobe AIR 4.0 SDK: build swc

After getting everything ready, let launch Eclipse and create a new Android project. Here are the step by step instruction.
android 1
android 2
android 3
android 4
android 5

After I click finish, I have got an android project in my Package Explorer. Then, we will add the Flash AIR runtime extensions to this android project. Here are the step by step instruction.

  • Right click on the project
  • Select Properties
  • Click Java Build Path
  • Select the Libraries tab
  • Click Add External JARS and navigate to your air sdk directory and \lib\android, select the FlashRuntimeExtensions.jar and click OK.

android 6
android 7

Implement FREEExtension Interface

Now, let’s create a class called AdmobExtension and this class will be called inside my Flash games to show AdMob ads. This class will implements the FREEExtension interface. This class should have 3 methods:

  • createContext() method accepts a string parameter. The return value should be a class that extends FREContext.
  • dispose() method will be called when the native extension is no longer needed by the flash application. Here we can do some cleanup jobs.
  • initialize() method is called when the native extension is ready to be used.

android 8

public class AdmobExtension implements FREExtension {
	@Override
	public FREContext createContext(String arg0) {
		// TODO Auto-generated method stub
		return new AdmobFREContext();
	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
	}

	@Override
	public void initialize() {
		// TODO Auto-generated method stub
	}
}

Implement FREContext Class

Next, we need to create another class which extends FREContext. This class has two methods:

  • dispose() method will be called when the native extension is no longer needed. We do some cleanup jobs here.
  • getFunctions() method returns a list of FREFunction objects, which returns all methods we can use in flash app.

We need to consider what kind of functions we will provide for our flash app. In this flash air native extension example, I will only provide one native API, which will show an AdMob Ads Banner on the top of the flash app. The function name will be showAdmobBanner. In getFunctions() function, I will tell flash that it can call showAdmobBanner to show AdMob ads banner. Here is the example source code:

public class AdmobFREContext extends FREContext {

	@Override
	public void dispose() {
		// TODO Auto-generated method stub

	}

	@Override
	public Map<String, FREFunction> getFunctions() {
		// TODO Auto-generated method stub
	    Map<String, FREFunction> functions = new HashMap<String, FREFunction>();
	    functions.put("showAdmobBanner", new AdmobBanner());
            //functions.put("anotherAPI", new AnotherAPIClass());
	    return functions;
	}
}

In above source code, I define an external API showAdmobBanner and bind it with AdmobBanner class. Follow the same concept, if you want to provide more API for your flash app, you have to create more class to bind with it. The API name and class name must be unique. Now let’s talk about the AdmobBanner class.

Implement FREFunction Interface

AdMobBanner class implements the interface FREFunction, which is defined in flashruntimeextensions.jar. In AdMobBanner, I will put all my android admob code in function call(FREContext context, FREObject[] args). Here is the sample AdMob source code.

public class AdmobBanner implements FREFunction {
	private AdView adView;
	private final String AD_UNIT_ID = "a14f840b733d0dc";
	
	@Override
	public FREObject call(FREContext context, FREObject[] args) {
		// TODO Auto-generated method stub
		Log.d("Tag","Version 6");
		
	    Activity activity = context.getActivity();
	    Context appContext = activity.getApplicationContext();
	    FrameLayout firstLayout = (FrameLayout) activity.getWindow().getDecorView().findViewById(android.R.id.content);
	    
		adView = new AdView(appContext);
		adView.setAdSize(AdSize.BANNER);
		adView.setAdUnitId(AD_UNIT_ID);
		firstLayout.addView(adView);
		
		AdRequest adRequest = new AdRequest.Builder().build();
		adView.loadAd(adRequest);
	    return null;
	}
}

The above example source code will find the first layout of coming context. Flash Air based android app use FrameLayout as its first layout object, I call it “firstLayout”. Then I create a AdView and add it in the FrameLayout, on the top of all its child views. In the example, I am using Google Play Service to display AdMob ads banner. To use Google Play Service, you have to import Google Play Service library. Here is an tutorial for how to add AdMob Banner with Google Play Services Library. If you want to put AdView in a specific layout, you have to know the layout layers hierarchy of Flash AIR based android apps. The first layer is a FrameLayout container. This container only has one child view, a FrameLayout container. This is the second layer. The second framelayout container has two child views. Both of them are SurfaceView. Therefore, you can either put your AdMob ads banner in first FrameLayout or in second FrameLayout. The following diagram will show you the android app layer hierarchy which is generated by flash air.

Flash AIR Based Android App Layout Layer Hierarchy
Flash AIR Based Android App Layout Layer Hierarchy

Export Android Native Extension as JAR File

In this step, we almost finish the Java code jobs. Now I will export the whole project as Jar file, which will be used to generate ANE file later. To export Android Java project as Jar, please right click on the project and select export. In the coming window, please select JAR file on under Java folder. In next coming window, select src folder in your Java project.

export jar 1
2 - incorrect
2 - correct

Create Actionscript Wrapper for Native Extension

Actionscript Wrapper is basically a Flex library. It will be packaged into ANE file as well. Actionscript Wrapper will build a bridge between your flash project and android native extension. You can include this class in your flash or flex project and call native functions. I am using Flash Builder 4.6 with Adobe AIR 4.0 to generate it. Here are the steps:

  • Create a Flex Library project
  • Create a Controller class that extends EventDispatcher. It is AdmobController in my example

Build Wrapper Class

Inside AdmobController class, we have to declare several functions. The first one is its own constructor function, AdmobController. In this function, I will initialize the extension context. The second one is init(). It will be called automatically when the extension is initialized. The third one is dispose() which will be invoked when the native extension is no longer needed. Let’s look at the Actionscript source code:

		public function AdmobController(target:IEventDispatcher=null)
		{
			super(target);
			extContext = ExtensionContext.createExtensionContext("com.jms.admobextension", "");
			
			if ( !extContext ) {
				throw new Error( "Volume native extension is not supported on this platform." );
			}
		}

		//init
		private function init():void
		{
			extContext.call("init");
		}
		
		//clean up
		public function dispose():void {
			extContext.dispose(); 
		}

Function ExtensionContext.createExtensionContext has two parameters. The first one is extensionID. It is defined in extension.xml file. The second is contextType, it could be a string or null.

Next, I will define some public function to expose the interface methods and call native methods on the extension context. These interface methods will be called in our Flash Air based android app. When these interface methods are called, they will call native extension interface methods which are defined in AdmobFREContext class (in Java project). As my example code, I only define one interface method showAdmobBanner which will call the native extension function AdmobBanner with a null parameters.

		public function showAdmobBanner():void
		{
			extContext.call( "AdmobBanner", null );
		}

Here is the full source code about this Flex library class:

	public class AdmobController extends EventDispatcher
	{
		private var extContext:ExtensionContext;
		public function AdmobController(target:IEventDispatcher=null)
		{
			super(target);
			extContext = ExtensionContext.createExtensionContext("com.jms.admobextension", "");
			
			if ( !extContext ) {
				throw new Error( "Volume native extension is not supported on this platform." );
			}
		}
		
		//init
		private function init():void
		{
			extContext.call("init");
		}
		
		//clean up
		public function dispose():void {
			extContext.dispose(); 
		}
		
		public function showAdmobBanner():void
		{
			extContext.call( "AdmobBanner", null );
		}
	}

Native Extension Configuration

Now, I will show you the extension.xml file. It is a xml file which defines the extension information.

<extension xmlns="http://ns.adobe.com/air/extension/3.1">
    <id>com.jms.admobextension</id>
    <versionNumber>0.0.1</versionNumber>
    <platforms>
        <platform name="Android-ARM">
            <applicationDeployment>
                <nativeLibrary>libAndroidVolumeLib.jar</nativeLibrary>
		<initializer>com.jms.admobextension.AdmobExtension</initializer>
            </applicationDeployment>
        </platform>
        
		<platform name="default">
            <applicationDeployment/>
        </platform>
    </platforms>
</extension>

In this tutorial, I only cover the android native extension. So in extension.xml, you can only find Android-ARM platform and default platform. The id value must be the same as the first parameter of ExtensionContext.createExtensionContext. Value for nativeLibrary is the java JAR file name we already export from Java Android Project. Value for initializer is the class Name in my Android native extension which implements FREEExtension interface. After building the above Flex library, we will get a swc file. In my example, it is named “AdmobLibrary.swc“. Later, we will use it to build

Build Native Extension Flex Library for Default Playform

I have admit this pare is very confused. When I develop my extension project, I also rise a question why we need to create this flex library. In this step, we will get another flex swc library file. It is named AdmobDefault.swc. Actually, it is necessary when we build the ANE file. Now, as my understanding, the purpose of this extension is severing project which is running on Adobe Air platform. To make the native extension more compatible, you’d better to provide all platform native code. For example, provide Android JAR file for android platform, provide IOS binary for IOS platform, and provide Actionscript/Flash/Flex library swc file for desktop platform. This flex library is quite simple. The only rule is keeping the same name and functions as the wrapper class. Here is the source code:

package
{
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	public class AdmobController extends EventDispatcher
	{
		public function AdmobController(target:IEventDispatcher=null)
		{
			super(target);
		}
		
		private function init():void
		{
		}
		
		//clean up
		public function dispose():void {
		}
		
		public function showAdmobBanner():void
		{
		}
	}
}

Build ANE File for Adobe AIR

Currently, the latest Flash Builder will support building ANE files. In case you don’t have Flash Builder, I will demostrate how to build ANE with Adobe AIR ADT tools in command line. The ADT tool is located in AIR_SDK_DIR/bin. To build the ANE file, I group our resource files (generated in above steps) in Adobe AIR SDK folder. Here is the folder structure.
android-flash-air-ane

In above folder structure, there are several points I have to explain:

  • google-play-services-res: this folder contains all resource required by google play service lib. It is copied from google play services lib. You can get all this from Android SDK.
  • android-support-v4.jar: this java library is copied from google play services lib
  • google-play-services.jar: this java library is copied from google play services lib
  • libAndroidVolumeLib.jar: this is generated in step 1. After you export the project to jar file, this file will be the result. You can name this file by yourself. But you must keep it the same file name with the one in extension.xml (mentioned in step 2)
  • library.swf in android folder: this file is extracted from AdmobLibrary.swc which is generated in Step 2. You can open swc by any unzip tools like zip, winrar, or 7zip.
  • library.swf in default folder: this file is extracted from AdmobDefault.swc which is generated in Step 3.
  • AdmobLibrary.swc: generated in step 2
  • extension.xml: generated in step 2
  • ane.bat: a windows bat file which I will create in this step. It only contains one command line to generate ANE file easily
  • platform-android.xml: a configuration file used by ane.bat. Later I will show the example.

After you prepare all the files, you can use following command line to generate ANE file. Please keep mind, all find should be put in Adobe AIR SDK bin folder.

adt -package -target ane Output.ane extension.xml -swc AdmobLibrary.swc -platform Android-ARM -platformoptions platform-android.xml -C android . -platform default -C default .

You can create a bat file (windows batch file) to make it easy to run. The platform-android.xml file tells ADT tools to build all required jar and res file into ANE file together. Here is my example:

<platform xmlns="http://ns.adobe.com/air/extension/4.0"> 
	<packagedDependencies>
		<packagedDependency>android-support-v4.jar</packagedDependency>
		<packagedDependency>google-play-services.jar</packagedDependency> 
	</packagedDependencies> 
	<packagedResources>
		<packagedResource> 
			<packageName>com.google.android.gms</packageName> 
			<folderName>google-play-services-res</folderName> 
		</packagedResource> 
	</packagedResources>
</platform>

Now, we have successfully generated a Android native extension for Adobe AIR based app. Above example is just a simple case to show you how to create AdMob native extension for Adobe AIR Android apps. In real project, you may provide more native function for your flash apps. You can follow these steps to improve your native extension.
flash-admob-example

Get Full Source Code under $9.99


I believe your time is more precious. To save your time, I suggest you to get this full source code. So you can contribute all your effort on your invention and innovation. The full source code is under GPL license. After you get the source code, you can apply it in your own project without any limitation. Here is what you will get:

  • Android AdMob native extension lib source code
  • Flex Actionscript native extension wrapper lib source code
  • FLex Actionscript default lib source code
  • ANE generator tools and source code
  • Flex AdMob Tesing Project Source Code
Previous PostNext Post

14 Comments

  1. I have been purchased full source code but i can’t compile and show message “platform.xml is not supported for platform Android-ARM” help me please? (i changed extension version 3.1 not 4.0 because 4.0 is error)

    Thanks.

    1. Hello,

      My working environment is Flash Build 4.6 with Adobe AIR 4.0 SDK. I suggest you to update your Adobe Air SDK to 4.0

          1. Sory james, i can’t export Output.ane file.
            i used to command “adt -package -target ane Output.ane extension.xml -swc AdmobLibrary.swc -platform Android-ARM -platformoptions platform-android.xml -C android . -platform default -C default .”

            do you have Output.ane file??
            please send file to me.

  2. Hi James. This might not be the right place to ask this, but i didn’t get any other platform. I am trying to get the AdvertisingId from google play services for my AIR app. But i am facing some runtime error. I followed all the points which you quoted here, still no improvement. I am attaching the link for my question in stackoverflow. Please help me to fix that.
    http://stackoverflow.com/questions/25258049/advertisingidclient-getadvertisingidinfocontext-is-thworing-noclassdeffounderr

    1. Have you tried my solution? You can get my whole working solution and integrate it in your project. If you make the ads working, I guess you will make your AdvertisingIdClient working as well.

          1. No. Actually i have written my own code. But not able to embed google-play-services.jar with ANE. Please help me how to do this.

  3. Hello James,

    am a beginner developer ,but i have a project of developing some apps in flash and need some ready codes to place in my different apps .

    you can contact me on my email so we can talk .

    Best regards

    Faisal

Leave a Reply

Your email address will not be published. Required fields are marked *