mobile app assignment

profilekarthikrao0207
chapter6book.pdf

Getting Started with Android WHAT’S IN THIS CHAPTER?

! Deciding to target Android as your mobile platform

! Getting the tools you need to develop Android

! Creating a new project

! Creating the Derby project in Android

Android Inc. was initially started in 2003, out of a frustration with the smartphone market as it existed at the time. It was acquired by Google in 2005.

The hardware side of Android is supported by the Open Handset Alliance (OHA), which is a conglomeration of many handset manufacturers, and the software is maintained by the Android Open Source Project, which is led by Google.

Android had its fi rst major release in late 2008; the fi rst major phone company to support it was T-Mobile, and the original handset was the HTC Dream (G1).

The Android OS was built on a modifi ed Linux kernel and applications are written in Java. By using Java as the development framework for the applications, Android enables you to develop your application on all major platforms.

By leveraging the Eclipse IDE, Android affords the user almost the exact same user experience for development on all major OS platforms.

Additionally, when researching Android you may come across the name Dalvik. It is the virtual machine that runs on the Android device, and your applications run within it. What does this mean to developers? Because your applications run inside this virtual space, it provides a level of security to the base OS. Also, Dalvik has been designed with performance in mind. As of Android 2.2 it also provides just-in-time compilation to your apps (because Dalvik requires specially compiled .dex fi les and not just the standard .class fi les generated in a normal Java compilation).

6

c06.indd 151c06.indd 151 28/07/12 6:01 PM28/07/12 6:01 PM

152 " CHAPTER 6 GETTING STARTED WITH ANDROID

WHY TARGET ANDROID? Among the many reasons to target the Android platform, fi rst and foremost is cost. On average you can get an Android smartphone for a fraction of the cost of an iPhone. They may not have commensurate features, but thrift is a major component for new smartphone buyers.

Next is fl exibility. More types of Android devices are available, so if your application fi ts a specifi c niche market, there is probably a device that would support your needs already in production. At the time of writing, there are effectively two iOS devices (iPhone/iPod touch and iPad); four if you include the retina display versions, versus roughly 15 form factors to develop for.

If you are already a Java developer, adding Android to your repertoire is a snap. What Java is to Android, Cocoa is to CocoaTouch and C# is to Silverlight. All of the frameworks that mobile developers use are a combination of subsets and supersets of the functionality of a given technology.

Identifying an application that exists on another platform but does not yet exist on Android is another perfectly good reason to target Android. That being said, you should do some research, because if a developer has targeted iOS or BlackBerry as the primary platform, you have to assume that Android is potentially on the horizon.

WHO SUPPORTS ANDROID? HTC, LG, Motorola, and Samsung are the major players in the Android smartphone market. Archos, Dell, Samsung, and Toshiba hold the largest pieces of the Android tablet market. You should note that Amazon’s Kindle Fire and Nook Color are up-and-comers and use a customized version of the Android tablet (Version 3) OS on their devices.

ANDROID AS COMPETITION TO ITSELF Because Android was designed to be run on many different types of devices, created by many different manufacturers (as opposed to the closed system that Apple has maintained), it has left itself open to the will of said manufacturers. Because of the open nature of the Android OS, it is commonplace for manufacturers to create vendor-specifi c builds of Android, and when this happens you are beholden to them for OS updates. Additionally in these custom builds, vendor-specifi c limitations have arisen such as the vendor-specifi c market. You then have another hurdle to cross when releasing your application for sale to the public because some devices may not be able to purchase it because of these limitations.

Another issue that has cropped up is the lack of over-the-air (OTA) distribution of OS updates by cellular carriers. Often your device is perfectly capable of running a later version of the Android software, but carriers are often slow to distribute that to their customers.

Multiple Markets and Market Locks Depending on your version of Android, and depending on the manufacturer of a given device, you may fi nd yourself locked into using a vendor-specifi c Android marketplace. Additionally, application

c06.indd 152c06.indd 152 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 153

vendors can list their application not only on Google Play or vendor-specifi c marketplaces, but also on the Amazon App Store. You often fi nd on cheap and imported Android devices a version of Google Play that is maintained by the manufacturer. They pick and choose what applications are available from the whole set in the marketplace. You should develop as you expect to be available to all Android devices; just note when purchasing large quantities for an enterprise deployment that you will have to watch out for these inconsistencies.

The version of the Android SDK that you need to support depends on what devices you want to support. If you want to target most phones available right now, you should support Android 2.2 or 2.3. “Gingerbread” (2.3) is the last widely available version for those devices. The Android 3.x versions are for tablets, such as the Samsung Galaxy Tab. The Android 4.x versions are the newest, and are a combination of the Android 2.x and Android 3.x functionality meant to pull back on the version splintering seen in devices, but not many devices currently in release support it.

Once you have decided on a version to deploy your application against, you need to set up your development environment. In the next section you will learn all about confi guring your IDE, Java and Android SDKs, and building emulators.

GETTING THE TOOLS YOU NEED This section paraphrases the installation instructions from the Android Developer section, and we added some personal notes from our experiences.

Downloading and Installing JDK The fi rst thing that you need to do to develop Android applications is to visit http://www.oracle .com/technetwork/java/javase/downloads/index.html and ensure that you have the Java JDK installed. Because so many different acronyms and versions appear on the Java download website, Figure 6-1 points you in the direction you need to get past all of the potential distractions on that site.

The JDK is the Java Development Kit. You need this package to do any Java development on your machine, Android or otherwise. Be sure to look for the Java Platform, Standard Edition JDK.

