It is entirely possible that the user base for your app consists solely of yourself.
However, in most cases, you are going to be giving your app to others, free or for some sort of fee.
This chapter outlines things you will need to think about when distributing your app.
Understanding this chapter requires that you have read the core chapters of this book, particularly the chapter on signing your app.
While being able to sign your application reliably with a production key is necessary for publishing a production application, it is not sufficient. Particularly for the Play Store, there are other things you must do, or should do, as part of getting ready to release your application.
You need to supply versionCode
and versionName
values in your build.gradle
file. The value of versionName
is what users and
prospective users will see in terms of the label associated with your
application version (e.g., “1.0.1”, “System V”, “Loquacious Llama”).
More important, though, is the value of versionCode
, which
needs to be an integer increasing with each release — that is
how Android tells whether some edition of your APK is an upgrade over
what the user currently has.
You also need to make sure that your application ID is going to be unique. If somebody tries downloading your application onto their device, and some other application is already installed with that same package name, your application will fail to install.
Your application ID defaults to be the value of your package
attribute in your <manifest>
element in the manifest. You can
override the application ID using applicationId
properties
in defaultConfig
or a product flavor in build.gradle
. You can
also append an applicationIdSuffix
tied to a build type or
product flavor in
Gradle as well.
Since the manifest’s package
also provides the base Java package
for your project, and since you hopefully named your Java packages
with something based on a domain name you own or something else
demonstrably unique, this should not cause a huge problem.
Also, bear in mind that your application ID must be unique across all applications on the Play Store, should you choose to distribute that way.
Your <application>
element needs to specify android:icon
and
android:label
attributes, to supply the display name and icon that will be
associated with the application in the My Applications list on the
device and related screens. Your activities will inherit the icon if
they do not specify icons of their own.
If you have graphic design skills, the Android developer site has guidelines for creating icons that will match other icons in the system.
In production, try to minimize unnecessary logging, particularly at
low logging levels (e.g., debug). Remember that even if Android does
not actually log the information, whatever processing is involved in
making the Log.d()
call will still be done, unless you arrange to
skip the processing somehow. You could outright delete the extraneous
logging calls, or wrap them in an if()
test:
if (BuildConfig.DEBUG) {
Log.d(TAG, "This is what happened");
}
Here, BuildConfig.DEBUG
is a public static final boolean
value,
supplied by Android, that indicates whether you are building for
debug or production. Whether you adjust the definition by hand or by
automating the build process is up to you. But, when BuildConfig.DEBUG
is false
, any work that would have been done to build up the actual
Log
invocation will be skipped, saving CPU cycles and battery life.
Conversely, error logs become even more important in production. Sometimes, you have difficulty reproducing bugs “in the lab” and only encounter them on customer devices. Being able to get stack traces from those devices could make a major difference in your ability to get the bug fixed rapidly.
First, in addition to your regular exception handlers, consider catching everything those handlers miss, notably runtime exceptions:
Thread.setDefaultUncaughtExceptionHandler(onBlooey);
This will route all uncaught exceptions to an onBlooey
handler:
private Thread.UncaughtExceptionHandler onBlooey=
new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable ex) {
Log.e(TAG, "Uncaught exception", ex);
}
};
There, you can log it, raise a dialog if appropriate, etc.
Then, offer some means to get your logs off the device and to you, via email or a Web service. Some Android analytics firms, like Flurry, offer exception stack trace collection as part of their service. There are also open source projects that support this feature, such as ACRA.
As always, testing, particularly acceptance testing, is important.
Bear in mind that the act of creating the production signed version of your application could introduce errors, such as having the wrong Google Maps V2 API key. Hence, it is important to do user-level testing of your application after you sign, not just before you sign, in case the act of signing messed things up. After all, what you are shipping to those users is the production signed edition — you do not want your users tripping over obvious flaws.
As you head towards production, also consider testing in as many distinct environments as possible, such as:
End-user license agreements — EULAs — are those long bits of legal prose you are supposed to read and accept before using an application, Web site, or other protected item. Whether EULAs are enforceable in your jurisdiction is between you and your qualified legal counsel to determine.
In fact, many developers, particularly of free or open source applications, specifically elect not to put a EULA in their applications, considering them annoying, pointless, or otherwise bad.
However, the Play Store developer distribution agreement has one particular clause that might steer you towards having a EULA:
You agree that if you use the Store to distribute Products, you will protect the privacy and legal rights of users. If the users provide you with, or your Product accesses or uses, user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your Product, and you must provide legally adequate privacy notice and protection for those users. Further, your Product may only use that information for the limited purposes for which the user has given you permission to do so. If your Product stores personal or sensitive information provided by users, it must do so securely and only for as long as it is needed. But if the user has opted into a separate agreement with you that allows you or your Product to store or use personal or sensitive information directly related to your Product (not including other products or applications) then the terms of that separate agreement will govern your use of such information. If the user provides your Product with Google Account information, your Product may only use that information to access the user’s Google Account when, and for the limited purposes for which, the user has given you permission to do so.
Hence, if you are concerned about being bound by what Google thinks appropriate privacy is, you may wish to consider a EULA just to replace their terms with your own.
Unfortunately, having a EULA on a mobile device is particularly annoying to users, because EULAs tend to be long and screens tend to be short.
Again, please seek professional legal assistance on issues regarding EULAs.