Using Android Multimedia APIs
Working with Multimedia
The Android SDK provides a variety of methods for applications to incorporate audio and visual media, including support for many different media types and formats. Individual Android devices and developers can extend the list of supported media to other formats. Not every Android handset has the same multimedia capabilities.Always verify the capabilities of target devices before publication. The multimedia features of the Android platform generally fall into three categories: n Still images (recorded with the camera) n Audio (recorded with the microphone, played back with speakers or audio output) n Video (recorded with the camera and microphone, played back with speakers or audio output) Multimedia hardware such as a built-in camera, speakers, and audio or video output ports are optional features for Android devices. In addition to requiring the appropriate permissions, you can specify which optional features your application requires within the Android Manifest file.You can do this using the tag of the Android Manifest file declare that your application uses the camera. Remember, though, that the tag is not enforced by the Android platform. Instead, application stores such as the Android Market use this data to filter which applications to sell to certain devices. Any application that requests the CAMERA permission is assumed to use all camera features. If your application accesses the camera, but can function properly without it, you can also set the android:required field of to false. However, if your Using Android Multimedia APIs 336 Chapter 15 Using Android Multimedia APIs application requires a microphone and a camera with autofocus but not a flash to be present on the device, you can set the camera features your application requires specifically, like this: Tip Many of the code examples provided in this chapter are taken from the SimpleMultimedia application. The source code for this application is provided for download on the book website.
Working with Still Images
We illustrated how to display still images such as bitmaps by using the ImageView widget in Chapter 7,“Exploring User Interface Screen Elements.” If the user’s handset has builtin camera hardware, the user can also capture still images using the Camera object of the Android SDK. In addition, you can assign images as the home screen wallpaper using the WallpaperManager class. Capturing Still Images Using the Camera The Camera object (android.hardware.Camera) controls the camera on handsets that have camera support enabled.The preview feature of the camera relies on the assignment of a SurfaceHolder of an appropriate type.This enables applications to control the placement and size of the preview area that the camera can use. Follow these steps to add camera capture capability to an application without having to draw preview frames (the CameraSurfaceView displays the camera view): 1. Create a new class extending SurfaceView and implement SurfaceHolder.Callback. For this example, we name this class CameraSurfaceView. 2. In the surfaceCreated() method, get an instance of the Camera object. 3. In the surfaceChanged() method, configure and apply the Camera.Parameters; then call the startPreview() method. 4. Add a method in CameraSurfaceView for capturing images. 5. Add the CameraSurfaceView to an appropriate layout. 6. Include some way, such as a button, for the user to trigger the capturing of images. 7. Implement a PictureCallback class to handle storing of the captured image. Working with Still Images 337 8. Add the android.permission.CAMERA permission to the AndroidManifest.xml file. 9. Release the Camera object in the surfaceDestroyed() method. Let’s start by looking at the CameraSurfaceView class: import android.hardware.Camera; import android.view.SurfaceHolder; import android.view.SurfaceView; private class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera camera = null; public CameraSurfaceView(Context context) { super(context); mHolder = getHolder(); mHolder.addCallback(this); mHolder.setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceCreated(SurfaceHolder holder) { } public void surfaceDestroyed(SurfaceHolder holder) { } public boolean capture(Camera.PictureCallback jpegHandler) { } } The constructor for the CameraSurfaceView configures the SurfaceHolder, including setting the SurfaceHolder type to SURFACE_TYPE_PUSH_BUFFERS, which is used by the camera internals.The constructor is appropriate for calling from an activity’s onCreate() method.When the display is ready, the surfaceCreated() method is called. Here we instantiate the Camera object: public void surfaceCreated(SurfaceHolder holder) { camera = Camera.open(); camera.setPreviewDisplay(mHolder); } 338 Chapter 15 Using Android Multimedia APIs The Camera object has a static method to retrieve a usable instance. Because the Surface is now available, the configured holder can now be assigned to it. Information about the Surface might not yet be available, but at the next call to the surfaceChanged() method, the camera parameters will be assigned and the preview will start, as shown here: public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { List sizes = params.getSupportedPreviewSizes(); Camera.Size pickedSize = getBestFit(sizes, width, height); if (pickedSize != null) { params.setPreviewSize(pickedSize.width, pickedSize.height); camera.setParameters(params); } camera.startPreview(); } The surfaceChanged() method provides the application with the proper width and height for use with the camera preview.After assigning this to the Camera object, the preview starts.At this point, the users see whatever is in front of the camera on their device. If, however, you debug this within the emulator, you see a black-and-white checkerboard with an animated square on it, as shown in Figure 15.1.This is the simulated camera preview, so camera testing can take place, to some extent, on the emulator.