Chapter 3 introduced the major application we use in this book to illustrate basic Android concepts. That chapter explained which files make up the source code, but it didn’t actually cover any source code in the application. We’ll start looking at source code in this chapter. And to allow you to get started developing an application quickly, we’ll begin with the first task every standalone application has to perform: initialization.
The events covered in this chapter occur between your selecting “Run As Android Application” from the Eclipse menu and seeing the map that MJAndroid displays at startup. This chapter shows how Android makes it easy to create relatively complex applications. In just 80 lines of code and some associated XML resource files, MJAndroid manages to:
Display an interactive map
Track the current location of the Android phone and update the map
Create a local database of information and load user preferences into it
Provide a dynamically changing menu
Display user interface elements such as labels, buttons, and spinners
Run a new Activity to display a supporting screen
The Java code in an Android application interacts tightly with XML resource files, so we’ll bounce back and forth between them in this chapter. As we point out repeatedly, XML files are easier to tweak during development and maintain over the life of an application. The design of Android encourages you to specify the look and behavior of the application in the resource files.
As Chapter 3 explained, we told Android to launch Microjobs.java as the first Activity for MJAndroid. We defined that on the Application tab of the AndroidManifest.xml editor. The first part of the XML code that results from that choice is shown here:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.microjobsinc.mjandroid" android:versionCode="1" android:versionName="1.0"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name= "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:icon="@drawable/icon2"> <uses-library android:name="com.google.android.maps" /> <activity android:name=".MicroJobs" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
This section of the chapter focuses on the XML in this file. The MicroJobs Activity is identified in the manifest at the beginning of the file. This part of the file is normally created in Eclipse when you first create the Project that you use to write your application.
Like all good XML files, line 1 has the standard declaration of the XML version and the character encoding used. Before we get into the Activities that make up the MJAndroid application, we define a few parameters and declare needed permissions for the whole application:
This is an integer that should always increment with each new version of the application. Every application should include a version code, and it should always be a monotonically increasing integer from version to version. This lets other programs (such as Android Market, installers, and launchers) easily figure out which is the latest version of an application. The filename of your .apk file should include this same version number, so it is obvious which version it contains.
This version identifier is a string, and it is intended to be more like the version numbers you usually see for applications. The naming convention is up to you, but generally the idea is to use a scheme like m.n.o (for as many numbers as you want to use), to identify successive levels of change to the application. The idea is that this is the version identifier that would be displayed to a user (either by your application or another application).
There are four of these in MJAndroid, and they declare that the
application intends to use features of Android that require
explicit permission from the user of the mobile device running the
application. The permission is requested when the application is
installed, and from then on Android remembers that the user said
it was OK (or not) to run this application and access the secure
features. There are many permissions already defined in Android,
all described in the Android documentation (search for
android.Manifest.permission). You can also define
your own permissions and use them to restrict other
applications’ access to functions in your application, unless
the user grants the other application that permission. The
permissions requested here are:
This is the filename for a PNG file that contains the icon you’d like to use for your application. In this case we’re telling the Android SDK to look for the icon file in the drawable subdirectory of the res (resources) directory under MJAndroid. Android will use this icon for your application in the Android Desktop.
Turning our attention to the definition for the first (and main) Activity, MicroJobs, we first define a few attributes for the Activity:
The name of the Activity. The full name of the Activity includes the package name (which in our application is “com.microjobsinc.mjandroid.MicroJobs”), but since this file is always used in the package’s namespace, we don’t need to include the leading package names. The Android SDK strips the package name down to “.MicroJobs” when it creates this part of AndroidManifest.xml, and even the leading period is optional.
The label that we want to appear at the top of the Android screen when the Activity is on the screen. We saw this before in HelloWorld, where we changed the string in strings.xml to match our application.
We then declare an intent filter that tells Android when this Activity should be run. We talked briefly about Intents in Chapter 1, and now we see them in use. As you’ll recall, when Android encounters an Intent to fulfill, it looks among the available Activities and Services to find something that can service the Intent. We set two attributes:
Right now Android is trying to launch this application, so it’s looking for an Activity that declares itself ready to resolve the MAIN action. Any application that is going to be launched by the Launcher needs to have exactly one Activity or Service that makes this assertion.
The Intent resolver in Android uses this attribute to further qualify the Intent that it’s looking for. In this case, the qualification is that we’d like for this Activity to be displayed in the User Menu so the user can select it to start this application. Specifying the LAUNCHER category accomplishes this. You can have a perfectly valid application without this attribute—you just won’t be able to launch it from the Android user interface. Normally, again, you’ll have exactly one LAUNCHER per application, and it will appear in the same intent filter as the opening Activity of your application.