Chapter 4. Permissions, Certificates, and Installation

It is your work in life that is the ultimate seduction.

Pablo Picasso

As a mobile application developer, you are a retailer in a global virtual storefront. You can make applications that live in people’s pockets. This is exciting.

In Chapter 2, you created an application and installed it on your device. Now it is time to put the application out there for the world to see.

The first and most important consideration is the value of your application as a mobile experience. After that discussion, we will review the various files that compose your Android Package (APK) file, and discuss the process of becoming an official Android developer and putting an application in the Android Market. Finally, we will discuss how to make money from your hard work.

Why Mobile?

The mobile marketplace is a cruel world. Users often download an application on impulse, try it once, and may never open it again if their first impression is negative. You should aim for excellence and simplicity. Define your application in one sentence. Find your niche. Make it unique, if not in concept, then in execution.

Also, you should analyze mobile consumption. An application is often only used for a few minutes at a time. Tasks should be completed quickly or in incremental steps saved on the device. Whatever you do, do not attempt to replicate your existing website. Instead, adapt it for mobile or create a companion application.

The APK File

A variant of the JAR format used for compression and archival, APK is the file format used to distribute and install an Android mobile application. You can open an APK file using an archive tool such as WinZip or StuffIt Expander to see what is inside it. An APK file typically includes .swf and application.xml files containing assets, as well as a res folder which contains icons.

Creating the Application Icon

The default system icon is an Android-green icon. Icons need to be 36×36-, 48×48-, or 72×72-pixel PNG images. They are used for low-, medium-, and high-density screens, respectively.

You should make your icon stand out, while clearly identifying your application. Google provides guidelines on how to make icons, and provides a Photoshop template, at http://developer.android.com/guide/practices/ui_guidelines/icon_design.html.

In Flash Professional, go to FileAIR Android SettingsIcon and browse to the icons on your computer.

Note

If you use an icon of the wrong size in Flash Professional, the IDE will prompt you with a message that reads, “One of the specified icons do not have the correct dimensions.”

In Flash Builder, create a directory called icons in the src folder, and place your icons in it. Right-click on your project and select Properties. Then select ActionScript Build PackagingGoogle AndroidPackage Contents and select the icons folder if it is not already selected.

In other tools, add a node to your application descriptor file as follows:

<icon>
<image36x36>icons/36.png</image36x36>
<image48x48>icons/48.png</image48x48>
<image72x72>icons/72.png</image72x72>
</icon>

Alternatively, if you are using the command line, place all your icons in a folder called icons and add it to the end of your statement:

AIR-sdk-path/bin/adt -package -target apk -storetype pkcs12
-keystore yourCertificate.p12 hello.apk Main-app.xml Main.swf icons

Publish your application one last time. Change your application to release mode if it is in debug mode. In Flash Professional, select FileAIR Android settings. Under the Deployment tab, for “Android deployment type,” choose Release.

If you are publishing from the command line, verify that the target is apk:

AIR-sdk-path/bin/adt -package -target apk -storetype pkcs12
-keystore yourCertificate.p12 hello.apk Main-app.xml Main.swf

Choosing the Application Settings

The application descriptor contains application settings, and should look similar to the following code. Note the required or optional annotation, and default, for each setting.

Here are the required tags:

<application xmlns=http://ns.adobe.com/air/application/2.6>
// Last segment specifies the version of AIR required

    <id>com.veronique.MyApplication</id>
    // Universally unique identifier.
    // Android converts ID to a package name by adding  
    // "air." to the beginning.
    // Hyphens are converted to underscore 
    // and digits are preceded by a capital A.

    <filename>MyApplication</filename>
    // name used for the APK package file

    <versionNumber>1.0.0</versionNumber>
    // contains three integers, up to three digits each

    <initialWindow>
    // properties of initial appearance of the application

        <content>Main.swf</content>
        // root swf

        <fullScreen>false</fullScreen>
        // application takes over the whole screen if true

        <aspectRatio>portrait</aspectRatio>
        // portrait (default) or landscape

        <autoOrients>false</autoOrients>
        // true (default) or false

        <visible>true</visible>

        <renderMode>cpu</renderMode>
        // cpu (default) or gpu

    </initialWindow>

</application>

The following tags are optional. They are child nodes of the application tag:

<name>Hello World</name>
// or localized
<name>
    <text xml:lang="en">English name</text>
    <text xml:lang="fr">nom français</text>
</name>
// name as it appears on device. Keep it short

<versionLabel>1.0.0</ versionLabel >
// Displayed in installation dialog

<description>
    <text xml:lang="en">English description</text>
    <text xml:lang="fr">Description française</text>
</description>

<copyright></copyright>

<icon>
    <image36x36>icons/36.png</image36x36>
    <image48x48>icons/48.png</image48x48>
    <image72x72>icons/72.png</image72x72>
</icon>

<customUpdateUI>false</customUpdateUI>
   // Update handled by user on double-click or automatic

<allowBrowserInvocation>false</allowBrowserInvocation>
   // can be launched from link in a browser

<android>
       <manifestAdditions>
        <![CDATA[
        <manifest>
        <uses-permission android:name="android.permission.CAMERA"/>
        <uses-permission android:name="android.permission.INTERNET"/>
        // Add all permissions as children of manifest tag

        <supports-screens android:normalScreens="true"/>
            <uses-feature android:required="true"
            android:name="android.hardware.touchscreen.multitouch"/>
            <application android:enabled="true">
                <activity android:excludeFromRecents="false">
                    <intent-filter>
                        <action
                        android:name="android.intent.action.MAIN"/>
                            <category
                            android:name=
                                "android.intent.category.LAUNCHER"/>
                    </intent-filter>
                </activity>
            </application>
        </manifest>
        ]]>
        </manifestAdditions>
</android>

Setting Permissions

The Android security and privacy model requires permissions to access certain features such as GPS. When clicking the Install button, the user sees the list of permissions and can then make an educated decision to opt out if desired.

Use the permission tag in the application descriptor to list all the permissions needed, as shown in the code below. Permissions cannot be modified at runtime.

Just before installing an application, the Android Market displays the permissions required. Figure 4-1 shows that Queue Manager, an application for managing your Netflix queue, only requires the Internet permission.

Warning

Before submitting your application, verify that you only include the permissions needed. Otherwise, you may filter out a group of users who will not see your application in their version of the Android Market.

<uses-permission android:name="android.permission.INTERNET" />
To make network requests. Can be used for remote debugging

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
To write data to external storage, such as the SDCard

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Read-only access of phone state. Used to mute AIR in case of incoming call

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Access the location information. Fine for GPS location, Coarse for Cell/Wi-Fi

<uses-permission android:name="android.permission.CAMERA" />
Access the device camera

<uses-permission android:name="android.permission.RECORD_AUDIO" />
Access the device microphone

<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
Prevents device from dimming, going in sleep mode and activating keyguard

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Access information on device network interfaces

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Access information on device Wi-Fi networks

Android offers a lot of other settings, only some of which can be set in AIR but not documented. They should all be added to the AndroidManifest AdditionsManifest node.

The Queue Manager application before installation
Figure 4-1. The Queue Manager application before installation

The Android Launcher activity keeps track of the applications that have been launched. If a long press is applied on the home button, a list of recently run applications appears. If you do not want your application to be on this list, add excludeFromRecents to your manifest file as follows:

<android>
<manifestAdditions>
    <![CDATA[
    <manifest>
        <application android:enabled="true">
            <activity android:excludeFromRecents="false">
                <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
        </application>
    </manifest>
    ]]>
    </manifestAdditions>
</android>

Applications are installed on the device memory by default. If you select SettingsApplicationsManage Applications, you will notice that some applications have the option “Move to SD card” (which then becomes “Move to phone”).

However, some Android applications and AIR applications do not have that option. If you type the following at the command line, all applications will now be moved:

adb shell pm setInstallLocation 2

To restore the settings, type the following:

adb shell pm setInstallLocation 0

If you set the installLocation tag to preferExternal, saving internally is not an option. All of your content, including your application, is stored on the SD card. This could be helpful for large applications. Keep in mind that the content is accessible to other applications, and therefore is vulnerable. If the SD card is full, the system falls back to an installation on the device:

<android>
    <manifestAdditions>
    <manifest>
        <attribute name="android:installLocation" value="preferExternal"/>
    </manifest>
    </manifestAdditions>
</android>