Downloading and Installing Eclipse

After you have successfully installed the JDK, you will need a development environment. The open source IDE Eclipse is recommended by Android directly in its documentation. You are not limited only to Eclipse, but the tooling has been honed over time to be the easiest solution to

FIGURE 6!1: JDK download page

c06.indd 153c06.indd 153 28/07/12 6:01 PM28/07/12 6:01 PM

154 " CHAPTER 6 GETTING STARTED WITH ANDROID

get up and running. Figure 6-2 shows the Eclipse download page (www.eclipse.org/downloads). Download the version of Eclipse Classic that is appropriate for your operating system.

FIGURE 6!2: Eclipse download site

Downloading and Installing the Android SDK After you have installed the Eclipse IDE, you need to install the Android Software Developer Kit (http://developer.android.com/sdk/index.html). This includes all the tools necessary to build Android apps, because the SDK is not built directly into Eclipse. Figure 6-3 shows the Android SDK download page; make sure to get the right version for your OS.

Don’t use the installer for 64-bit Windows. Just get the zip fi le and unzip it to c:\Android. At the time of writing the installer package has diffi culty fi nding the Java SDK installed on the machine.

For Mac deploy it to /android in your root volume.

FIGURE 6!3: Android SDK download page

c06.indd 154c06.indd 154 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 155

Downloading and Confi guring the Eclipse ADT Plug-in After you have installed the Android SDK you need the ADT plug-in. What this does is add the features necessary to create Android Projects (and Android Test Projects), because they are not bundled with the base Eclipse install. Additionally, the plug-in adds debugging tools to Eclipse to help during the Android development process. Figure 6-4 shows the interface for installing the ADT plug-in. You will also use this interface when upgrading ADT. The tooling generally gets a revision when a new version of the Android OS is released.

FIGURE 6!4: Installing the ADT plug-in

Use the Update Manager feature of your Eclipse installation to install the latest revision of ADT on your development computer. Follow these steps:

1. Start Eclipse and select Help # Install New Software. 2. Click Add in the top-right corner. 3. In the Add Repository dialog box that appears, enter ADT plug-in for the name and the

following URL for the location: https://dl-ssl.google.com/android/eclipse/.

4. Click OK. If you have trouble acquiring the plug-in, try using “http” in the Location URL instead of “https” (“https” is preferred for security reasons).

5. In the Available Software dialog box, select the checkbox next to Developer Tools and click Next.

c06.indd 155c06.indd 155 28/07/12 6:01 PM28/07/12 6:01 PM

156 " CHAPTER 6 GETTING STARTED WITH ANDROID

6. The next window shows a list of the tools to be downloaded. Click Next. 7. Read and accept the license agreements and then click Finish. If you get a security warning

saying that the authenticity or validity of the software can’t be established, click OK.

8. When the installation completes, restart Eclipse. Once you have downloaded the ADT plug-in you need to set it up to talk to the Android SDK that you downloaded earlier. This allows Eclipse to build, run, and debug Android applications without needing to open a terminal or command shell. Figure 6-5 shows where you need to add the link to the Android SDK in the Eclipse preferences.

After you’ve successfully downloaded the ADT, the next step is to modify your ADT preferences in Eclipse to point to the Android SDK directory (see Figure 6-5):

1. Select Window # Preferences to open the Preferences panel. In Mac OS X, click Eclipse # Preferences.

2. Select Android from the left panel. 3. You may see a dialog box asking whether you want to send usage statistics to Google. If

so, make your choice and click Proceed. You cannot continue with this procedure until you click Proceed.

4. For the SDK Location in the main panel, click Browse and locate your downloaded SDK directory.

5. Click Apply and then click OK.

FIGURE 6!5: ADT confi guration screen

c06.indd 156c06.indd 156 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 157

Installing Additional SDK Components The last step in preparing your development environment for Android is to download additional Android OS packages. This enables you to build applications that target that OS, and also gives you the tools you need to emulate a device running that OS on which to test all of your applications, whether or not they have been targeted to that OS version. Figure 6-6 shows just how many options you have when looking to target Android OS versions.

FIGURE 6!6: Working with the SDK Manager

Correctly confi guring and using this tool will ensure that you have all the latest SDKs and utilities afforded to you. Note that you will not necessarily need all of the versions of the SDKs listed in Figure 6-6; this was merely to illustrate the full breadth of your options.

Loading the Android SDK Manager in Eclipse takes only a few steps:

1. Open Eclipse. 2. Select Window # Android SDK and AVD Manager.

c06.indd 157c06.indd 157 28/07/12 6:01 PM28/07/12 6:01 PM

158 " CHAPTER 6 GETTING STARTED WITH ANDROID

3. Select Available Packages in the left panel. This reveals all of the components that are cur- rently available for download from the SDK repository.

4. Select the component(s) you’d like to install and click Install Selected. 5. Verify and accept the components you want (ensure each one is selected with a green check-

mark) and click Install. The components will now be installed into your existing Android SDK directories.

I recommend that you download and install an Android 2.2.x, Android 2.3.x, and Android 3.x version. This will give you the latest two handset-specifi c versions of Android, and the current tablet version of Android. As Android 4.0 is so new, you may choose to get it, but understand that you may need to purchase a newer device to test apps targeted to that version.

Development The following sections discuss the application layout and Android app development.

Creating a New Project First things fi rst — you need to create a new Android project. The line highlighted in Figure 6-7 is the type of project you want.

FIGURE 6!7 Creating a new Android project

c06.indd 158c06.indd 158 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 159

First you need to name your application and add it to a workspace. Think of a workspace as the folder in which your application resides. Figure 6-8 illustrates what the New Android Project screen looks like.

After you have named your application you will need to give it a package name, set the minimum SDK required to run your application, and name the initial Activity that will run when your application runs. If you want to add a test project to your workspace, you can do so at this time. Figure 6-9 shows a completed Application Info step in the new project wizard.

An important note at this point: Make sure that your package name is unique. The standard format for package names is com.companyName.applicationName. This must be unique because that is how it is known on the Android device and in the Android Market. When you make updates you can make them only within your package name. If you change your package name there will be no upgrade path between versions.

The minimum SDK required is generally set when you are leveraging a permission or piece of functionality that did not exist when the core Android version was released, or if you want to target a specifi c type of device (tablet versus handset). The major jumps are between 1.6 and 2.1, 2.3 and 3.x, and 3.x and 4.x. Figure 6-10 shows you all of the SDKs that you have installed that you can target when creating your application. Please note that the reason this screen is full of SDKs is because I took the time to download them all for demonstration purposes.

FIGURE 6!8: Naming your project

FIGURE 6!9: Confi guring application information

c06.indd 159c06.indd 159 28/07/12 6:01 PM28/07/12 6:01 PM

160 " CHAPTER 6 GETTING STARTED WITH ANDROID

This step is also very important when building your application. The minimum SDK version you set specifi es the lowest possible version of the SDK in which your application will run, and it is the primary version in which your application will run. Android 1.5 is the lowest version of the SDK still supported, and Android 4.0.3 (at the time of this writing) is the highest.

FIGURE 6!10: Choosing the SDK version for your app

Figure 6-10 shows a Google version of the SDK alongside all of the versions I have installed on my machine. The Google APIs add additional functionality to each API Level. Please use your best judgment when deciding whether to use the Google APIs, and research if you need the functionality they provide.

Project Structure The major sections to note in Figure 6-11 are the src and res folders and the AndroidManifest .xml fi le. It shows the project layout for the application that I have been building in the previous steps.

c06.indd 160c06.indd 160 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 161

All of your code lives within your src folder, under your Package Namespace. The res folder holds layouts and resources for different hardware specs. HDPI, LDPI, and MDPI are the resolutions for which you can create images. The layout subfolder holds all of your XML layouts. These are how your application gets rendered. The code will be how to populate these layouts. All of your XML layouts are stored in the layout subfolder of res, and your code will be linked under the namespace in your src folder of the project view.

The Android Manifest is the heart of your application. It holds the entire confi guration of your app (Figure 6-12) — the permissions you request (Figure 6-14), the application attributes (Figure 6-13), and links to instrumentation to be attached to your app. You can edit this in Eclipse’s Manifest Editor or in XML (Figure 6-15) because that is how it is saved.

FIGURE 6!11: Basic project structure

FIGURE 6!12: Main Manifest Editor

c06.indd 161c06.indd 161 28/07/12 6:01 PM28/07/12 6:01 PM

162 " CHAPTER 6 GETTING STARTED WITH ANDROID

The Manifest Editor is where the initial information of your application is stored when you create it. This interface also has links to export your application. Exporting is necessary when submitting your app to Google Play. In Eclipse there is a specifi c menu option and wizard that expedites the submission process.

Figure 6-13 shows all of the base properties that can be set for a given application in the app’s AndroidManifest.xml fi le. The most common properties to edit are the Label (the text shown under the icon, often referenced in a resource fi le) and Icon (the icon shown in the launcher UI of your device, the icon your users will click on to launch the app).

FIGURE 6!13: Manifest Application Info Editor

The spartan view shown in Figure 6-14 is the Permissions Editor. Here you can add permission requests to your application. The most common one is android.permission.INTERNET, which allows the application to use the device Internet connectivity. This, along with GPS and accelerometer, are the permissions you will add to the Derby Names application.

c06.indd 162c06.indd 162 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 163

Last is the XML Editor shown in Figure 6-15. As you make changes in the other tabs they are refl ected here. If you feel more comfortable editing the XML by hand you can use this interface to add, update, and remove properties as you see fi t.

FIGURE 6!14: Android Manifest Permissions Editor

FIGURE 6!15: Android Manifest XML Editor

c06.indd 163c06.indd 163 28/07/12 6:01 PM28/07/12 6:01 PM

164 " CHAPTER 6 GETTING STARTED WITH ANDROID

Android Basics You have two options for starting your application. You can build the layout you would like to populate, or you can build the code that will populate the layout. Either is acceptable; it just depends on what you feel most comfortable with.

Creating User Interfaces This section describes the common widgets that come with Android, and shows examples of the different layout elements you can use to coordinate the fl ow of your application’s activities.

Basic Android UI Elements All of the basic elements in Android are stored in the android.widgets namespace in the SDK.

The most commonly used elements include:

! Button: This is a standard button element.

The following XML specifi es the layout of the Button widget:

<Button android:layout_height=”wrap_content” android:layout_width=”wrap_content” android:id=”@+id/button” android:text=”Click Me” android:onClick=”btnClick” />

Code: This code is necessary to handle the Click event noted in the XML layout.

public void btnClick (View view) { //Do Something. }

! TextView: When I see this I want to think text box, but it isn’t a text box. TextView is effectively the same as a label in other languages. It is just a place to display text.

Layout:

<TextView android:id=”@+id/textview” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:text=”Hello World”/>

Code:

TextView tvToShow = (TextView)this.findViewById(R.id.textview); tvToShow.setText(“Ta-Dah!”);

! EditText: This is the text box widget. You can edit the contents of the text box and save those values in code.

c06.indd 164c06.indd 164 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 165

Layout:

<EditText android:id=”@+id/txtUsername” android:hint=”Username” android:layout_width=”fill_parent” android:layout_height=”wrap_content” />

Code:

EditText txtUserName = (EditText) findViewById(R.id.txtUsername); String username = txtUserName.getText().ToString();

! CheckBox: This is a standard checkbox element.

Layout:

<CheckBox android:id=”@+id/checkbox” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”Checkbox Text” />

Code:

final CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox); checkbox.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (((CheckBox) v).isChecked()) { //It’s Checked } else { //Not Checked } } });

! RadioButton: This is a standard radio button element. To really get the most bang for your buck, though, you need a RadioGroup.

Layout:

<RadioGroup android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:orientation=”vertical”> <RadioButton android:id=”@+id/radio_uno” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”1 - Uno” /> <RadioButton android:id=”@+id/radio_dos” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”2 - Dos” /> </RadioGroup>

c06.indd 165c06.indd 165 28/07/12 6:01 PM28/07/12 6:01 PM

166 " CHAPTER 6 GETTING STARTED WITH ANDROID

Code:

private OnClickListener radioButtonOnClick = new OnClickListener() { public void onClick(View v) { RadioButton rb = (RadioButton) v; // Do with it what you will //rb.getText(); } };

//This assigns this event to the radio buttons. RadioButton radio_uno = (RadioButton) findViewById(R.id.radio_uno); RadioButton radio_dos = (RadioButton) findViewById(R.id.radio_dos); radio_uno.setOnClickListener(radio_listener); radio_dos.setOnClickListener(radio_listener);

Figure 6-16 shows all of the major UI widgets.

! ListView: This is the element you use if you want to show lists of data. You can overload its display and put lots of elements in each row, or you can just bind a text item and a value to each. The trick is using an ArrayAdapter<T> where T is the type of object that you want bound. Additionally, creating a layout XML for how you want each item displayed is a good strategy.

Layout:

<ListView android:id=”@+id/lstWords” android:layout_width=”fill_parent” android:divider=”#ddd” android:dividerHeight=”1px” android:paddingBottom=”67dp” android:layout_height=”fill_parent” />

Code:

static final String[] words = new String[]{ “Hello”, “World” }; lstWords = (ListView)findViewById(R.id.lstWords); lstWords.setAdapter new ArrayAdapter<String>(this.getApplicationContext(),R.id.list_content,words));

Basic Android Layouts and Views ! FrameLayout: This is very simplistic and can really contain only a single UI element. You

can, in fact, have multiple elements but they overlap each other by default.

The example code shown here is rendered in Figure 6-17:

FIGURE 6!16: Major UI elements all together

c06.indd 166c06.indd 166 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 167

<?xml version=”1.0” encoding=”utf-8”?> <FrameLayout android:id=”@+id/frameLayout” android:layout_width=”fill_parent” android:layout_height=”fill_parent” xmlns:android=”http://schemas.android.com/apk/res/android”> <EditText android:id=”@+id/widget46” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”EditText” android:textSize=”18sp” /> </FrameLayout>

This is a simple FrameLayout that contains a single EditText widget with the text “EditText.”

LinearLayout: This lays out your UI elements along a given direction: horizontal or vertical. Figure 6-18 is a linear layout, which contains four consecutive TextView widgets along the vertical.

FIGURE 6!17: FrameLayout rendered

FIGURE 6!18: LinearLayout rendered

Example:

<?xml version=”1.0” encoding=”utf-8”?> <LinearLayout android:id=”@+id/widget59” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:orientation=”vertical” xmlns:android=”http://schemas.android.com/apk/res/android”>

c06.indd 167c06.indd 167 28/07/12 6:01 PM28/07/12 6:01 PM

168 " CHAPTER 6 GETTING STARTED WITH ANDROID

<TextView android:id=”@+id/widget60” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:background=”#ffaa0000” android:layout_marginTop=”5dp” android:layout_marginLeft=”5dp” android:text=”red” /> <TextView android:id=”@+id/widget63” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:background=”#ffaaaa00” android:layout_marginTop=”5dp” android:layout_marginLeft=”5dp” android:text=”yellow” /> <TextView android:id=”@+id/widget64” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:background=”#ff00aa00” android:layout_marginTop=”5dp” android:layout_marginLeft=”5dp” android:text=”green” /> <TextView android:id=”@+id/widget65” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:background=”#ff0000aa” android:layout_marginTop=”5dp” android:layout_marginLeft=”5dp” android:text=”blue” /> </LinearLayout>

! TableLayout: Think tables in HTML and this is the type of organization you get with this layout. TableLayouts contain rows and columns, representing a grid, and you can put other UI elements into it. The following code results in a table with two rows, each with two cells, and is visualized in Figure 6-19:

<?xml version=”1.0” encoding=”utf-8”?> <TableLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:stretchColumns=”1”> <TableRow> <TextView android:text=”Hello” android:padding=”3dip” /> <TextView android:text=”World” android:gravity=”right” android:padding=”3dip” /> </TableRow>

c06.indd 168c06.indd 168 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 169

<TableRow> <TextView android:text=”Goodbye” android:padding=”3dip” /> <TextView android:text=”User” android:gravity=”right” android:padding=”3dip” /> </TableRow> </TableLayout>

! RelativeLayout: This is the most complex layout of the four mentioned in this section. You specify relationships between UI elements to lay out your interface.

The following code represents a simple form with a TextView acting as a label for a blank EditText widget, with Cancel and OK widgets docked beneath EditText relative to the right screen boundary:

<?xml version=”1.0” encoding=”utf-8”?> <RelativeLayout android:id=”@+id/widget37” android:layout_width=”fill_parent” android:layout_height=”fill_parent” xmlns:android=”http://schemas.android.com/apk/res/android”>

<TextView android:id=”@+id/label” android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:text=”Type here:” />

<EditText android:id=”@+id/entry” android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:background=”@android:drawable/editbox_background” android:layout_below=”@id/label” /> <Button android:id=”@+id/ok” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:layout_below=”@id/entry” android:layout_alignParentRight=”true” android:layout_marginLeft=”10px” android:text=”OK” />

<Button android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:layout_toLeftOf=”@id/ok” android:layout_alignTop=”@id/ok” android:text=”Cancel” /> </RelativeLayout>

FIGURE 6!19: TableLayout rendered

c06.indd 169c06.indd 169 28/07/12 6:01 PM28/07/12 6:01 PM

170 " CHAPTER 6 GETTING STARTED WITH ANDROID

Figure 6-20 shows how this code renders on an Android device.

Having seen the various UI elements, now is the time to get the rest of your development environment confi gured to be able to debug your app.

Creating an Android Virtual Device You need to create an Android Virtual Device (AVD) in order to debug your application in the emulator, because this “device” is what the emulator runs. Creating an AVD is quite easy. Eclipse includes a tool called AVD Manager (click Window Manager # AVD Manager). You need to name your AVD instance, choose its OS version (Target), pick a skin (with which you can customize the look and feel of the emulator) and resolution, and specify the hardware details for the device (amount of RAM, size of SD card, and sensors like Accelerometer and GPS). Once you have confi gured it to your specifi cations, click Create AVD and you are all set.

For most purposes, the stock AVD skins are fi ne for debugging, but if you would like to emulate a specifi c device (tablet or handset) either for demonstration purposes or because you want it to feel like the device you are developing for, you can use a custom skin. Although you can always set the hardware properties to mirror those of the device you are using, there is an online community (www.xda-developers.com) dedicated to making custom skins for use with the AVD. Using your favorite search engine, type the model and make of the Android device you want to emulate, and most likely you will fi nd a custom skin out there for it. Creating a new AVD with the appropriate specs and then selecting this skin gives you an emulator that looks just like the device you are testing for.

Debugging Debugging in Eclipse is easy. Instead of running your application, you click Debug As and you are off and running. Set breakpoints in your code by selecting them by the gutter next to the line numbers, and as your code progresses it will break at all your steps.

In addition to breakpoint-based debugging, you also have access to the Dalvik Debug Monitor Server (DDMS) perspective in Eclipse (see Figure 6-21). You can use DDMS to view the heap usage for a given process (your running app or anything running inside the virtual machine), track memory allocation of objects inside an app, interact with the fi lesystem of the device running the app (emulator or actual), view running threads for an application, profi le methods using tracing, read log messages using LogCat, and emulate phone and sensor data (SMS, phone calls, location [GPS]), as shown in Figure 6-22.

FIGURE 6!20: RelativeLayout rendered

c06.indd 170c06.indd 170 28/07/12 6:01 PM28/07/12 6:01 PM

Getting the Tools You Need " 171

In Figure 6-22 you see the Emulator Control pane. In this pane you can spoof an incoming number to your emulator, to test how your application deals with that. You can also simulate text messages. The bottom pane in that page has a way to confi gure your GPS manually. This allows you to test location-based code without having to move your device.

FIGURE 6!21: DDMS perspective

FIGURE 6!22: Faking out your emulator

c06.indd 171c06.indd 171 28/07/12 6:01 PM28/07/12 6:01 PM

172 " CHAPTER 6 GETTING STARTED WITH ANDROID

CONNECTING TO THE GOOGLE PLAY This section explains what is necessary to publish your application to the Google Play. There is also the Amazon Android Marketplace, which has other requirements. But because it may be more of a marketing choice than a development choice, we decided to go with the explanation of the basic Google Play distribution process.

Getting an Android Developer Account Signup is a snap for a dev account. Just make sure you have a Google account (Gmail, or Google Apps), $25 (one-time registration fee), head to https://play.google.com/apps/publish/signup, and you are all set.

Signing Your Application Signing your application with Eclipse is a relatively simple process:

1. Right-click your project in the Package Explorer and select File # Export. 2. Select Export Android Application. 3. Complete the steps of the wizard and you will have a keystore, and a signed release build of

your app ready for the market.

When you have created your keystore, make sure to guard it safely. It is the fi le you will use to sign your application every time you update, and if you lose it you cannot upgrade your application in Google Play.

SIGNS OF THE TIMES

When you are signing your application you can use the export tooling built into Eclipse. However, if you need to request a Google Maps API key for your application, you will need to use the keytool and jarsigner applications to get the hash of your signature. Information regarding these tools is available at http:// developer.android.com/guide/publishing/app-signing.html.

ANDROID DEVELOPMENT PRACTICES This section covers the fundamentals of developing an Android application, explaining the permissions in the Manifest and how you must always manage your navigation between Activities using the back stack.

Android Fundamentals When developing an Android app you need to account for which of the four basic components (Activities, Services, Content Providers, and Broadcast Receivers) of apps you need to include.

c06.indd 172c06.indd 172 28/07/12 6:01 PM28/07/12 6:01 PM

Android Development Practices " 173

Activities Activities are the individual screens in your application. All of the functionality that is exposed in the UI for that screen lives in the scope of that Activity.

Services Services are components that run in a background thread. Common usages for services are to hold long-running processes, or for functions that can happen in parallel with the application (playing music from your library, or updating a web service). Be aware that when you have an application running in the background it can take processing power from the device, though contrary to popular thought it does not affect your battery life.

Content Providers Content providers are interfaces to the offl ine storage that you have within your app. If you create a suite of applications you may want to have a single point for holding all of your data. You can also leverage the Content Providers built into the Android OS. The standard set of providers in the OS allows you to get content from the Calendar, Contacts, Media Store, Messaging, and Voice Mail applications.

Broadcast Receivers Broadcast receivers are components that respond to system messages. You would use a Broadcast Receiver to catch events like the screen turning off, or the battery reaching a critical level. A common use for a Broadcast Receiver is for querying the status of the network (Wi-Fi or cellular) so that you can display the appropriate messaging to the user.

Fragments as UI Elements Starting in Android 3.x, there has been a shift in design elements to account for the signifi cant differences between the screen sizes of tablets versus handsets.Whereas normally UI design for mobile devices is very rigid, Fragments add a level of fl exibility. Fragments themselves live as a subactivity that you can reference in multiple places in your application. Fragments live within the scope of their parent activity, but can be used in multiple activities.

Ask for Permission The users of your application must approve of what functionality you want to leverage on their device. To prompt the user for what you need, and so that your device will behave as designed, you need to add permission requests in your application’s manifest. Visit http://developer.android .com/reference/android/Manifest.permission.html for a list the various permissions you can request when developing.

Depending on what version of the OS you are targeting you are afforded additional permissions. One of the newest permissions available is READ_SOCIAL_STREAM, which enables you to access the user’s social stream. One of the oldest permissions is your ability to set the given time zone, using, you guessed, it SET_TIME_ZONE.

c06.indd 173c06.indd 173 28/07/12 6:01 PM28/07/12 6:01 PM

174 " CHAPTER 6 GETTING STARTED WITH ANDROID

If you try to run a piece of code in the emulator and it should be responding to fi ring events or listening to hardware, and it isn’t, make sure you have requested permission in your app. Additionally, do not request every possible permission. Applications that do this are often considered malware or at least not trustworthy by the layperson.

Mind the Back Stack Unlike iOS-based devices, all Android devices have a hardware back button. What this means is that there is something physical on the device that interrupts the UI and takes the user to the previous action. This is known in the back stack. It can be likened to a browser history or a copy/ paste clipboard. How this differs from those, though, is that it must be stateful (to provide the least jarring UI to your users). You must understand that you need to persist the state of the View when returning to it from the back stack. Additionally, if the current view affects the state of the previous view, you must update it accordingly without requiring the user to click a UI element; it needs to be able to be updated when the user backs up the stack.

Now that this chapter has covered all the major sections of development in Android, the next section will show how to build the demo Derby app in Android.

BUILDING THE DERBY APP IN ANDROID The idea of the Derby app is to build the same app over all of the mobile platforms covered in this book. The Android version is very similar to the other versions you have built thus far or will build in future chapters.

The requirements are to list the roster from the Lansing Derby Vixens roller derby team as the primary function, and then list all the roller derby teams in the world with the ability to see their team rosters.

Common Interactions The main ways to get your users around your app, and to let them know when events happen or issues arise is by using well-managed UI navigation (and the back stack), and timely use of notifi cations.

UI Navigation and Using Back Stack Because Android devices are equipped with a dedicated hardware back button, you need to make certain considerations as you pass from activity to activity within your application. The states of activities are stored in a back stack that persists and allows users to walk back through the navigation one button click at a time. Extras are stateful objects held within Intents that are the primary way that you communicate between activities. Considered “the glue between activities” (http://developer.android.com/reference/android/content/Intent.html) Intents provide a simple storage mechanism that can be retrieved and set, and are passed between two activities.

Use the GetExtra command to retrieve simple and complex objects from one activity to another using an Intent.

c06.indd 174c06.indd 174 28/07/12 6:01 PM28/07/12 6:01 PM

Building the Derby App in Android " 175

You can select the extras you want to refer to individually from the Intent. For example:

String id = getIntent().getStringExtra(“id”); String name = getIntent().getStringExtra(“name”);

Or you can get all of the objects you passed along as a Bundle:

Bundle extras = getIntent().getExtras(); String userName; String id;

if (extras != null) { userName = extras.getString(“name”); id = extras.getString(“id”); }

Use the PutExtra command to put the object you want to pass between activities. You can pass simple or complex objects. You need to use Extras only when you want to pass data between activities. It is not necessary to set a complex state transfer process if you don’t need that data.

String username = “DerbyUser”; String id = “derbyuser42”; Intent newIdea = new Intent(this, newIdea.class); newIdea.putExtra(“username”, username); newIdea.putExtra(“id”, id); startActivity(newIdea);

Notifi cations You have lots of ways to display content to your users: either in your Base UI or through different types of notifi cations. What follows is an explanation of toasts and alerts.

Toasts A toast is a quick notifi cation that displays (by default) in a gray translucent box over your UI.

Context context = getApplicationContext(); //Find the application you are currently running CharSequence text = “Greetings from the App!”; //This is the message you want to share. int duration = Toast.LENGTH_SHORT; //This is a constant in the SDK for a quick notification Toast toast = Toast.makeText(context, text, duration); //Create the toast object toast.show(); //Display it for the duration now.

Alerts Simpler even than toasts, alerts are very similar to JavaScript alerts in that they pop a modal form with which you have very little ability to interact. You can set a button to represent affi rmation, declination, and cancellation alerts. The following snippet of code shows how to do that:

//Create a new AlertDialog using its builder respective to the current context. new AlertDialog.Builder(this)

c06.indd 175c06.indd 175 28/07/12 6:01 PM28/07/12 6:01 PM

176 " CHAPTER 6 GETTING STARTED WITH ANDROID

.setTitle(“Alert Title”) //Set Title for the Alert

.setMessage(“Is this the message you expected?”) //Set Message for the alert

.setNegativeButton(“No”, null) //Set the Declination Button (Optional)

.setPositiveButton(“Yes”, null) //Set the Affirmation Button (Optional)

.setNeutralButton(“Who Cares”, null) //Set the Cancellation Button (Optional)

.show(); //Display the alert now.

Like all things in Android, you can customize notifi cations. You can fi nd more information on customizing them at http://developer.android.com/guide/topics/ui/notifiers/index.html.

O" ine Storage Even though the bulk of Android devices are smartphones — which afford users an always-on, always-connected experience — many reasons exist to store data on the device versus querying the a service remotely. For simple or small pieces of data you can use Shared Preferences; for larger data sets that may include complex objects, you can use SQLite.

SQLite SQLite is a fl at-fi le database that runs inside the Android framework. You can use it to store large object graphs or signifi cant amounts of data so that you aren’t constantly connecting to a remote source.

This is the base class for instantiating your SQLite instance in your Android app:

public class PersistingData extends Activity{ private static final String DATABASE_NAME = “DerbyData”; private SQLiteDatabase db; private DatabaseOpenHelper dbhelper;

/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ConnectToDatabase(this.getApplicationContext()); }

public void ConnectToDatabase(Context context){ dbhelper = new DatabaseOpenHelper(context, DATABASE_NAME, null, 1); }

public void DB_Open() throws SQLException{ db = dbhelper.getWritableDatabase(); }

public void DB_Close(){ if (db != null){ db.close(); } } }

This is a helper class to handle creating the database for you based on a predefi ned schema:

c06.indd 176c06.indd 176 28/07/12 6:01 PM28/07/12 6:01 PM

Building the Derby App in Android " 177

public class DatabaseOpenHelper extends SQLiteOpenHelper{

public DatabaseOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); }

@Override public void onCreate(SQLiteDatabase db) { String loadSchema = “CREATE TABLE DerbyNames” + “( DerbyNameId integer primary key autoincrement,” + “name TEXT, Number TEXT, League TEXT, DateAdded DateTime);”; db.execSQL(loadSchema); }

@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }

SharedPreferences SharedPreferences is a set of key-value pairs saved on your device that is helpful for storing instance-specifi c data as it pertains to the app. The main concern is the level of privacy that you impose upon it. If you make it world-readable its value can be accessed by any application should another application query against your key. This function is an example of leveraging SharedPreferences to store application preference for the user:

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit();

public void savePreferenceToSharedPreferences(String key, String value){ editor.putString(key, value); editor.commit(); } public String loadPreferenceFromSharedPreferences(String key) { String tmpRtn = sharedPreferences.getString(key, “”); return tmpRtn; }

Web Service In Chapter 3 you developed a web service for the Derby application to call. This section goes over what you need to do to consume this information. In this example you write out the data to the log:

public class DerbyDataActivity extends Activity { /** Called when the activity is first created. */ @Override

c06.indd 177c06.indd 177 28/07/12 6:01 PM28/07/12 6:01 PM

178 " CHAPTER 6 GETTING STARTED WITH ANDROID

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); getLansingDerbyVixens(); }

In the following part you are loading up the activity, and telling it to run your getLansingDerbyVixens function.

public void getLansingDerbyVixens() { String requestURL = “http://derbynames.gravityworksdesign.com/DerbyNamesService.svc/ DerbyNames?$filter=League%20eq%20’Lansing%20Derby%20Vixens’”; Log.i(“DerbyData”, “getSurvey-Starting”); try { URL webRequest = new URL(requestURL); URLConnection tc = webRequest.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(tc. getInputStream()));

Log.i(“DerbyData”, “- before loading JSON”); StringBuilder surveyJSON = new StringBuilder(); String currentLine = “”; while ((currentLine = in.readLine()) != null) { surveyJSON.append(currentLine); }

This continuing function makes a webRequest to your service, takes the content of the response, and reads it in as a string. Because your service returns JSON you can deserialize each item in your JSON string to a DerbyName object using your getDerbyDataFromJSON function.

if (surveyJSON != null) { Log.i(“DerbyData”, “getSurvey-Have Data”); ArrayList<DerbyName> derbyNames = getDerbyDataFromJSON(surveyJSON.toString());

Next you iterate through the returned ArrayList<DerbyName> object and print each item’s properties in the log.

for(DerbyName item : derbyNames ){ Log.i(“DerbyData”, String.format(“Name=%s: Number=%s: League=%s”, item.getName(), item.getNumber(), item.getLeague())); } } } catch(Exception e) { Log.e(“DerbyData”, “Error getting data” + e.getMessage()); } Log.i(“DerbyData”, “finished”); }

