Implementing an app widget involves creating some XML metadata, associating that metadata with a <receiver>
element in your manifest, and implementing that receiver as an AppWidgetProvider
. Most likely in conjunction with a service that will handle any time-consuming work (e.g., network lookups), your provider will create and push out RemoteViews
when requested by the home screen. Note that app widgets are designed for infrequent update, since frequent polling for new widget contents can rapidly drain the device battery.
Live folders are, in essence, a simplified home-screen-launched look into the contents published by a ContentProvider
. In the screenshot shown previously, you see a “Phones” icon. Tapping that brings up a dialog over the home screen containing a list of all contacts containing phone numbers as you can see in Figure A-3.
Figure A-3. A Live Folder in Android 1.5
Tapping an individual contact, of course, brings up the detail screen for that contact.
To create your own live folders for your users to offer, you can add an intent filter watching for a CREATE_LIVE_FOLDER Intent
on an activity in your application. That activity, in turn, simply calls setResult()
with another Intent
object, this one describing the live folder, such as its icon, name, and display mode (e.g., LiveFolders.DISPLAY_MODE_LIST
). This Intent
also contains the Uri
pointing to the ContentProvider
whose information you are trying to display. That ContentProvider
should be updated to recognize the live folder Uri
and, on query()
, return an ID, title, and description of each piece of content in the provider (or a subset if appropriate). Android will take care of the rest, in terms of formatting the data in the live folder convention (large font title, small font description), pouring the query results into a list, etc.
Tying Up Loose Threads
A common pattern in Android is to perform some work on a background thread, then update something on the UI thread when the background work is complete. A simple way to handle this is to fork a background thread and use a Handler
or runOnUiThread()
to accomplish the UI thread work. However, the danger here is in forking too many threads — the user might do something that causes you to fork many threads in short order, bogging down the device at best. And while there are classes that can help you manage a work pool (e.g., LinkedBlockingQueue
), their use can be mildly tedious.
Enter AsyncTask
.
AsyncTask
manages a work queue with a thread pool, so you do not need to implement that yourself. Moreover, all of the communication between foreground and background threads are handled for you. All you need to do is override a few methods to describe what you want done in the background or in the foreground.
To create an AsyncTask
, simply extend one anonymously, like you might do to create a Runnable
. You can then override whatever methods you need to for the pattern you want:
• Override onPreExecute()
to specify something that should be done on the UI thread when the task is started
• Override doInBackground()
to indicate the work that should be done in the background thread
• Override onProgressUpdate()
to update your progress on the UI thread when doInBackground()
calls publishProgress()
(e.g., update a ProgressBar
)
• Override onPostExecute()
to do whatever work needs to be done on the UI thread after the background work is complete
Using your custom AsyncTask
is then a matter of calling execute()
on one of its instances, such as one might call run()
on a Runnable
.
Now, the Rest of the Story
Of course, there are many, many more things added to Android 1.5 beyond what is covered earlier. Here is a quick recap of other capabilities you will be able to take advantage of in Android 1.5.
Speech Recognition
Android 1.1 debuted Google Voice Search, where you could tap on a microphone icon text to the search field on the home screen, speak your search request, and have the search conducted on what you said.
Android 1.5 opens this up to be available to all applications. You can start an activity using an Intent using the RecognizerIntent.ACTION_RECOGNIZE_SPEECH
action and have the converted text supplied to you in response via onActivityResult()
.
IntentService
A common pattern, particularly when using AlarmManager
for scheduling periodic background work, is to have a service that implements onStart()
and forks a background thread to do the desired work. This runs the risk of forking too many threads, though, and managing your own work queue and thread pool can be annoying.
The IntentService
class wraps that pattern up for you. All you do is implement onHandleIntent()
, and Android will process all inbound Intents via a work queue on a background thread. Android will also automatically stop the service when the work queue becomes empty, to help minimize the memory footprint of your application.
Audio Playback Options
The SoundPool
class, largely undocumented in Android 1.1, is now ready for widespread use in Android 1.5. The SoundPool
is designed to play back multiple overlapping sounds, particularly useful for games. Moreover, you can specify priorities for these audio streams and a maximum number of streams, so your application can simply play back clips as needed (e.g., based on game events), and Android will ensure the maximum number of streams is not exceeded. That way, you can minimize the amount of CPU power audio playback requires.
Android 1.5 also offers AudioTrack
, whereby the device can play back audio that your code converts, perhaps from a streaming source, into PCM data. So, for example, should you want to implement a Voice-Over-IP (VOIP) application, you might use AudioTrack
to handle playback of the audio coming off of, say, the SIP connection.
Android 1.5 also introduces the JetPlayer
, designed to play back JET interactive music filesJET interactive music files.
Media Recording
Android 1.1 offered a MediaRecorder
class, but it would only record audio. Now, with Android 1.5, you can record video as well. You control the frame rate and size, along with the encoding (e.g., H.264) and output format (e.g., MP4). Android will then, on demand, record video off of the device’s camera to a file you specify.