Tuesday, June 30, 2015

Here's a very simple example to get you started with an Android ListView. This example just displays a hard-coded list of colors in a ListView control. The key components are the ArrayAdapter and the additional layout file.

ListViews work via an adapter pattern. So, we have to create an adapter that lists the items that we're going to display in the ListView. We also have to create a layout with the type of entity that we're displaying for each item in the ListView. In this example, each item in the ListView will be a simple TextView. However, it could be something more involved (like an image).

In Android, each screen or presentation is done via its own activity. So, we will have a main activity that runs when the application is first started. Launching a new activity is simple, using an explicit intent.

Let's say that we have a button that launches a new activity when it's clicked. Here's the code for doing this, using an explicit intent.

public void openOtherActivityClick(View view) {
// create an explicit intent and specify
// the exact class name of the activity that we want
Intent otherActivityIntent = new Intent(this, OtherActivity.class);
// start the other activity
startActivity(otherActivityIntent);
}

Wednesday, June 24, 2015

Often times, you will need to run an operation in the background of your Android app, so that you're not blocking the UI thread. For short running operations, AsyncTask is the perfect tool for the job. The best part is that it's very easy to use.

Let's consider an app that takes an image and adjusts the contrast of the image to make it brighter. By clicking a button in the app, a predefined image is made brighter and then displayed on the screen. To implement the image contrast functionality, let's pretend that we've already written a Java class called ImageUtils that contains a method called setContrast. The signature for this method looks like this:

public Bitmap setContrast(Bitmap image, double contrastValue);

Naively, we could call this method within our button's onClickListener. However, if we do that, then while the image is being manipulated, we will block the UI thread and cause the application to "freeze". So, we can use AsyncTask to perform this image manipulation in the background!

Here's a naive approach to processing the image, within the button's onClickListener:

Thankfully, to use AsyncTask, all that's needed is for us to create a new Java class that extends AsyncTask. Within this class, we'll call our setContrast method. In a sense, we're simply wrapping our current image logic with a class that extends AsyncTask. Pretty simple indeed! Here's how this new class looks:

The generic types that are defined on our AsyncTask class are specifying that a Bitmap is passed into the doInBackground method and a Bitmap is returned by our onPostExecute method.

The VOID type specifies the type that's used to as the unit of progress for the background operation. I didn't use a "progress indicator" in this example, but this is where you would do this type of indication. You could specify this as an Integer and then override the method onProgressUpdate(Integer... progress) to set a progress indicator.