c06.indd 178c06.indd 178 28/07/12 6:01 PM28/07/12 6:01 PM

Building the Derby App in Android " 179

This function takes the JSON string and deserializes it into an ArrayList of DerbyName objects. You iterate through the contents of the returned objects and assign them to properties inside an instance of a DerbyName object, then add it to the ArrayList to be returned to your main function.

public static ArrayList<DerbyName> getDerbyDataFromJSON(String surveyDerby) { ArrayList<DerbyName> tmpRtn = new ArrayList<DerbyName>(); Log.i(“DerbyData”, “getDerbyDataFromJSON-Starting”); try { JSONObject fullJsonObject = new JSONObject(surveyDerby); JSONArray jsonNames = fullJsonObject.getJSONArray(“d”); // loop through each json derby name for (int i = 0; i < jsonNames.length(); i++) { DerbyName derbyName = new DerbyName(); JSONObject result = jsonNames.getJSONObject(i); derbyName.setDerbyNameId(result.getInt(“DerbyNameId”)); derbyName.setName(result.getString(“Name”)); derbyName.setNumber(result.getString(“Number”)); derbyName.setLeague(result.getString(“League”)); tmpRtn.add(derbyName); } } catch (JSONException e) { Log.e(“DerbyData”, “getDerbyDataFromJSON-Error converting JSON to Derby Name” + e.getMessage()); } Log.i(“DerbyData”, “getDerbyDataFromJSON-Finished”); // return return tmpRtn; }

}

The following class is the DerbyName object you have created to hold the data you get from the web service. You have effectively created an entity to equate to a single item from the service.

public class DerbyName { private int DerbyNameId; private String Name; private String Number; private String League; public int getDerbyNameId() { return DerbyNameId; } public void setDerbyNameId(int derbyNameId) {

c06.indd 179c06.indd 179 28/07/12 6:01 PM28/07/12 6:01 PM

180 " CHAPTER 6 GETTING STARTED WITH ANDROID

DerbyNameId = derbyNameId; } public String getName() { return Name; } public void setName(String name) { Name = name; } public String getNumber() { return Number; } public void setNumber(String number) { Number = number; } public String getLeague() { return League; } public void setLeague(String league) { League = league; } }

Long-Running Tasks over the Web Please be aware that if you are going to be downloading a lot of data over any web request, or if you are in a high-latency situation, you might want to look into using the AsyncTask (http://developer.android.com/reference/android/ os/AsyncTask.html) for handling long-running tasks on a background thread. If your main thread hangs for roughly fi ve seconds, you can receive a message like the one shown Figure 6-23.

GPS The following function connects to your device’s GPS (if available) and displays a toast of your latitude and longitude when you go past its set threshold:

public class SensorsGPS extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);

/* Use the LocationManager class to obtain GPS locations */ LocationManager locManager = (LocationManager) getSystemService(Context. LOCATION_SERVICE); LocationListener locListener = new MyLocationListener();

FIGURE 6!23: Common error when your Service times out

c06.indd 180c06.indd 180 28/07/12 6:01 PM28/07/12 6:01 PM

Building the Derby App in Android " 181

locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener); }

