UNIT-III
Graphics and animation – Custom views, Canvas, Animation APIs, Multimedia – Audio/Video
playback and record, Location awareness.
Native data handling –file I/O, Shared preferences, Mobile databases such as SQLite, and
Enterprise data access (via Internet/Intranet).
1. Custom Views:
Android offers a sophisticated and powerful componentized model for building your UI, based
on the fundamental layout classes: View and ViewGroup. To start with, the platform includes a
variety of prebuilt View and ViewGroup subclasses — called widgets and layouts,
respectively — that you can use to construct your UI.
A partial list of available widgets includes Button, TextView, EditText, ListView,
CheckBox, RadioButton, Gallery, Spinner, and the more special-purpose
AutoCompleteTextView, ImageSwitcher, and TextSwitcher.
Among the layouts available are LinearLayout, FrameLayout, RelativeLayout, and
others.
If none of the prebuilt widgets or layouts meets our needs, we can create our own View
subclass.
Creating your own View subclasses gives you precise control over the appearance and function
of a screen element. Some examples of what we can do with custom views:
You could create a completely custom-rendered View type, for example a "volume
control" knob rendered using 2D graphics.
You could combine a group of View components into a new single component, perhaps
to make something like a ComboBox (a combination of popup list and free entry text
field), a dual-pane selector control (a left and right pane with a list in each where you can
re-assign which item is in which list), and so on.
You could override the way that an EditText component is rendered on the screen.
You could capture other events like key presses and handle them in some custom way
(such as for a game).
The Basic Approach
Here is a high level overview of creating own View components:
1. Extend an existing View class or subclass with your own class.
2. Override some of the methods from the superclass. The superclass methods to override
start with 'on', for example, onDraw(), onMeasure(), and onKeyDown(). This is similar to
the on... events in Activity or ListActivity that you override for lifecycle and other
functionality hooks.
3. Use your new extension class. Once completed, your new extension class can be used in
place of the view upon which it was based.
View lifecycle
Constructor
Every view starts it’s life from a Constructor.
First, create a new file and call it attrs.xml. In that file could be all the attributes for different
custom views
onAttachedToWindow
After parent view calls addView(View) that view will be attached to a window. At this stage our
view will know the other views that it is surrounded by.
onMeasure
Means that our custom view is on stage to find out it’s own size. It’s very important method, as
for most cases you will need your view to have specific size to fit in your layout.
onLayout
This method, incorporates assigning a size and position to each of its children.
onDraw
That’s where the magic happens. Having both Canvas and Paint objects will allow you draw
anything you need.
A Canvas instance comes as onDraw parameter, it basicly respond for drawing a different
shapes, while Paint object defines that color that shape will get.
View Update
From a view lifecycle diagram you may notices that there are two methods that leads view to
redraw itself. invalidate() and requestLayout() methods will help you to make an interactive
custom view.
invalidate() method used to simple redrawing view.
requestLayout() method used to update view when its size changed and there is need to
measure it once again to draw the view.
2. Canvas
The Canvas class holds the "draw" calls. To draw something, you need 4 basic components:
A Bitmap to hold the pixels,
A Canvas to host the draw calls (writing into the bitmap),
A drawing primitive (e.g. Rect, Path, text, Bitmap), and
A paint (to describe the colors and styles for the drawing).
Create a canvas and draw on it
I. Create the SimpleCanvas project and layout
Create the SimpleCanvas project with the Empty Activity template.
In activity_main.xml, replace the TextView with an ImageView that fills the parent.
Add an onClick property to the ImageView and create a stub for the click handler called
drawSomething().
II. Create the SimpleCanvas member variables and constants
Create a Canvas member variable mCanvas. The Canvas object stores information on
what to draw onto its associated bitmap. For example, lines, circles, text, and custom
paths.
Create a Paint member variable mPaint and initialize it with default values. The Paint
objects store how to draw.
Create a Bitmap member variable mBitmap.
Create a member variable for the ImageView, mImageView. A view, in this example an
ImageView, is the container for the bitmap.
III. Fix the onCreate method and customize the mPaint member variable
IV. Implement the drawSomething() click handler method: The drawSomething() method
is where all the interaction with the user and drawing on the canvas are implemented.
3. Animation APIs
Animations can add visual cues that notify users about what's going on in your app.
They are especially useful when the UI changes state, such as when new content
loads or new actions become available. Animations also add a polished look to your
app, which gives it a higher quality look and feel.
Animate bitmaps
When you want to animate a bitmap graphic such as an icon or illustration, you should use
the drawable animation APIs. Usually, these animations are defined statically with a
drawable resource, but you can also define the animation behavior at runtime.
For example, animating a play button transforming into a pause button when tapped is a nice
way to communicate to the user that the two actions are related, and that pressing one makes
the other visible.
Animate UI visibility and motion
To move, reveal, or hide views within the current layout, you can use the property
animation system provided by the android.animation package, available in Android
3.0 (API level 11) and higher.
These APIs update the properties of your View objects over a period of time,
continuously redrawing the view as the properties change.
For example, when you change the position properties, the view moves across the
screen, or when you change the alpha property, the view fades in or out.
Physics-based motion
Whenever possible, your animations should apply real-world physics so they are natural-
looking. For example, they should maintain momentum when their target changes, and make
smooth transitions during any changes.
To provide these behaviors, the Android Support library includes physics-based animation
APIs that rely on the laws of physics to control how your animations occur.
Two common physics-based animations are the following:
Spring Animation
Fling Animation
Animations not based on physics—such as those built with ObjectAnimator APIs—are
fairly static and have a fixed duration. If the target value changes, you need to cancel the
animation at the time of target value change, re-configure the animation with a new value as
the new start value, and add the new target value.
Whereas, animations built by with physics-based animation APIs such as
DynamicAnimation are driven by force. The change in the target value results in a change in
force. The new force applies on the existing velocity, which makes a continuous transition to
the new target. This process results in a more natural-looking animation.
4. Multimedia – Audio/Video playback and record
Playing Audio
In terms of audio playback, most implementations of Android support AAC LC/LTP, HE-
AACv1 (AAC+), HE-AACv2 (enhanced AAC+), AMR-NB, AMR-WB, MP3, MIDI, Ogg
Vorbis, and PCM/WAVE formats.
Audio playback can be performed using either the MediaPlayer or the AudioTrack classes.
AudioTrack is a more advanced option that uses streaming audio buffers and provides greater
control over the audio. The MediaPlayer class, on the other hand, provides an easier
programming interface for implementing audio playback and will meet the needs of most audio
requirements.
The MediaPlayer class has associated with it a range of methods that can be called by an
application to perform certain tasks. A subset of some of the key methods of this class is as
follows:
create() – Called to create a new instance of the class, passing through the Uri of the
audio to be played.
setDataSource() – Sets the source from which the audio is to play.
prepare() – Instructs the player to prepare to begin playback.
start() – Starts the playback.
pause() – Pauses the playback. Playback may be resumed via a call to the resume()
method.
stop() – Stops playback.
setVolume() – Takes two floating-point arguments specifying the playback volume for
the left and right channels.
resume() – Resumes a previously paused playback session.
reset() – Resets the state of the media player instance. Essentially sets the instance back
to the uninitialized state. At a minimum, a reset player will need to have the data source
set again and the prepare() method called.
release() – To be called when the player instance is no longer needed. This method
ensures that any resources held by the player are released.
In a typical implementation, an application will instantiate an instance of the MediaPlayer class,
set the source of the audio to be played and then call prepare() followed by start(). For example:
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource("http://www.ebookfrenzy.com/myaudio.mp3");
mediaPlayer.prepare();
mediaPlayer.start();
Recording Audio and Video using the MediaRecorder Class
As with audio playback, recording can be performed using a number of different techniques. One
option is to use the MediaRecorder class, which, as with the MediaPlayer class, provides a
number of methods that are used to record audio:
setAudioSource()' – Specifies the source of the audio to be recorded (typically this will
be MediaRecorder.AudioSource.MIC for the device microphone).
setVideoSource() – Specifies the source of the video to be recorded (for example
MediaRecorder.VideoSource.CAMERA).
setOutputFormat() – Specifies the format into which the recorded audio or video is to
be stored (for example MediaRecorder.OutputFormat.AAC_ADTS).
setAudioEncoder() – Specifies the audio encoder to be used for the recorded audio (for
example MediaRecorder.AudioEncoder.AAC).
setOutputFile() – Configures the path to the file into which the recorded audio or video
is to be stored.
prepare() – Prepares the MediaRecorder instance to begin recording.
start() - Begins the recording process.
stop() – Stops the recording process. Once a recorder has been stopped, it will need to be
completely reconfigured and prepared before being restarted.
reset() – Resets the recorder. The instance will need to be completely reconfigured and
prepared before being restarted.
release() – Should be called when the recorder instance is no longer needed. This method
ensures all resources held by the instance are released.
A typical implementation using this class will set the source, output and encoding format and
output file. Calls will then be made to the prepare() and start() methods. The stop() method will
then be called when recording is to end followed by the reset() method. When the application no
longer needs the recorder instance a call to the release() method is recommended:
MediaRecorder mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setOutputFile(audioFilePath);
mediaRecorder.prepare();
mediaRecorder.start();
.
.
.
mediaRecorder.stop()
mediaRecorder.reset()
mediaRecorder.release()
In order to record audio, the manifest file for the application must include the
android.permission.RECORD_AUDIO permission:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
5. Location awareness
With the help of Google Play services, we can add location awareness to our app with automated
location tracking, geofencing, and activity recognition.
The Location Object
The Location object represents a geographic location which can consist of latitude, longitude,
time stamp, and other information such as bearing, altitude and velocity. There are following
important methods which you can use with Location object to get location specific information:
Sr.No. Method & Description
float distanceTo(Location dest): Returns the approximate distance in meters between
1
this location and the given location.
2 float getAccuracy(): Get the estimated accuracy of this location, in meters.
3 double getAltitude(): Get the altitude if available, in meters above sea level.
4 float getBearing(): Get the bearing, in degrees.
5 double getLatitude(): Get the latitude, in degrees.
6 double getLongitude(): Get the longitude, in degrees.
7 float getSpeed(): Get the speed if it is available, in meters/second over ground.
8 boolean hasAccuracy(): True if this location has an accuracy.
Get the Current Location
To get the current location, create a location client which is LocationClient object, connect it to
Location Services using connect() method, and then call its getLastLocation() method. This
method returns the most recent location in the form of Location object that contains latitude and
longitude coordinates and other information as explained above. To have location based
functionality in your activity, you will have to implement two interfaces −
GooglePlayServicesClient.ConnectionCallbacks
GooglePlayServicesClient.OnConnectionFailedListener
Get the Updated Location
If you are willing to have location updates, then apart from above mentioned interfaces,
you will need to implement LocationListener interface as well.
Displaying a Location Address
Once you have Location object, you can use Geocoder.getFromLocation() method to
get an address for a given latitude and longitude. This method is synchronous, and may
take a long time to do its work, so you should call the method from the
doInBackground() method of an AsyncTask class.
6. File I/O
https://developer.android.com/training/data-storage/files.html#InternalVsExternalStorage
7. Shared preferences
Shared Preferences allows activities and applications to keep preferences, in the form of key-value
pairs similar to a Map that will persist even when the user closes the application.
Android stores Shared Preferences settings as XML file in shared_prefs folder under
DATA/data/{application package} directory. The DATA folder can be obtained by calling
Environment.getDataDirectory().
SharedPreferences is application specific, i.e. the data is lost on performing one of the
following options:
on uninstalling the application
on clearing the application data (through Settings)
As the name suggests, the primary purpose is to store user-specified configuration details, such
as user specific settings, keeping the user logged into the application.
To get access to the preferences, we have three APIs to choose from:
getPreferences() : used from within your Activity, to access activity-specific preferences
getSharedPreferences() : used from within your Activity (or other application Context),
to access application-level preferences
getDefaultSharedPreferences() : used on the PreferenceManager, to get the shared
preferences that work in concert with Android’s overall preference framework
getSharedPreferences()-The method is defined as follows:
getSharedPreferences (String PREFS_NAME, int mode)
PREFS_NAME is the name of the file and mode is the operating mode.
Following are the operating modes applicable:
MODE_PRIVATE: the default mode, where the created file can only be accessed by the
calling application
MODE_WORLD_READABLE: Creating world-readable files is very dangerous, and
likely to cause security holes in applications
MODE_WORLD_WRITEABLE: Creating world-writable files is very dangerous, and
likely to cause security holes in applications
MODE_MULTI_PROCESS: This method will check for modification of preferences
even if the Shared Preference instance has already been loaded
MODE_APPEND: This will append the new preferences with the already existing
preferences
MODE_ENABLE_WRITE_AHEAD_LOGGING: Database open flag. When it is set,
it would enable write ahead logging by default
Initialization
We need an editor to edit and save the changes in shared preferences. The following code can be
used to get the shared preferences.
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Editor editor = pref.edit();
Storing Data
editor.commit() is used in order to save changes to shared preferences.
editor.putBoolean("key_name", true); // Storing boolean - true/false
editor.putString("key_name", "string value"); // Storing string
editor.putInt("key_name", "int value"); // Storing integer
editor.putFloat("key_name", "float value"); // Storing float
editor.putLong("key_name", "long value"); // Storing long
editor.commit(); // commit changes
Retrieving Data
Data can be retrieved from saved preferences by calling getString() as follows:
pref.getString("key_name", null); // getting String
pref.getInt("key_name", null); // getting Integer
pref.getFloat("key_name", null); // getting Float
pref.getLong("key_name", null); // getting Long
pref.getBoolean("key_name", null); // getting boolean
Clearing or Deleting Data
remove(“key_name”) is used to delete that particular value.
clear() is used to remove all data
editor.remove("name"); // will delete key name
editor.remove("email"); // will delete key email
editor.commit(); // commit changes
editor.clear();
editor.commit(); // commit changes
8. Databases such as SQLite, and Enterprise data access (via Internet/Intranet)
SQLite is a opensource SQL database that stores data to a text file on a device. Android comes in
with built in SQLite database implementation.
SQLite supports all the relational database features. In order to access this database, you don't
need to establish any kind of connections for it like JDBC,ODBC e.t.c
Database - Package
The main package is android.database.sqlite that contains the classes to manage your own
databases
Database - Creation
In order to create a database you just need to call this method openOrCreateDatabase with your
database name and mode as a parameter. It returns an instance of SQLite database which you
have to receive in your own object.Its syntax is given below
SQLiteDatabase mydatabase = openOrCreateDatabase("your database
name",MODE_PRIVATE,null);
Database - Insertion
we can create table or insert data into table using execSQL method defined in SQLiteDatabase
class. Its syntax is given below
mydatabase.execSQL("CREATE TABLE IF NOT EXISTS TutorialsPoint(Username
VARCHAR,Password VARCHAR);");
mydatabase.execSQL("INSERT INTO TutorialsPoint VALUES('admin','admin');");
This will insert some values into our table in our database. Another method that also does the
same job but take some additional parameter is given below
Sr.No Method & Description
execSQL(String sql, Object[] bindArgs) :This method not only insert data , but also
1
used to update or modify already existing data in database using bind arguments
Database - Fetching
We can retrieve anything from database using an object of the Cursor class. We will call a
method of this class called rawQuery and it will return a resultset with the cursor pointing to the
table. We can move the cursor forward and retrieve the data.
Cursor resultSet = mydatbase.rawQuery("Select * from TutorialsPoint",null);
resultSet.moveToFirst();
String username = resultSet.getString(0);
String password = resultSet.getString(1);
Database - Helper class
For managing all the operations related to the database, an helper class has been given and is
called SQLiteOpenHelper. It automatically manages the creation and update of the database. Its
syntax is given below
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(){
super(context,DATABASE_NAME,null,1);
}
public void onCreate(SQLiteDatabase db) {}
public void onUpgrade(SQLiteDatabase database, int oldVersion, int
newVersion) {}
}