Chapter 4. Permissions, Certificates, and Installation
It is your work in life that is the ultimate seduction.
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 File→AIR Android Settings→Icon 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 Packaging→Google Android→Package 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 File→AIR 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 Android→Manifest Additions→Manifest node.
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 Settings→Applications→Manage 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 Packaging→Google Android→Package 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 File→AIR Android settings→Deployment→Certificate 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.
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.
Paid Applications
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 Settings→Applications→Unknown 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:
AdMob (http://AdMob.com)
Smaato (http://www.smaato.com)
Google (http://www.google.com/mobileads/publisher_home.html)
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.