/* Class My Location Listener */

public class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { loc.getLatitude(); loc.getLongitude();

String Text = “My current location is: “ + “\nLatitude = “ + loc.getLatitude() + “\nLongitude = “ + loc.getLongitude(); Toast.makeText(getApplicationContext(), Text, Toast.LENGTH_SHORT).show(); }

@Override public void onProviderDisabled(String provider) { Toast.makeText(getApplicationContext(), “GPS Disabled”, Toast.LENGTH_SHORT). show(); }

@Override public void onProviderEnabled(String provider) { Toast.makeText(getApplicationContext(), “GPS Enabled”, Toast.LENGTH_SHORT). show(); }

@Override public void onStatusChanged(String provider, int status, Bundle extras) {} }

Accelerometer In order to track motion and position of the Android device you will leverage the device’s built-in accelerometer as it monitors the x, y, and z axes of the device.

Following is a basic Activity that monitors the Accelerometer in your device:

public class SensorsAccel extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* do this in onCreate */ mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensorManager.registerListener(mSensorListener, mSensorManager. getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);

c06.indd 181c06.indd 181 28/07/12 6:01 PM28/07/12 6:01 PM

182 " CHAPTER 6 GETTING STARTED WITH ANDROID

mAccel = 0.00f; mAccelCurrent = SensorManager.GRAVITY_EARTH; mAccelLast = SensorManager.GRAVITY_EARTH; }

