Saving a BitmapBased Canvas Drawing
What good would it be to just draw on an image without being able to save it after the user has created a masterpiece So far we have just drawn images let's look at how we can commit these wonderful drawings to permanence. Well, at least let's look at how we can save them to the SD card. Unsurprisingly, it will be a similar process to what we used in the second chapter to save images captured from our custom camera application. Let's go over the changes that we can make to our ChoosePictureDraw...
Text on a Path
Text isn't limited to being drawn on a horizontal line it can be drawn on a Path as well. Here is an example. Paint paint new Paint paint.setColor Color.GREEN paint.setTextSize 20 Path p new Path p.moveTo 20, 20 p.lineTo 100, 150 p.lineTo 200, 220 canvas.drawTextOnPath Hello this is text on a path, p, 0, 0, paint
Audio Capture with an Intent
The easiest way to simply allow audio recording capabilities in an application is to leverage an existing application through an intent that provides recording capabilities. In the case of audio, Android ships with a sound recorder application that can be triggered in this manner. The action used to create the intent is available as a constant called RECORD_SOUND_ACTION within the MediaStore.Audio.Media class. Here is the basic code to trigger the built-in sound recorder. Intent intent new...
Preview Surface
Also before we can get started using the camera, we need to create some type of Surface for the Camera to draw viewfinder or preview images on. A Surface is an abstract class in Android representing a place to draw graphics or images. One straightforward way to provide a drawing Surface is to use the SurfaceView class. SurfaceView is a concrete class providing a Surface within a standard View. To specify a SurfaceView in our layout, we simply use the lt SurfaceView gt element within any normal...
MediaRecorder Output Formats
The next method to be called in sequence is setOutputFormat. The values this takes in are specified as constants in the MediaRecorder.OutputFormat inner class. This specifies that the file written will be an MPEG-4 file. It may contain both audio and video tracks. This represents a raw file without any type of container. This should be used only when capturing audio without video and when the audio encoder is AMR_NB. This specifies that the file written will be a 3GPP file extension .3gp . It...
MediaStore for Audio
We explored using the MediaStore for images early on in this book. Much of what we learned can be leveraged for the storage and retrieval of other types of media, including audio. In order to provide a robust mechanism for browsing and searching for audio, Android includes a MediaStore.Audio package, which defines the standard content provider. Accessing audio files that are stored using the MediaStore provider is consistent with our previous uses of the MediaStore. In this case, we'll be using...
MediaRecorder Audio Sources
The first method that should be called after the MediaRecorder is instantiated is setAudioSource. setAudioSource takes in a constant that is defined in the AudioSource inner class. Generally we will want to use MediaRecorder.AudioSource.MIC, but it is interesting to note that MediaRecorder.AudioSource also contains constants for VOICE_CALL, VOICE_DOWNLINK, and VOICE_UPLINK. Unfortunately, it appears as though there aren't any handsets or versions of Android where recording audio from the call...
Video Thumbnails from the MediaStore
We could, starting with Android 2.0 API Level 5 , pull out the thumbnails associated with each video file from within the loop. We need the ID of the video file that is in our list of columns to select MediaStore.Video.Media._ID , which we can then use in the where clause of the managedQuery. int id String thumbColumns MediaStore.Video.Thumbnails.DATA, Cursor thumbCursor thumbColumns, MediaStore.Video.Thumbnails.VIDEO_ID id, null, null if thumbCursor.moveToFirst
Audio and Video Bitrates
Video encoding bitrates can be set using the setVideoEncodingBitrate method on the MediaRecorder and passing in the bitrate requested in bits per second. A low bitrate setting for video would be in the range of 256,000 bits per second 256 kbps , while a high bitrate for video would be in the range of 3,000,000 bits per second 3 mbps . We can also specify the maximum bitrate that we would like used for the encoded audio data. We do so by passing the value as bits per second into the...
Supported Audio Formats
Android supports a variety of audio file formats and codecs for playback it supports fewer for recording, which we'll discuss when we go over recording . AAC Advanced Audio Coding codec as well as both profiles of HE-AAC, High Efficiency AAC , .m4a audio m4a or.3gp audio 3gpp files. AAC is a popular standard that is used by the iPod and other portable media players. Android supports this audio format inside of MPEG-4 audio files and inside of 3GP files which are based on the MPEG-4 format ....
prepareAsyncO Preparing
Looping true amp amp playback completes Looping true amp amp playback completes Looping false amp amp onCompletlonO invoked on OnCompletionListener Looping false amp amp onCompletlonO invoked on OnCompletionListener Figure 6-1. MediaPlayer state diagram from Android API Reference Figure 6-1. MediaPlayer state diagram from Android API Reference Here is a full MediaPlayer example that uses prepareAsync and implements several listeners to keep track of its state. package import java.io.IOException...
Local Service plus MediaPlayer
Now that we have created an example Service, we can use it as a template to create an application to play audio files in the background. Here is a Service, and an activity to control the Service that does just that, allows us to play audio files in the background. It works in a similar manner to the custom audio player example from the last chapter, as it is using the same underlying MediaPlayer class that Android makes available to us. package import android.app.Service import...
Visualizing Frequencies
One common way that people typically use to analyze audio is to visualize the frequencies that exist within it. Commonly these types of visuals are employed with equalizers that allow the adjustment of the levels of various frequency ranges. The technique used to break an audio signal down into component frequencies employs a mathematic transformation called a discrete Fourier transform DFT . A DFT is commonly used to translate data from a time base to a frequency base. One algorithm used to...
Raw Audio Capture and Playback Example
Here is a full example that records using AudioRecord and plays back using AudioTrack. Each of these operations lives in their own thread through the use of AsyncTask, so that they don't make the application become unresponsive by running in the main thread. package import java. import java. import java. import java. import java. import java. import java. import java. import android.view.View.OnClickListener public class AltAudioRecorder extends Activity implements OnClickListener We have two...
Adding Video Metadata
As we discussed in Chapter 9, Android's MediaStore content provider has a portion, MediaStore.Video, dedicated to video in addition to the portions for image and audio files and metadata that we have previously looked at. When triggering the Camera application via an intent, the Uri to the newly recorded video file that is returned is a content style Uri, which is used in combination with a content provider in this case, the MediaStore. In order to add additional metadata, we can use the Uri...
Altering Contrast and Brightness
Adjusting the brightness and contrast of an image can be done by increasing or decreasing the color values. This code will double the intensity of each color channel, which affects both the brightness and contrast in an image as illustrated in Figure 3-15 ColorMatrix cm new ColorMatrix float contrast 2 cm.set new float contrast, 0, 0, 0, 0, 0, contrast, 0, 0, 0, 0, 0, contrast, 0, 0, 0, 0, 0, 1, 0 paint.setColorFilter new ColorMatrixColorFilter cm Figure 3-15. ColorMatrix with each color's...
Image Capture Using the BuiltIn Camera Application
With mobile phones quickly becoming mobile computers, they have in many ways replaced a whole variety of consumer electronics. One of the earliest non-phone related hardware capabilities added to mobile phones was a camera. Currently, it seems someone would be hard pressed to buy a mobile phone that doesn't include a camera. Of course, Android-based phones are no exception from the beginning, the Android SDK has supported accessing the built-in hardware camera on phones to capture images. The...
Drawing on Existing Images
Since we are drawing on a Canvas, we can use techniques described in the previous chapter to draw an image to the Canvas and then draw on top of that image. package import java.io.FileNotFoundException import android.app.Activity import android.content.Intent import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Canvas import android.graphics.Color import android.graphics.Matrix import android.graphics.Paint import android.net.Uri import android.os.Bundle...
Network Video Playback
Android supports HTTP and RTSP video playback in all three video playback methods discussed in Chapter 9. Using either the built-in Media Player activity via an intent or the VideoView class to play either form of network video requires no source code changes. Simply use the HTTP or RTSP URL as the video Uri, and it will work as long as the format is supported. Here is the ViewTheVideo activity example from Chapter 9 that uses a VideoView with an RTSP URL to a video from YouTube's mobile site....
Raw Audio Recording with AudioRecord
Aside from using an intent to launch the sound recorder and using the MediaRecorder, Android offers a third method to capture audio, using a class called AudioRecord. AudioRecord is the most flexible of the three methods in that it allows us access to the raw audio stream but has the least number of built-in capabilities, such as not automatically compressing the audio. The basics for using AudioRecord are straightforward. We simply need to construct an object of type AudioRecord, passing in...
Drawing a Bitmap onto a Bitmap
Before we get into the specific mechanisms used to alter the images, let's look at how we can create a new, empty Bitmap object and draw an existing Bitmap into that. This is the process that we will be using to create altered versions of our images. In the foregoing example, we have a Bitmap object instantiated with an image that has been selected by the user. It has been instantiated by a call to BitmapFactory's decodeStream method, as we learned how to do in Chapter 1. Bitmap bmp...
Preview Surface 1
Before we can move forward, we need to specify a Surface for the MediaRecorder preview viewfinder images to draw. We'll handle this in a similar manner to how we handled the preview images in our custom camera examples in Chapter 2. Let's go through an abbreviated example. First, we'll create a Surface in our layout. lt xml version 1.0 encoding utf-8 gt lt SurfaceView android id id CameraView android layout_width 640px lt LinearLayout gt In our activity, we need to implement...
Playback Using a MediaPlayer
In Chapters 6 and 7, those dealing with audio and networked audio, we introduced the MediaPlayer class. The very same MediaPlayer class can also be used for video playback, in much the same manner. Using a MediaPlayer object for video playback gives us the greatest amount of flexibility in the control of the playback itself, as compared with playing video using VideoView or via an intent. In fact, the mechanism used to handle the actual playback within the VideoView and the activity triggered...
Full MediaStore Video Example
Here is a full example that retrieves all of the available video files from the MediaStore and displays each of their thumbnail images and titles. Figure 10-1 shows the following example running. This example uses the MediaStore.Video.Thumbnails class which is available in Android 2.0 API Level 5 and above. package import java.io.File import java.util.ArrayList import java.util.List import android.app.Activity import android.content.Context import android.content.Intent import...
Other MediaRecorder Methods
MediaRecorder has a variety of other methods available that we can use in relation to audio capture. getMaxAmplitude Allows us to request the maximum amplitude of audio that has been recorded by the MediaPlayer. The value is reset each time the method is called, so each call will return the maximum amplitude from the last time it is called. An audio level meter may be implemented by calling this method periodically. setMaxDuration Allows us to specify a maximum recording duration in...
Streaming Audio via HTTP
One way that live audio is commonly delivered online is via HTTP streaming. There are a variety of streaming methods that fall under the umbrella of HTTP streaming from server push, which has historically been used for displaying continually refreshing webcam images in browsers to a series of new methods being put forth by Apple, Adobe, and Microsoft for use by their respective media playback applications. The main method for streaming live audio over HTTP is one developed in 1999 by a company...
Image Compositing
Compositing is the act of putting together two images, allowing features of both images to be seen. In the Android SDK, we can accomplish compositing by first drawing one Bitmap to a Canvas and then drawing a second Bitmap to the same Canvas. The only difference is that we specify a transfermode Xfermode on the Paint when drawing the second image. The set of classes that can be used as a transfermode all derive from the Xfermode base class and include one called PorterDuffXfermode. The...
Generating Samples
Using a little bit of math, we can algorithmically create these samples. The classic sine wave can be reproduced. This example produces a sine wave at 440 Hz. package import android.view.View.OnClickListener public class AudioSynthesis extends Activity implements OnClickListener AudioSynthesisTask audioSynth boolean keepGoing false float synth_frequency 440 440 Hz, Middle A Override public void onCreate Bundle savedInstanceState super.onCreate savedInstanceState setContentView R.layout.main...
Audio Sample Rate
Along with bitrate, the audio sample rate is important in determining the quality of the audio that is captured and encoded. The MediaPlayer has a method, setAudioSampleRate, which allows us to request a specific sample rate. The sample rate passed in is in Hz hertz , which stands for the number of samples per second. The higher the sample rate, the larger the range of audio frequencies that can be represented in the captured file. A sample rate on the low end, 8,000 Hz, is suitable for...
Implementing the Camera
Now that we have the activity and preview Surface all set up, we are ready to start using the actual Camera object. When the Surface is created, which will trigger calling the surfaceCreated method in our code due to the SurfaceHolder.Callback, we can obtain a Camera object by calling the static open method on the Camera class. public void surfaceCreated SurfaceHolder holder camera Camera.open We'll want to follow that up with setting the preview display to the SurfaceHolder we are using, which...
Android Media
Developing Graphics, Music, Video and Rich Media Apps for Smartphones and Tablets Developing Graphics, Music, Video, and Rich Media Apps for Smartphones Pro Android Media Developing Graphics, Music, Video, and Rich Media Apps for Smartphones and Tablets Copyright 2009 by Shawn Van Every All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval...