Read the Android recommendation regarding what should not be installed externally, online at http://developer.android.com/guide/appendix/install-location.html.

Users can erase the application data. If you want to prevent them from doing this, you can add the allowClearUserData attribute to the android node:

<manifest>
<application android:allowClearUserData="false" />
</manifest>

Warning

At the time of this writing, a bug in Android prevented this setting from working. It should be fixed in a future release.

You can also fine-tune permissions to add specific requirements. For instance, you may have an application which only works for devices with a camera auto-focus. You can add a different type of permission, uses-feature, to inform users of what is needed for your application:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

Android throws an error if a required permission is not set, such as for Internet or GPS, but not others, such as reading the phone state or disabling the keyguard. The criterion is what it considered potentially dangerous for the user. In AIR, the application always fails silently.

Native developers have a larger choice of features, and therefore permissions. You can go to http://developer.android.com/reference/android/Manifest.permission.html to learn about some of the new possibilities. If you see one that you would like to use, send Adobe a feature request, preferably with a use case so that it can be added to the AIR runtime, by going to https://www.adobe.com/cfusion/mmform/index.cfm?name=wishform.

For example, having an API to access contacts would open a lot of possibilities:

<uses-permission android:name="android.permission.READ_CONTACTS" />

Packaging External Resources

If your application has a lot of art, you may want to keep the art external to the application and load it at runtime. In the AIR for Android settings, if you are using Flash Professional, add the resources to the “Included files” list at the bottom of the General tab.

In Flash Builder, create a directory called assets in the scr folder, and place your art in it. Right-click on your project and select Properties. Then select ActionScript Build PackagingGoogle AndroidPackage Contents and select the assets folder if it is not already selected.

If you are using the command line, list the files or the containing folders at the end of the command line:

AIR-sdk-path/bin/adt -package -target apk -storetype pkcs12
-keystore yourCertificate.p12 hello.apk Main-app.xml Main.swf
image.jpg movie.flv data.xml

Another way to handle external files is to store them on the SD card and access them via File Access. You cannot remove files included at the time of installation because it would make the application invalid. You can, however, copy them to the SD card. This is the approach you would use if you want to modify them during the life of the application. We will cover this method in Chapter 6.

Signing Your Application with a Certificate

All applications must be signed before being updated to the Android Market. This enables consumers to identify and establish trust with a developer. The developer signs the certificate using a private key. The private key is different from the one you used during development. Typically, a key generally using ADT is only good for five years.

To create a suitable key in Flash Professional, go to FileAIR Android settingsDeploymentCertificate and fill out every field. The publisher name will appear in the Android Market as you enter it. As before, make a note of the password, since you will need it when you compile your application. Choose Type 2048-RSA, Google’s recommended type.

The certificate must be valid for 25 years. The system only checks the certificate’s expiration date upon installation. If the certificate expires afterward, the application will continue working.

To create a suitable key using AIR ADT and the command line, use the following code, making sure to put your name and country in quotes:

AIR-sdk-path/bin/adt -certificate -cn "FirstName LastName" -c "US"
-validityPeriod 25 2048-RSA myCertificate.p12 myPassword

More information on this is available on the Android developer website, at http://developer.android.com/guide/publishing/app-signing.html.

When/if you later upgrade your application, you must use the same certificate, so keep it in a safe place.

Versioning

Versioning gives you the opportunity to submit fixes and updates to your application. A version number consists of three digits separated by dots, as in 1.0.0, referred to as major.minor.build. Set the version number in Flash Professional in the Settings window. In Flash Builder, open the application descriptor and change the version number in the XML.

For debugging purposes, you can check the version number at runtime from the applicationDescriptor of the NativeApplication.nativeApplication that is an XML object:

import flash.desktop.NativeApplication;

var applicationDescription:XML =
NativeApplication.nativeApplication.applicationDescriptor;

var ns:Namespace = applicationDescription.namespace();
// http://ns.adobe.com/air/application/2.6
var currentVersion:String = applicationDescription.ns::versionNumber;
// 1.0.0

The update to an application appears on the Android Market quickly.

As mentioned earlier in this chapter, the update can be accomplished in two ways. You can specify your preference in the application descriptor, or the user can specify it manually. The following tag implies that the update is handled by the user upon double-clicking:

<customUpdateUI>false</customUpdateUI>