If you really want to get an appreciation for AsyncTask, you can add a Thread.sleep(5000) inside your doInBackground method. You'll notice that you can still click around on the screen while the operation is happening in the background. If instead, you put the image processing logic directly inside the button's onClickListener, you will find that the screen becomes non-responsive while the image is being processed (namely that the button remains depressed and it's obvious that the UI is blocked).

So, next time you need to quickly make an operation run in the background, consider using AsyncTask. Note that this works great for operations that only take a few seconds to complete. However, if you have long running operations, you should consider using an Android service. This is because AsyncTask processes are still connected to the activity stack that executed the AsyncTask. As all of us Android developers know, the Android OS could decide to kill your activity at any time, if the OS needs to recover system resources. This could leave your background task in an unknown state. If you have a long running process, you'll want to use a service that continues to run, just in case your activity is shut down for some unplanned reason.

Saturday, January 24, 2015

There are times that you want to utilize another application on the Android device for some action in your application. For example, let's say you have an application that opens a browser and navigate to a web site. You wouldn't want to build your own browser (most likely anyway), so you'd just let the Android device choose an application to use for navigating to the web site. When you do this, you're using an implicit intent. Here's how you do it.

The chooserIntent is optional. I'm using it to add a custom title to the chooser dialog. You can simply create the intent and call "startActivity(intent)" and let Android display the standard chooser dialog.

In this example, we just told Android to include any application that can handle the ACTION_VIEW intent. What if you have written your own application that you want to include as an option for handling this type of intent? In your application's AndroidManifest.xml file, you simply add an intent-filter within the definition of the activity.

For example, here I've added a second intent-filter to handle any applications that initiates an intent on the Intent.ACTION_VIEW with "http" requests, just like in the example above.

Monday, January 19, 2015

There are many things that can happen outside of your Android application. One of the most common occurrences is a change in the device settings. For example, the user might leave your app running, while they go into the display settings and change the font size.

When the user goes back to your application, the activity in your application is recreated, which means onCreate() is called all over again. Most times, this is o.k. In fact, for the most part, you want to trust Android to handle these global settings and manage the effects of those changes to the lifecycle of your application's activities. However, there are times when you may want to manually handle these configuration changes. One obvious advantage to manually handling the config changes, is that you can avoid the activity being killed and recreated. Note that onStart(), onResume(), and onRestart() will still be called.

To manually handle config changes, simply add the "android:configChanges" attribute to the activity in your Manifest file. For example:

When the font size changes in the device settings, your onConfigurationChanged() method is called and an object containing the new device configuration is passed to the method, for you to handle as you please.

Saturday, January 17, 2015

If you know Java, you can learn Android development. In this blog post, we'll create a very simple Android application in Android Studio and run it with an Android emulator.
To get started, download the Android Studio installer here: http://developer.android.com/sdk/index.html.

Take note of the system requirements, most importantly being the Java Development Kit (JDK).

Now that you've installed Android Studio, let's create a simple application for Android. Start up Android Studio and click the option for "Start a new Android Studio project".

The next dialog prompts you to name your application and provide the Company Domain. For all intents and purposes, this is simply the package name for your Java classes. Choose a name for your application and package directory and click the "Next" button.

The next dialog prompts you for the platform where you want to develop and deploy your application. Android is a very cool platform, in that you can develop apps for TV and wearables (e.g. watches), but for this example, I'm going to select "Phone and Tablet" and choose "API 8: Android 2.2 (Froyo)" for my minimum SDK version. When you develop applications for Android, you specify the minimum and maximum SDK version. For this application, API 8 Froyo will be the minimum SDK version needed to run the application. After you select the platform, click "Next".

Next, you select an activity for you application and click "Next". I'm going to choose a Blank Activity. As you get more experienced with Android development, you'll become familiar with activities and the Activity class. For now, you can think of an activity as a screen or view in your application. By choosing Blank Activity, the application will have a blank screen to start building an application.

The next dialog prompts you for a name for the activity. I'm going to leave it as MainActivity and click "Finish".

After clicking the "Finish" button, you'll see a progress dialog, as your application is being created.

When Android Studio is finished building your project, you'll see your new Android application open in the IDE.

Next, let's run the application in an Android emulator. You can start up an emulator from the menu option under Tools-> Android -> AVD Manager. Note that AVD Manager is short for Android Virtual Device Manager.

The AVD Manager dialog prompts you to start a virtual device / emulator. If you don't have a virtual device created, you need to click the button for "Create Virtual Device...". This will allow you to device configuration and Android API version that you want to emulate. For this example, I'm going to use the virtual device that emulates a Nexus 5 using API 21. Because I already have it created, I'll click the green start button on the right side of the device listing, to start the device emulator.

Next, you'll see a progress dialog, as your device emulator is starting.

Note that it can take a few minutes to start the emulator, so be patient. After your emulator has started, you'll see the Android welcome screen (just as you'd see if you were powering on an actual Android device). After powering on, you'll see the Android home screen.

To unlock the welcome screen, just click on the unlock icon and swipe upwards, as you would on an actual Nexus device.

Now that the emulator is running, go back to your Android Studio IDE to run your application on the emulator. From the Android Studio menu, select Run -> Run...

You'll be prompted for the device where you want to run the application. Choose the emulator that's already running and click "OK".

After a few seconds, you'll see the application running on the device emulator.

Congratulations, you've just created your first Android application! In the next Android blog post, I'll talk about the project structure and the files in the project, as well as provide a more involved application example.