Monday, September 29, 2014

This week we're continuing the Starting From Scratch series. Today we're going to take a look at the Action Bar. The action bar UI was first defined in Android 3.x (API 11+). It provided a consistent navigation paradigm for applications as well as a convenient way to present context specific calls to action (like sharing, search, and etc).

Because Android only supported the Action Bar APIs on Android 11+ an open source project called ActionBarSherlock provided support for earlier versions of Android. ActionBarSherlock is a great project and very useful and eventually Android added a similar Appcompat project to it's v7 support library. While I'm a big fan of ActionBarSherlock I'm going to be using Android's Appcompat project in my example code for consistency.

Creating a project that has an Action Bar.

Setup the support appcompat project as a library. Note, for purposes of this series i'm using android-14 as my target version. You'll want this to match whatever Android version your app is targeting.

At this point you've got your application setup so that it can use an Action Bar, but it's not using one yet. In order to actually use an Action Bar you'll need to update your Android manifest to use a theme with an Action Bar. This can be done by using either Theme.AppCompat.Light or Theme.AppCompat (dark theme) as the theme of your activity in your AndroidManifest.xml. For example:

You'll also want to hint Android that you're going to support an older version of Android. You can do that by adding the following in your AndroidManifest.xml

<uses-sdkandroid:minSdkVersion="14"android:targetSdkVersion="19"/>

At this point you can compile your app and install it on your test device or emulator and you'll see an Action Bar. Make sure you either have an emulator running or a device attached in debug mode and run:

$ ant clean && ant debug && ant installd

Action Bar Menu

One of the great things about the Action Bar is that you can provide menu items directly in the action bar. This allows you to provide context specific menu options in a place that is convenient and easy for your users to access.

If you are planning on supporting the Action Bar via the Support Library then the first thing to do is to update your Activity to extend ActionBarActivity instead of Activity.

Android provides an Action Bar Icon Pack which you can download and use in your application. Simply copy the resources from the theme your app is using into your res/drawable folders. For this example we'll use the refresh icon.

When a user selects a menu item the onOptionsItemSelected method will be called. This method is called regardless of which Menu Item was selected. So you'll need to check the id of the item before you handle the action. Here's an example of handling our refresh action.

At this point you can compile your app and install it on your test device or emulator and you'll see an Action Bar with a refresh menu button. Selecting the refresh button will display message saying Refresh select.

Monday, September 22, 2014

This week we're continuing the Starting From Scratch series. Today we're going to take a look at Android Fragments. I'll discuss what a Fragment is, the Fragment life-cycle, creating a Fragments options menu, and finally I'll give a few Fragment tips I've found along the way.

What Is A Fragment

Simply put, a Fragment is a way to encapsulate a piece of your applications UI and UI interactions into a reusable set of resources and code. A Fragment is not tied to any particular Activity, but instead can be used within many Activities.

One example of where I've used this modularity in my applications is with Lists. Lists are common in mobile applications and often only differ by what they show. Using Fragments it would be easy to encapsulate creating, displaying, and interaction with a list into a set of reusable code and resources. You could then display multiple lists in a variety of places throughout your app using the same code and resources.

Fragment Life-cycle

The Fragment life-cycle is very similar to the Activity life-cycle we've already gone through in this series. You still have creating, starting, resuming, pausing, stopping, and destroying life-cycle events. But in addition to those you have life-cycle events that are associated with creating your Fragments view and attaching/detaching from an Activity. I'm not going to go through every Fragment life-cycle method but instead will call out two key life-cycle differences from Activities.

The first big difference is in creating the Fragments view. In an Activity this is done via the onCreate method. In a Fragment this is done in the onCreateView method. The onCreateView method is expected to return the view to use with this Fragment. Creating this view is pretty simple, just inflate your Fragments layout using the LayoutInflator passes into this method.

The next difference comes with the onActivityCreated method. The main purpose of this method is to allow the Fragment to restore state. There are two places that state can be stored. The first is internally within the Fragment via a Bundle. The second is in any arguments that were passed into the Fragment by it's composing Activity.

The internal saved state is passed into the onActivityCreated method in the form of a Bundle. The state that was passed in via arguments can be retrieved via a call to the getArguments method. It's important to restore Fragment state using the correct source of information. For instance, if you get the initial state from the Arguments but then update that state and save it in your Fragments Bundle then it's important to have some logic that determines the correct place to get the saved state from.

Creating menu items for your Fragment is a four step process. The fist step is declaring your Fragments options menu in an XML file. The second step is declaring that your Fragment has an options menu. The third step is inflating your options menu layout. The last step is handling users selecting an option in your Fragments menu.