If the user installs an update of your application, previously saved data is preserved.

Registering As an Android Developer

To submit your application to the Android Market, you must have or create a Google account and sign up as an Android developer. You also must pay a one-time registration fee of $25 (see https://market.android.com/publish/signup).

You should read the Android Market Developer Distribution Agreement (http://www.android.com/us/developer-distribution-agreement.html) as well as the content policy which determines what content is allowed (http://www.android.com/market/terms/developer-content-policy.html).

If you are going to sell applications through the Android Market, you need to set up a merchant account with Google Checkout. For more information on this topic, refer to Monetizing Your Application.

Publishing an Application on the Android Market

An AIR application is packaged as a standard Android application. Therefore, you can distribute it via the Android Market or via another website of your choice.

To publish your application, go to the Developer Console page at http://market.android.com/publish/Home and click on the Upload Application button. Figure 4-2 shows the necessary steps to submit an application.

Steps to upload an application to the Android Market
Figure 4-2. Steps to upload an application to the Android Market

Uploading Assets

Select “Upload assets” to upload the APK file. At the time of this writing, the maximum allowed size for this file is 50 MB. You can also upload at least two screenshots at 320×480, 480×854, or 480×800; one high-resolution, 512×512 icon; one promotional graphic at 180×120; a feature graphic at 1,024×500; and the URL to an optional promotional video (must be YouTube).

Unless you select the Marketing Opt-Out button, Google has the right to promote your application in the Android Market or other Google-owned properties.

Listing Details

Upon selecting “Listing details,” you can enter the title, a description, some promotional text, the type, and the category of your application. The default language is English, but you can choose additional languages. As of November 2010, applications need to have a content rating of All, Pre-Teen, Teen, or Mature, as per the Android content policy (see http://www.android.com/us/developer-content-policy.html).

Publishing Options

The Android Market Licensing Service is a protection option to prevent users from copying an application from a device. At runtime, it queries the Android Market to obtain the user’s licensing status. The License Verification Library (LVL) is a component of the Android SDK. It does increase the file size, so choose it only if you are selling your application.

Warning

LVL is a Java-only API with no integration with ActionScript. At the time of this writing, no solution has been offered to protect applications.

Distributing Applications via Adobe InMarket

Adobe offers a service called InMarket that handles distribution of AIR applications, including credit card processing, hosting, and marketing. You receive 70% of the sales revenue. InMarket has an ActionScript license manager that only works within its system. For more information on InMarket, go to http://www.adobe.com/products/inmarket/ or http://www.webkitchen.be/2010/12/02/inmarket-monetizing-your-apps-made-easy/.

Publishing for the Amazon Market

In March 2011, Amazon opened Appstore for Android, which offers Android games and applications as well as Free Amazon applications.

Note that the Amazon store does not do any filtering, so in your application description, clearly indicate the requirement for at least Android 2.2 and an ARMv7-A processor.

To make your application compatible with this Appstore, you must build an APK specifically for it (build a separate one for the Android market). You must use only AIR 2.6 and up, so that you can overwrite the runtime download URI. Adobe and Amazon are working on a more practical solution. Flash Professional CS5.5 offers a pull-down menu: go to AIR for Android settings→Deployment to target the Google Android Market or the Amazon Appstore.

For more information, read http://blogs.adobe.com/cantrell/archives/2011/03/air-2-6-applications-and-the-amazon-appstore-for-android.html.

Controlling Distribution by Using the MAC Address

You may need to develop an application that is only authorized to run on some devices. You could upload it to a server and give the URL to a selected group, but this method is not very secure.

To monitor installation, use the MAC address of the device. The MAC address is the unique identifier for the hardware, mobile device, or desktop.

First, set the Android permissions to have access to network information:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

To obtain the address at runtime, use the NetworkInfo class, which gets a list of interfaces and looks for a hardwareAddress. It is the MAC address for your device:

if (NetworkInfo.isSupported) {
    trace("network information is supported");
}

var network:NetworkInfo = NetworkInfo.networkInfo;
for each (var object:NetworkInterface in network.findInterfaces()) {
    if (object.hardwareAddress) {
        trace(object.hardwareAddress);
    }
}

The address looks something like this:

00:23:76:BB:46:AA.

Launching an AIR Application

The first time a user launches an AIR application, the Adobe AIR license agreement will appear. The user only needs to agree to the terms once.

If you are familiar with developing AIR applications on the desktop, you may have noticed a difference here. The installation warning dialog does not appear on the device. The messaging is handled by the operating system when the application is installed, as it is for native Android applications. Also, downloaded applications are stored in the /data/app directory which is a private directory.

Monetizing Your Application

Before you submit an application, you should become acquainted with other applications already on the Android Market. Visit the AppBrain website (http://www.appbrain.com/apps/) or the Android Market website (https://market.android.com) to see the current applications.

For reference, the website at http://www.appbrain.com/apps/popular/adobe-air/ keeps track of the applications developed using AIR.

Setting up a merchant account with Google Checkout requires that you provide banking and tax information. You only need it for the applications you charge money for. Google’s transaction fee is 30% of the price of your application. The arguments for using the Android Market are security, efficiency, and exposure.

It is up to you to decide whether to charge for your application. Your history is public and available to consumers, so charging a fair price is a good long-term business practice.

Unlike Apple and the Apple Store, Google doesn’t force you to use the Android Market as a distribution channel. Instead, you can place your application on your web server of choice. Your server MIME type needs to be edited, however. The MIME media type for .apk files is application/vnd.android/package-archive.

To install an application on a device via a non-Android Market source, select SettingsApplicationsUnknown Sources. Unless the application is properly documented, this may reduce your audience.

Mobile Ads

If you want to earn money from your work, you can offer your application for free but receive revenues from embedded advertisements. Read Arron La’s story on the revenue he made from his Advanced Task Manager application, at http://arronla.com/2010/08/android-revenue-advanced-task-manager/.

The advertisement displayed in your application is one image with a clickable URL. Here is a short list of some mobile advertising companies:

You must subscribe to get an application ID. At runtime, your application makes a request to receive advertisement information. Indicate the ad’s format (XML is best) and dimensions. Some providers allow you to specify geolocation, age, or gender for targeted ads.

All providers give you an option to test your application with dummy ads before it goes live. Always put the advertisement code in a try catch block. You do not want your application to stop functioning because the provider server is down or sends bad data.

At the time of this writing, mobile advertising providers do not offer an AS3 SDK. You need to download the AS2 version and rewrite it for your purposes. Making straight calls in the standalone application does not seem to provide ad impressions. Instead, use the StageWebView API, which allows you to open a web page within your AIR application to simulate the browser experience. We will cover this topic in Chapter 13.

Reporting

Google Market tracks how many users have downloaded your application. But you may want to also know how users interact with your application. You could track, for instance, which part of your product is most popular and which features could be replaced or removed.

Reporting has become a standard component for many applications. This capability tracks user activity and sends the information to a remote service that stores data and provides analysis.

Google Analytics (http://www.google.com/analytics/), a popular choice in the nonenterprise market, is free and provides an open source ActionScript API. An ActionScript 3 API for Google Analytics data collection, called gaforflash, is available at http://code.google.com/p/gaforflash/. In addition, you can keep up with Google Analytics information by reading the blog athttp://analytics.blogspot.com/2011/01/new-actionscript-3-library-for-api.html.

You need to provide a website profile and some geographic information when you register on Google Analytics. A simple example follows.

To set the Internet permission:

<uses-permission android:name="android.permission.INTERNET" />

To use the Web ID property you received from the service:

import com.google.analytics.GATracker;
import com.google.analytics.AnalyticsTracker;

var tracker:AnalyticsTracker =
            new GATracker(this, "UA-111-222", "AS3", false);
            // current displayObject
            // Unique Web ID
            // tracking mode
            // debug mode

// button press go to section "game"
function pressButton(event:MouseEvent):void {
    tracker.trackerPageView("game");
    tracker.trackEvent("Button", "click", "parameter1", "parameter2");
    // category
    // action
    // additional parameters as needed
}

Conclusion

The distribution model for AIR applications is constantly evolving. Keep informed of new channels. For best practices on mobile distribution, read Jonathan Campos’s article, “Learn from my mobile mistakes,” at http://unitedmindset.com/jonbcampos/2010/12/28/learn-from-my-mobile-mistakes/.

Get Developing Android Applications with Adobe AIR now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.