private SensorManager mSensorManager; private float mAccel; // acceleration apart from gravity private float mAccelCurrent; // current acceleration including gravity private float mAccelLast; // last acceleration including gravity

private final SensorEventListener mSensorListener = new SensorEventListener() { public void onAccuracyChanged(Sensor sensor, int accuracy) {}

@Override public void onSensorChanged(SensorEvent se) { float x = se.values[0]; float y = se.values[1]; float z = se.values[2];

mAccelLast = mAccelCurrent; mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z)); float delta = mAccelCurrent - mAccelLast; mAccel = mAccel * 0.9f + delta; // perform low-cut filter } };

@Override protected void onResume() { super.onResume(); mSensorManager.registerListener(mSensorListener, mSensorManager. getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onStop() { mSensorManager.unregisterListener(mSensorListener); super.onStop(); } }

SUMMARY This chapter outlined the best reasons to target Android as your framework. It covered how to get your development environment confi gured, gave you solid examples of best practices while developing your application and connecting with the Google Play, and fi nally how to implement the Derby application with all its respective functionality within Android.

Chapter 7 will cover these same topics using the iOS stack, for targeting iPhone, iPod touch, and iPad devices. Please note that development will require a computer running OSX.

c06.indd 182c06.indd 182 28/07/12 6:01 PM28/07/12 6:01 PM