First, create res/menu/my_first_fragment_menu.xml. The important thing to call out here is that each menu item needs to have an id. This id is important because there is one method that is called when the user selects a menu item. So we need a way to differentiate the desired action the user wishes to perform.

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/my_menu_item" android:showAsAction="ifRoom"/>

</menu>

Declaring that your Fragment has an options menu is done via a call to setHasOptionsMenu. This call should be made in the Fragments default constructor.

public MyFirstAndroidFragment(){ setHasOptionsMenu(true);}

Inflating your Fragments options menu is done by overriding the onCreateOptionsMenu method. This is done by passing the MenuInflater's inflate method the id of the menu XML file you created. If you want to use an ActionProvider in your Fragment, like the ShareActionProvider, this is the right time to set that provider up.

@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ inflater.inflate(R.menu.my_first_fragment_menu, menu); // this is a good time to setup a share action provider}

Finally, handling the selection of a menu option is done by overriding the onOptionsItemSelected method. This method is called when any menu item is selected. It's a good idea to encapsulate the menu item action into it's own method and just call that method when the item has been selected. It's important to remember to return true in the onOptionsItemSelected method if you did handle the menu item selection.

One thing that often causes people to stumble is putting a video, web browser, or any other stateful object inside a Fragment. The reason is that when the device changes orientation the Activity (and it's child Fragments) are torn down and recreated. This causes problems when the user isn't expecting it. One way to solve this problem is to tell Android to retain the Fragment instance across Activity re-creation. This is done via a call to setRetainInstance. This call should be made in the Fragments default constructor.

public MyFirstAndroidFragment(){ setRetainInstance(true);}

Cross Fragment Coordination

Cross Fragment coordination is done by declaring an interface in your Fragment for any events you want to allow others Fragments to respond to. The Activities that compose your fragment will implement your Fragments interface and can then dispatch messages to other Fragments that it is composing. This allows you to keep your concerns separated correctly by NOT tightly coupling your Fragment with any other Fragment. It's okay to tightly couple your Activity with your Fragment because your Activity is composing that Fragment.

Monday, September 15, 2014

This week we're continuing the Starting From Scratch series. Today we're going to take a look at Android Activities. I'll discuss what an Activity is, how you create one, the Activity life-cycle, launching an Activity programmatically, and finally I'll give a few Activity tips I've found along the way.

What Is An Activity

According to the Android documentation, an Activity is "... a single, focused thing that the user can do." Yeah, that's pretty vague. So let's break it down.

In the early days of Android (pre-tablet) an Activity represented pretty much everything on the screen, how it got there, and how you interact with it. Basically the Activity was analogous to a "screen" in an application. If you wanted to display a different screen you either had to dynamically tear down the current screen and rebuild the new screen (very laborious) or, preferably, start a new Activity which owned the UI and interactions for the new screen. This allowed developers to encapsulate the concepts within a screen pretty nicely and manage workflow easier.

As Android matured, and tablets became mainstream, it became necessary to reuse portions of an Activity within other Activities. Thus was born the Fragment (which I'll talk about later in this series). Prior to Fragments a typical application would have many Activities. Once Fragments were introduced the number of Activities an application had were reduced from one per screen to one per workflow.

Creating an Activity

There are two steps necessary when creating an Activity. The first is to write the Java class which extends the Activity class. This class should implement any necessary life-cycle events (which are outlined below). The second step is to declare the Activity in the Android manifest. You can see an example of this by looking at the initial Activity that was created for your application in your AndroidManifest.xml.

Activity Life-cycle

An Activity has several states that it can be in. Those states are associated with creating, starting, resuming, pausing, stopping, or destroying the Activity.

Creating

When an Activity if first being created a call will be made to the Activities onCreate method. The onCreate method is responsible for associating a UI layout with the Activity. This is done via a call to the setContentView method with the associated layout ID. As mentioned previously in this series, a layout is a composition of the UI elements to display on screen.

If you have any state that needs to be restored before the official call to onRestoreInstanceState you can do it after the call to setContentView using the saved instance state Bundle passed in. The typical reasons you may want state restored here is if you want to be able to make any decisions on the other life-cycle methods based on the current state of the Activity. Because of this, the onCreate method is passed a Bundle which will contain any state that was saved when the Activity was paused.

You cannot assume that the Bundle passed in to the onCreate method will exist. In the case that there is no previous state or if it's the first time the Activity is run the Bundle will be null. Therefore it is very important to check to make sure the Bundle exists before you try to use it. If the Bundle exists you can use the information you've saved in it to restore the internal state of the Activity.

NOTE: It is really important to draw the distinction here between resetting the internal state of an Activity and resetting the UI of an Activity. YOU SHOULD NOT try to interact with the UI in the onCreate method. The onCreate method is called when the Activity is starting but before it is displayed on the screen. If you try to get a handle to UI elements they will not exist.

Restarting

The onCreate method is only called when the Activity is not already in memory. Often it is the case that the Activity has been paused but not cleared out of memory. In this case when the Activity is about to be re-started the onRestart method is called. For most people there really isn't anything you need to do in onRestart. The internal state of your Activity will be the same as when it was paused, so there is nothing to really restore. The exception being if you are using a Cursor.

@Override

public void onRestart() {
}

Starting

The onStart method is called after either onCreate or onRestart when the Activity is visible to the user. The Activity UI is not yet ready to be interacted with. At this point you still don't want to do anything programmatically with UI elements but you are able to reset internal Activity data.

@Override

public void onStart() {
}

Resuming

Finally, we're at the point in the Activity life-cycle where you can do something with the UI. The onResume method is called right after the Activity has been displayed on the screen. At this point the UI is ready to be interacted with. If you did not register your UI event listeners in the layout file this is where you would want to register those listeners.

@Override

public void onResume() {
}

At this point in the life-cycle your Activity is considered to be running.

Pausing

When your Activity is about to go into the background, but it is still active, the onPause method is called. This happens when another Activity is about to be put on top of your Activity (while it's still running) or your Activity is about to be put into the background or killed.

@Override

public void onPause() {
}

This is a good time to commit changes to data and unwire any listeners that you've set up. It's important to note that onPause doesn't necessarily mean that your Activity is going into the background. This will also be called when a dialog is displayed on top of your Activity. In this case the next life-cycle event will be onResume instead of onStop.

It's important that this method returns very quickly as the onResume method for the Activity about to show will not get called until this method returns.

Stopping

The onStop method is called when another Activity has come to the foreground and fills the entire screen. On stop cause be used to save state as well as stop things that are time intensive.

@Override

public void onStop() {
}

Destroying

The onDestroy method is called right before your Activity is about to be removed from memory. This is a good time to clean up the internal handles that your Activity may have.

@Override

public void onDestroy() {
}

Saving State

In the previous life-cycle events I mentioned saving/restoring Activity state several times. Users will expect an Activity to be in the same state that they left it in. The user can leave the Activity for a variety of reasons like to answer a phone call or to use another app. Sometimes when a user has a lot of applications running or is doing something very memory intensive Android needs to completely remove the Activity from memory when it's not on the screen. In that case displaying the Activity again will cause it to re-display as if it was never on the screen to begin with. This is why it is important to make sure you restore the internal Activity state if there is any to restore

Launching an Activity

There are two main ways to launch an Activity. The first way is to specify the type of action you want performed and allowing the user to select the appropriate application they want to handle that. This is commonly used when sharing data or launching a url.

The second way to launch an Activity is by class name. This is the case when you want to launch a very specific Activity. Typically this is how you would launch another Activity within your application.

In either case launching an Activity is a two step process. The first step is to create an Intent which details what you want to do. You decide how you want to launch the Activity based on the Intent constructor you select. The second step is to call the startActivity method from your Activity.

Activity Tips

Only restore an Activities internal state in onCreate. Never try to restore UI.

The first time an Activity is being displayed, the Bundle passed into onCreate will be null.

Don't change the name of the Activity used to start the application. Changing that will cause the any home screen icons associated with the previous Activity to be broken after the application is updated. The is because the icons are associated with the previous Activity name.

Monday, September 8, 2014

This week we're continuing the Starting From Scratch series. Today we're going to take a look at Android resources. There are many types of resources in Android. First i'm going to outline the different resource types. Then I'll explain what configuration qualifiers are and what they're used for. Finally I'll call out a few important configuration qualifiers that will be used in most applications.

All resources in your Android application are stored in the res/ folder of your project. Resources are grouped by type and configuration.

Resource Types

The easiest way to explain the different resource types is to simply list out the folder structure and what type of resource is provided in each folder. The following is a list of the various resource types.

Configuration Qualifiers

One of the most powerful things that you can do with Android resources is specify configuration qualifiers for the various resource types. Configuration qualifiers allow you to target specific resources towards a specific device, screen size, or etc. There are different configuration qualifiers depending on the context in which they are used.

Configuration qualifiers are appended to the resource type and separated with a dash (<resource type>-<configuration qualifier>). I won't go into detail on each qualifier as table 2 in the Android resource documentation provides an exhaustive list of all qualifiers. But I want to call out a few different qualifiers that are important to know.

Screen Pixel Density

Screen pixel density qualifiers are used with drawables and help you to avoid images that look terrible from being scaled up as well as providing lower resolution images for screens that are not very dense. There are six types of screen pixel densities nodpi, tvdpi, ldpi, mdpi, hdpi, and xhdpi.

nodpi is for resources that you do not want scaled. tvdpi is for screens that fall in-between mdpi and hdpi (like televisions). ldpi, mdpi, hdpi, and xhdpi are for low, medium, high, and extra high density screens respectively.

For example, images in the res/drawable-mdpi/ folder should be images that are ideal on a medium density screen.

If a screen pixel density is not specified that's ideal for the device Android will scale up/down based on the best match density.

Language and Region

Language and region qualifiers use the ISO 639-1 language and an optional ISO 3166-1-alpha-2 region preceeded by a lowercase r. For example fr-rCA for Canadian French. Language and region qualifiers are the easiest way to localize your application and provide different text translations for different languages and regions.

Screen Size

Screen size qualifiers allow you to target screens using small, normal, large, and xlarge. When targeting Android versions prior to Honeycomb these are best way to provide layouts optimized to specific screen sizes. But, it's important to note that the screen size qualifier is not the ideal way to determine phone versus tablet. There are some tablets with lower screen sizes than some of the higher end phones. This is because the size relates to the density of the screen.

If you're providing an application that supports a version of Android prior to Honeycomb and you want to target screen size you should use a combination of screen size and the smallest width qualifier.

Smallest Width

The smallest width qualifier allows you to specify screen sizes with a minimum number of density independent pixels. The format us sw<N>dp. For example layout-sw600dp provides a layout for screens with a minimum of 600 density independent pixels.

Monday, September 1, 2014

This week I'd like to start a new series called Starting From Scratch. The idea behind the Starting From Scratch series is to give you real world insight into a specific topic. According to PC World, Android currently makes up 84% of the overall smartphone market. So I thought a good place to start the Starting From Scratch series would be with Android.

If you've been following this blog for a while, you know that I'm not a fan of the traditional IDE. Given that, I won't be using Eclipse for this series. I'm going to walk you through creating a project from the command line.

Installing the Android SDK Tools

The first thing you need in getting started with Android development is to download the SDK. Head over to the Android developer site and download the SDK tools (you don't need the ADT plugin for this series). The second thing you need to do extract the SDK tools and, for convenience, add them to your path.

On *nix, for the latest version to date, this can be accomplished by running:

Installing the SDK tools doesn't actually install any of the SDKs. The next thing we need to do is install one or more of the Android SDK versions. Which SDK versions you install depends on your applications target audience. You should take a look at the Android Platform Versions website to see what versions you should install. For this tutorial we're going to install the platform tools and Android 4.4.2.

$ android update sdk --no-ui -t tool,platform-tool,19

Creating a project

The android tool that comes with the Android SDK allows you to create projects from the command line. There are several things that you need to provide the tool when creating the project. These are:

Android version

Package name

Path of the project

Name of the Application

Name of the main Activity

The Android version is the name of the Android version you want to target. You can get a list of all installed Android versions by running $ android list target.

The package name is the namespace to use within your project. This is typically your domain in reverse. For instance if your domain was www.foo.com your package name would be com.foo.

The path is the directory where the project files should be created under.

The name of the application is, well, the name of the application.

The name of the main Activity is the name of the Activity that will be launched when a user opens the application. I'll get into what an Activity is later in this series.

The default Android command line build system is built on top of Apache Ant. Ant uses a build file which tells it how to to build a project. When you installed the Android SDK tools you got several Android specific Ant targets which have been created to allow compilation, signing, and other interactions with your application build artifacts. When you created the project using the android binary a build.xml file was created for you in your project directory. This is the Ant build file.

Running the command ant debug tells the Android build system to compile the application for debug. The ant installd command tells Ant to install the debug Android package (APK) on the connected device.

About Me

I’ve been in the technology industry for 14+ years mostly as a Software Developer. I've worked on projects ranging from a Ruby on Rails Portal, a high performance/low latency .NET search stack, R&D for building infrastructure in the cloud including automated server builds using Chef, to architecting and building iOS and Android Mobile platforms and frameworks.I've also spent some time building Android, iOS, Windows Phone, and Bada mobile applications that focused on the presentation of long form audio/video.The middle of my career was spent at MSNBC working on their content management publishing platform, their video syndication system, as well as being a co-creator of their iOS iPad framework from which the Rachel Maddow, Today Show, and Nightly News iPad apps were built.Finally, the beginning of my career was spent writing software on government contracts with a few years spent writing criminal investigation software.