0% found this document useful (0 votes)
2 views

Ch5 Activity and Multimedia with Databases

This document provides an overview of Android activities, multimedia databases, and the use of intents in application development. It covers the concepts of activities as single screens, the role of services, and the structure of multimedia databases, along with practical examples of explicit and implicit intents. The document also outlines the lifecycle of activities and how to manage user interactions and data within Android applications.

Uploaded by

khn.salman901
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Ch5 Activity and Multimedia with Databases

This document provides an overview of Android activities, multimedia databases, and the use of intents in application development. It covers the concepts of activities as single screens, the role of services, and the structure of multimedia databases, along with practical examples of explicit and implicit intents. The document also outlines the lifecycle of activities and how to manage user interactions and data within Android applications.

Uploaded by

khn.salman901
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

5…

Activity and Multimedia


with Databases
Chapter Outcomes...
▣ Apply the given Intents and service in application development.
▣ Use fragment to generate the given multiple activities.
▣ Develop programs to play the given multimedia.
▣ Write the query to perform the given database management operation.
▣ Explain significance of the given component in Android architecture.

Learning Objectives…
▣ To understand Concepts in Activity
▣ To learn Database and with Multimedia Database with its Framework
▣ To study Services in Android
▣ To understand SQL Database with its Creation and Connection

5.0 INTRODUCTION
• An activity is the single screen in android. It is like window or frame of Java. With the help of
activity, one can place all our UI components or widgets in a single screen.
• A database is an organized collection of data. A database is a collection of schemas, tables, queries,
reports, views and other objects. A query language is a computer language used to make queries (or
questions about data) in databases and information systems.
• A Database Management System (DBMS) is a computer software application that interacts with the
user, other applications, and the database itself to capture and analyze data. A general-purpose
DBMS is designed to allow the definition, creation, querying, update, and administration of
databases.
• Multimedia database is the collection of interrelated multimedia data that includes text, graphics,
images, animations, video, audio etc. and have vast amounts of multisource multimedia data.
• The framework that manages different types of multimedia data which can be stored, delivered and
utilized in different ways is known as multimedia database management system.
• There are three classes of the multimedia database which includes static media, dynamic media and
dimensional media.
• A combination of multiple forms of media and content is called Multimedia. This can be text,
graphics, audio, video etc. A MultiMedia DataBase (MMDB) is a collection of related multimedia data.
• Multimedia database systems are database systems where, besides text and other discrete data,
audio and video information will also be stored, manipulated and retrieved.
• A service is a component that runs in the background to perform long-running operations without
needing to interact with the user and it works even if application is destroyed.
[1.1]
Mobile Application Development 5.2 Activity and Multimedia with Database

• A service can essentially take two states namely, Started when an application component, such as an
activity, starts it by calling startService() and Bound when an application component binds to it by
calling bindService().
• SQLite is a open-source SQL database that stores data to a text file on a device. Android comes in with
built in SQLite database implementation.
• SQLite is an open-source relational database i.e. used to perform database operations on android
devices such as storing, manipulating or retrieving persistent data from the database.
Introduction to Activity in android:
• The activity represents a single screen or interfaces that allows the user to interact with an
application.
• So, depending on the application on the application types, applications have single to multiply
activities.
• For example, the Facebook application of our Android smart phone could have an activity to log into
the application.
• All the activities of an application must work together to provide a comprehensive and cohesive user
experience. However, each of these activities could be independent of one another, thereby enabling
a different application to use those activities.
• For example: the camera application of our smart phone can use the post a photograph activity of
the Facebook application to post a photograph in our Facebook account.

Fig. 5.1
• A visual user interface for one directed attempt that the user can take is offered by an activity. For
instance, an activity may offer a list of menu items that the user could select from or exhibit
photographs besides with their captions.
• A text messaging application may have one activity that shows a list of contacts to send messages to,
a second activity which is used for writing the messages to the selected contact, and other activities
to review old messages. Each activity is independent of the others even though they work together.
• Each one is implemented as a subclass of the Activity base class.
• Typically, one of the activities is marked as the first one that should be presented to the user when
the application is launched. Moving from one activity to another is proficient by having the current
activity which start the next one.
• Each activity is given a default window to draw in. Usually the window fills the screen, but it may be
smaller than the screen and float on top of other windows. An activity can also compose the use of
additional windows.
Mobile Application Development 5.3 Activity and Multimedia with Database

• For example, a pop-up dialog that calls for a user comeback in the middle of the activity, or a
window to present users with vital information when they select a particular item on-screen.
• The visual content of the window is provided by a hierarchy of views-objects derived from the base
View class. Each view controls a rectangular space inside the window. Parent views hold and
organize the layout of their children. Leaf views draw in the rectangles they control and respond to
user actions directed at that space. The activity’s interaction with the user takes place where there
are views.
• Android offers many build in views that you use; buttons, textfields, scrollbars, menu bar, cjeck box
etc.
• A view hierarchy is placed with in an activity’s window by the Activity.setContentview() method.
o An activity is a single , focused thing that the user can easily do. All activities interact with the
user so the Activity class creates a window in which we can place the UI with
setContentView(View).
o While activities are often presented to the user as full-screen windows, it can also be used in
other ways: as floating windows or embedded inside another activity.
o There are two methods to implement activity:-
onCreate(Bundle) is a method in which we initialize our activity. Here we usually call
setCotentView(int)with a layout resource defining the UI, and using findViewById(int) to
retrieve the widgets in that UI which we need to interact with programmatically.
onPause() is another method in which we deal with the user leaving the activity. Any changes
made by the user should at this point be committed.
• The points are Activity Lifecycle, Starting activities and getting results, Saving persistent state,
Permission, Process Lifecycle.

5.1 INTENT
• Have we ever wondered how a new Activity opens when we click on some button, suppose the
settings button to show the Settings screen in any app? How does the app opens up when we click on
its notification? How do we get Low battery alert in our mobile? All these things are possible because
of Intent in Android.
• An Intent is a messaging object that you can use to request an action from an app component. An
Intent is basically an intention to do an action. It is a way to communicate between Android
components to request an action from a component, by different components.
• It's like a message that Android listens for and then react accordingly by identifying and invoking
the app's appropriate component (like an Activity, Service, Content Provider, etc.). It can be within
that same app or some other app as well.
• If multiple apps are capable of responding to the message then Android provides the user with a list
of those apps from which a choice can be made.
Uses of Intent in Android:
• There are three fundamental uses of intents:
1. To Start an Activity:
• An Activity represents a single screen in an app. We can start a new instance of an Activity by
passing an Intent to startActivity(). The Intent describes the activity to start and carries any
necessary data along.
2. To Start a Service:
• A Service is a component that performs operations in the background and does not have a user
interface. We can start a service to perform a one-time operation (such as downloading a file) by
passing an Intent to startService(). The Intent describes which service to start and carries any
necessary data.
Mobile Application Development 5.4 Activity and Multimedia with Database

3. To Deliver a Broadcast:
• A broadcast is a message that any app can receive. The system delivers various broadcasts for system
events, such as when the system boots up or the device starts charging.
• We can deliver a broadcast to other apps by passing an Intent to sendBroadcast() or
sendOrderedBroadcast().
• In Android, there are two types of Intents namely, Explicit Intents, Implicit Intents
5.1.1 Explicit Intents
• When we explicitly define which Android component should be opened on some user action, then
you use explicit intents. We generally use an explicit intent to start a new component in our own
app, because we know which exact activity or service you want to start.
• For example, you can start a new activity in response to a user action or start a service to download a
file in the background.
Create an Explicit Intent: To create an explicit intent,
1. We need to make an Intent object. The constructor of the Explicit Intent's object needs two
parameters as follows:
Context c: This represents the object of the Activity from where you are calling the intent.
Java file name: This represents the name of the java file of the Activity you want to open.
Note: We need to mention the java file name with .class extension
Intent i = new Intent(this.MyJavaFile.class);
2. Call startActivity() method and pass the intent's object as the parameter. This method navigates to
the java file mentioned in the Intent's object.
startActivity(i);
• If we need to pass some information or data to the new Activity we are calling, you can do this by
calling putExtra() method before the startActivity() method. This method accepts key-value pair as
its parameter.
i.putExtra(“key1”,”I am value1”);
i.putExtra(“key2”,”I am value2”);
startActivity(i);
Note: To receive the data in the new Activity and use it accordingly, you need to call
the getIntent() method and then getStringExtra() method in the java class of the Activity you want to
open through explicit intent. getStringExtra() method takes the key as the parameter.
String a=getIntent().getStringExtar(“key1”);
• Doing this, stores the value stored at key1 into the string variable a.
5.1.2 Implicit Intents
• When we just have to tell what action we want to perform without worrying which component will
perform it, then we can use implicit intent.
• Implicit intents do not name a specific component to perform a particular action, but instead it
declares a general action to be performed, which allows any component, even from another app to
handle it.
• For example, if we want to show a specific location of the user on a map, we can use an implicit
intent to pass the coordinates through the intent and then any other app, which is capable of
showing the coordinates on a map will accept that intent.
Create an Implicit Intent: To create an implicit intent,
1. We need to make an Intent object. The constructor of the Implicit Intent's object needs a type of
action we want to perform.
Mobile Application Development 5.5 Activity and Multimedia with Database

An action is a string that specifies the generic action to be performed. The action largely determines
how the rest of the intent is structured, particularly the information that is contained as data and
extras in the intent object. For example,
ACTION_VIEW: This action is used when you have some information that an activity can show to the
user, such as a photo to view in a Gallery app, or an address to view in a Map app.
ACTION_SEND: This action is used when you have some data that the user can share through
another app, such as an Email app or some Social Networking app.
Note: You can specify our own actions for getting used by intents within our own app (or for getting
used by other apps to invoke components in our app), but you usually specify action constants
defined by the Intent class or other framework classes.
Intent i = new Intent(Intent.ACTION VIEW);
2. We need to provide some data for the action to be performed. Data is typically expressed as a URI
(Uniform Resource Identifier) which provides data to the other app so that any other app which is
capable of handling the URI data can perform the desired action. For example, if we want to open a
website through our app, we can pass the URI data using setData() method as follows:
i.setData(Uri.parse(http://www.google.co.in));
3. Call startActivity() method in the end with the intent object as the parameter.
startActivity(i);
Android Implicit Intent Example:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/a
pk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="60dp"
android:ems="10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.575"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginLeft="156dp"
android:layout_marginTop="172dp"
android:text="Visit"
app:layout_constraintEnd_toEndOf="parent"
Mobile Application Development 5.6 Activity and Multimedia with Database

app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />
</android.support.constraint.ConstraintLayout>
MainActivity.java
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
Button button;
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
editText = findViewById(R.id.editText);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url=editText.getText().toString();
Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
});
}
}
Android Explicit Intent Example:
• Android Explicit intent specifies the component to be invoked from activity. In other words, we can
call another activity in android by explicit intent.
• We can also pass the information from one activity to another using explicit intent.
• Here, we are going to see an example to call one activity from another and vice-versa. Android
calling one activity from another activity example
• Let's see the simple example of android explicit example that calls one activity from another and vice
versa.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/a
pk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstActivity">
Mobile Application Development 5.7 Activity and Multimedia with Database

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="First Activity"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.454"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.06" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="392dp"
android:onClick="callSecondActivity"
android:text="Call second activity"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
ActivityOne class
File: MainActivityOne.java
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
}
public void callSecondActivity(View view){
Intent i = new Intent(getApplicationContext(), SecondActivity.class);
i.putExtra("Value1", "Android By Javatpoint");
i.putExtra("Value2", "Simple Tutorial");
// Set the request code to any code you like, you can identify the
// callback via this code
startActivity(i);
Mobile Application Development 5.8 Activity and Multimedia with Database

}
}

activitytwo_main.xml
activitytwo_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/a
pk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Second Activity"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.454"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.06" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="392dp"
android:onClick="callFirstActivity"
android:text="Call first activity"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
ActivityTwo class
MainActivityTwo.java
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
Mobile Application Development 5.9 Activity and Multimedia with Database

import android.view.View;
import android.widget.Toast;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bundle extras = getIntent().getExtras();
String value1 = extras.getString("Value1");
String value2 = extras.getString("Value2");
Toast.makeText(getApplicationContext(),"Values are:\n First value: "+value1+
"\n Second Value: "+value2, Toast.LENGTH_LONG).show();
}
public void callFirstActivity(View view){
Intent i = new Intent(getApplicationContext(), FirstActivity.class);
startActivity(i);
}
}
5.1.3 Intent_Filter
• Intent_filters is a very powerful way to connect different applications together hence allowing
better user experience. They take care of intent resolution to match activities, services and broadcast
receiver. Intent filter are declared in the AndroidManifest.xml. an intent filters is an instance of the
IntentFilter class.
• An intent filter declares the capability of its parent component.
Syntax:
<intent-filter android:icon=”drawable resource”
android:label=”string resource”
android:priority=”integer”>
. . .
</intent-filter>
Attributes:
1. ANDROID:ICON: An icon represents the parent activity, service, or broadcast receiver when that
component is existing to the user as having the potential described by the filter. This attribute must
set as a reference to z drawable resource containing the image definition. The defaulting value is the
icon set by the parent components icon attribute. If the parent do not specify an icon, the default is
the icon set by the <application> element.
2. android:label: A user readable label for the parent component. This label, rather than the single set
by the parent component, is used when the component is offered to the user as having the capability
described by the filter.
• The label should be set as the reference to the string resource, so that it can be localized like other
strings in the user interface.
• The default value is the label set by the parent component. If the parent do not specify a label, the
default is the label set by the <application> element’s label attribute.

5.2 ACTIVITY LIFE CYCLE


• Activities in the system are managed as an activity stack. When a new activity is happening, it is
placed on the top of the stack and becomes the running activity.
• The activity always remains below it in the stack, and will not come to the foreground again until the
new activity exits.
Mobile Application Development 5.10 Activity and Multimedia with Database

Fig. 5.2: Activity Life Cycle


• Activities have a predefined life-cycle and which certain methods are called. Following Table
important activity lifecycle methods:
Sr. No. Method Purpose
onCreate()
1. Called then the activity is created. Used to initialize the activity, for
example create the user interface.
onResume()
2. Called if the activity get visible again and the user starts interacting
with the activity again. Used to initialize fields, register listeners, bind
to services, etc.
onPause()
3. Called once another activity gets into the foreground. Always called
before the activity is not visible anymore. Used to release resources or
save application data. For example you unregister listeners, intent
receivers, unbind from services or remove system service listeners.
onStop()
4. Called once the activity is no longer visible. Time or CPU intensive shut-
down operations, such as writing information to a database should be
Mobile Application Development 5.11 Activity and Multimedia with Database

down in the onStop() method. This method is guaranteed to be called as


of API 11.
• The flow of these methods is depicted in the diagram.
1. Activity States:
• The Android OS uses a priority queue to assist in managing activities running on the device. Based
on the state a particular Android activity is in, it will be assigned a certain priority within the OS.
• This priority system helps Android identify activities that are no longer in use, allowing the OS to
reclaim memory and resources.
• Fig. 5.2 illustrates the states an activity can go through, during its lifetime:
• These states are often broken into three main teams as follows:
1. Active or Running:
• Activities are thought of active or running if they're within the foreground, additionally referred to
as the top of the activity stack. this can be thought of the highets priority activity within
the Android Activity stack, and as such only be killed by the OS in extreme things, like if the activity
tries to use more memory than is available on the device as this might cause the UI to become
unresponsive.
2. Paused:
• When the device goes to sleep, or an activity continues to be visible but partially hidden by a new,
non-full-sized or clear activity, the activity is taken into account paused.
• Paused activities are still alive, that is, they maintain all state and member information, and stay
attached to the window manager.
• This can be thought of to be the second highest priority activity within the android Activity stack
and, as such, can solely be killed by the OS if killing this activity can satisfy the resource requirement
needed to keep the Active/Running Activity stable and responsive.
3. Stopped:
• Activities that are utterly obscured by another activity are thought of stopped or within the
background.
• Stopped activities still try and retain their state and member info for as long as possible but stopped
activities are thought of to be loweat priority of the three states and, as such, the OS can kill
activities during this state initial to satisfy the resource needs of higher priority activities.
5.2.1 Broadcast Life Cycle
• Fig. 5.3 shows braodcast life cycle of activity.

Register the intent


to observe.

Android Braodcast
System Receiver

Gets notification
when intends occur
Mobile Application Development 5.12 Activity and Multimedia with Database

Fig. 5.3
• A broadcast receiver is a component that does nothing but receives and reacts to broadcast
announcements. Many broadcasts originate in system code but any other applications can also
initiate broadcasts.
• Broadcast receivers do not display a user interface. However they may perhaps start an activity in
response to the information they receive, or as service do they may possibly use the notification
manager to alert the user.

5.3 CONTENT PROVIDER


• A Content Provider component supplies data from one application to others on request. Such
requests are handled by the methods of the ContentResolver class.
• A content provider can use different ways to store its data and the data can be stored in files, in a
database or even over a network.
• Content Providers support the four basic operations, normally called CRUD-operations. CRUD is the
acronym for Create, Read, Update and Delete.
• With content providers those objects simply represent data as most often a record of a database, but
they could also be a photo on our SD-card or a video on the web.
Content URIs
• The most important concept to understand when dealing with content providers is the content URI.
• Whenever we want to access data from a content provider we have to specify a URI. URIs for content
providers look like this:
content://authority/optionalPath/optionalId
• Here, detailed explanation about Content URIs:
• The scheme for content providers is always “content”. The colon and double-slash “://” are a fixed
part
• This specifies the name of the content provider, for example browser , contacts etc. Authorities have
to be unique for every content provider. Android documentation recommends to use the fully
qualified class name of our ContentProvider-subclass.
• The optional path, is used to distinguish the kinds of data our content provider offers. For example,
distinguishes between audio files, video files and images using different paths for each of these
types of media. This way a content provider can support different types of data that are nevertheless
related. For totally unrelated data though you should use different content providers, and thus
different authorities.
• The last element is the optional id, which - if present - must be numeric. The id is used whenever you
want to access a single record (For example, a specific video file).
• There are two types of URIs namely, directory-based URIs, id-based URIs.
• If no id is specified a URI is automatically a directory-based URI.
• If we use directory-based URIs to access multiple elements of the same type (for example, all songs of
a band). All CRUD operations are possible with directory-based URIs.
• We use id-based URIs if we want to access a specific element. We cannot create objects using an id-
based URI: but reading, updating and deleting is possible.
Content Types
• A content type consist of a two types such as media type and a subtype divided by a slash. A typical
example is “image/png”. The media type “image” describes the content as an image file which is
further specified to be of the Portable Network Graphic variety by the subtype “png”.
And guess what?
• vnd.android.cursor.item: Used for single records
• vnd.android.cursor.dir: Used for multiple records
Mobile Application Development 5.13 Activity and Multimedia with Database

• The subtype on the other hand is used for content provider specific details and should
differ for all types our content provider supports. The naming convention for subtypes is
vnd.companyname.contenttype. Most content providers support multiple subtypes.
Which standard Content Providers are available?
• A number of content providers are part of Android’s API. All these standard providers are defined in
the package android.provider. The below lists the standard providers and what they are used for
1. CalendarContract SDK 14: Manages the calendars on the user’s device.
2. Browser SDK 1: Manages our web-searches, bookmarks and browsing-history.
3. CallLog SDK 1: Keeps track of our call history.
4. MediaStore SDK 1: The content provider responsible for all our media files like music, video and
pictures.
5. Settings SDK 1: Manages all global settings of our device.
6. UserDictionary SDK 3: Keeps track of words we add to the default dictionary.
Create Content Provider
• This involves number of simple steps to create our own content provider.
• First of all you need to create a Content Provider class that extends the ContentProviderbaseclass.
• Second, you need to define our content provider URI address which will be used to access the
content.
• Next you will need to create our own database to keep the content. Usually, Android uses SQLite
database and framework needs to override onCreate() method which will use SQLite Open Helper
method to create or open the provider's database. When our application is launched, the onCreate()
handler of each of its Content Providers is called on the main application thread.
• Next we will have to implement Content Provider queries to perform different database specific
operations.
• Finally register our Content Provider in our activity file using <provider> tag.
• list of methods which we need to override in Content Provider class to have our Content Provider
working:
1. onCreate(): This method is called when the provider is started.
2. query(): This method receives a request from a client. The result is returned as a Cursor object.
3. insert(): This method inserts a new record into the content provider.
4. delete(): This method deletes an existing record from the content provider.
5. update(): This method updates an existing record from the content provider.
6. getType(): This method returns the MIME type of the data at the given URI.

5.4 FRAGMENTS
• A fragment is a self-contained, modular section of an application’s User Interface (UI) and
corresponding behavior that can be embedded within an activity.
• Fragments can be assembled to create an activity during the application design phase, and added to
or removed from an activity during application runtime to create a dynamically changing user
interface.
• Fragments may only be used as part of an activity and cannot be instantiated as standalone
application elements. That being said, however, a fragment can be thought of as a functional “sub-
activity” with its own lifecycle similar to that of a full activity.
• Fragments are stored in the form of XML layout files and may be added to an activity either by
placing appropriate <fragment> elements in the activity’s layout file, or directly through code
within the activity’s class implementation.
Creating a Fragment:
Mobile Application Development 5.14 Activity and Multimedia with Database

• The two components that make up a fragment are an XML layout file and a corresponding Java class.
The XML layout file for a fragment takes the same format as a layout for any other activity layout
and can contain any combination and complexity of layout managers and views.
• The following XML layout, for example, is for a fragment consisting simply of a RelativeLayout with
a red background containing a single TextView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/red" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/fragone_label_text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>

• The corresponding class to go with the layout must be a subclass of the Android Fragment class. This
class should, at a minimum, override the onCreateView() method which is responsible for loading
the fragment layout. For example:
package com.example.myfragmentdemo;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.Fragment;

public class FragmentOne extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_one_layout,
container, false);
}
}
Adding a Fragment to an Activity using the Layout XML File:
• Fragments may be incorporated into an activity either by writing Java code or by embedding the
fragment into the activity’s XML layout file.
Mobile Application Development 5.15 Activity and Multimedia with Database

• Regardless of the approach used, a key point to be aware of is that when the support library is being
used for compatibility with older Android releases, any activities using fragments must be
implemented as a subclass of FragmentActivity instead of the AppCompatActivity class:
package com.example.myfragmentdemo;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;

public class FragmentDemoActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_demo);
}
}
• Fragments are embedded into activity layout files using the <fragment> element. The following
example layout embeds the fragment created in the previous section of this chapter into an activity
layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentDemoActivity" >

<fragment
android:id="@+id/fragment_one"
android:name="com.example.myfragmentdemo.myfragmentdemo.FragmentOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
tools:layout="@layout/fragment_one_layout" />

</RelativeLayout>
• The key properties within the <fragment> element are android:name, which must reference the
class associated with the fragment, and tools:layout, which must reference the XML resource file
containing the layout of the fragment.
• Once added to the layout of an activity, fragments may be viewed and manipulated within the
Android Studio Layout Editor tool.
• Fig. 5.4, for example, shows the above layout with the embedded fragment within the Android Studio
Layout Editor:
Mobile Application Development 5.16 Activity and Multimedia with Database

Fig. 5.4

Adding and Managing Fragments in Code:


• The ease of adding a fragment to an activity via the activity’s XML layout file comes at the cost of the
activity not being able to remove the fragment at runtime.
• In order to achieve full dynamic control of fragments during runtime, those activities must be added
via code. This has the advantage that the fragments can be added, removed and even made to replace
one another dynamically while the application is running.
• When using code to manage fragments, the fragment itself will still consist of an XML layout file and
a corresponding class. The difference comes when working with the fragment within the hosting
activity. There is a standard sequence of steps when adding a fragment to an activity using code:
1. Create an instance of the fragment’s class.
2. Pass any additional intent arguments through to the class instance.
3. Obtain a reference to the fragment manager instance.
4. Call the beginTransaction() method on the fragment manager instance. This returns a fragment
transaction instance.
5. Call the add() method of the fragment transaction instance, passing through as arguments the
resource ID of the view that is to contain the fragment and the fragment class instance.
6. Call the commit() method of the fragment transaction.
• The following code, for example, adds a fragment defined by the FragmentOne class so that it
appears in the container view with an ID of LinearLayout1:
FragmentOne firstFragment = new FragmentOne();
firstFragment.setArguments(getIntent().getExtras());

FragmentManager fragManager = getSupportFragmentManager();


FragmentTransaction transaction = fragManager.beginTransaction();

transaction.add(R.id.LinearLayout1, firstFragment);
transaction.commit();
The above code breaks down each step into a separate statement for the purposes of
clarity. The last four lines can, however, be abbreviated into a single line of code as
follows:
Mobile Application Development 5.17 Activity and Multimedia with Database

getSupportFragmentManager().beginTransaction()
.add(R.id.LinearLayout1, firstFragment).commit();
• Once added to a container, a fragment may subsequently be removed via a call to the remove()
method of the fragment transaction instance, passing through a reference to the fragment instance
that is to be removed:
transaction.remove(firstFragment);
• Similarly, one fragment may be replaced with another by a call to the replace() method of the
fragment transaction instance. This takes as arguments the ID of the view containing the fragment
and an instance of the new fragment.
• The replaced fragment may also be placed on what is referred to as the back stack so that it can be
quickly restored in the event that the user navigates back to it. This is achieved by making a call to
the addToBackStack() method of the fragment transaction object before making the commit()
method call:
FragmentTwo secondFragment = new FragmentTwo();
transaction.replace(R.id.LinearLayout1, secondFragment);
transaction.addToBackStack(null);
transaction.commit();
5.5 SERVICE
• A service is an application component which runs without direst interaction with the user in the
background.
• Services are used for repetitive and potentially long running operations, i.e., Internet downloads,
checking for new data, data processing, updating content providers and the like.
• Services run with a higher priority than inactive or invisible activities and therefore it is less likely
that the Android system terminates them. Services can also be configured to be restarted if they get
terminated by the Android system once sufficient system resources are available again.
• Services are started with two methods namely, Context.startService(), Context.bindService().
• Services are the faceless components of Android as they have their individual interfaces. They
typically run in the background to perform long-running operations or work for remote processes.
• Services are communicate with other Android components and use the Android’s notification
framework to notify the users.
• Services are job-specific and they are unaffected by the switching activity. They will continue to run
in the background even if you switch to the interface of a different application.
5.5.1 Features of Service
• A feature for the application where the user is not directly interacting with the application
corresponds to calls to startService() method, which ask the system to agenda work for the service ,
to be run until the service or someone stops it forcefully.
• A feature for an application to expose some of its functionality to other applications. This
correspond to calls to bindService() which allows a established connection to be made to the service
in order to interact with it.
5.5.2 Android Platform Service
• The Android platform provides pre-defined services, generally showing by a particular Manager
class. The getSystemService() method is used to access them.
5.5.3 Defining New Services
Mobile Application Development 5.18 Activity and Multimedia with Database

• All android application can define and start new services. If we use asynchronous processing in
activites, the corresponding threads are still connected to the life cycle of the corresponding activity.
The android system may choose to terminate them at the time.
• Services run with higher priority than inactive or invisible activities or invisible activities and the
Android system terminate them. Defining our own services allows us to design very approachable
applications.
• We can obtain the application via a service and once the application is started by the user, it can
current fresh data to the user.
• Declaring services: A service wants to be declared in the AndroidManifest.xml and the implementing
class should extend the Service class or one of its subclasses.
1. Service perform long running operation in the background.
2. It does not contain the user interface.
3. It is useful for things like playing music, network, network operations etc.
4. Services are run independently of the component that created it.
5. It can be bound to by other application components if allowed.
5.5.4 Service Life Cycle
• As explained above service can either be started or bound. We just need to call either startService()
or bindService() from any of our android components. Based on how our service was started it will
either be “started” or “bound”
1. Started
• A service is started when an application component, such as an activity, starts it by calling
startService().
• Now the service can run in the background indefinitely, even if the component that started it is
destroyed.
2. Bound
• A service is bound when an application component binds to it by calling bindService().
• A bound service offers a client-server interface that allows components to interact with the service,
send requests, get results, and even do so across processes with InterProcess Communication (IPC).
Mobile Application Development 5.19 Activity and Multimedia with Database

Fig. 5.5: Lifecycle of Service


• Like any other components service also has callback methods. These will be invoked while the service
is running to inform the application of its state. Implementing these in our custom service would
help you in performing the right operation in the right state.
• There is always only a single instance of service running in the app. If you are calling startService()
for a single service multiple times in our application it just invokes the onStartCommand() on that
service. Neither is the service restarted multiple times nor are its multiple instances created
1. onCreate():
• This is the first callback which will be invoked when any component starts the service. If the same
service is called again while it is still running this method wont be invoked. Ideally one time setup
and intializing should be done in this callback.
2. onStartCommand()
• This callback is invoked when service is started by any component by calling startService(). It
basically indicates that the service has started and can now run indefinetly.
• Now its our responsibilty to stop the service. This callback also has a int return type. This return type
describes what happens to the service once it is destroyed by the system.
• There are three possible return types:
(i) START_STICKY: Returning this indicates that once the service is killed by the system it will be
recreated and onStartCommand method will be invoked again.But the previous intent is not
redelivered. Instead onStartCommand is called with a null intent
(ii) START_NOT_STICKY: Returning this indicates that the service wont be recreated if it is killed by
the system
Mobile Application Development 5.20 Activity and Multimedia with Database

(iii) START_REDELIVER_INTENT: Returning this indicates that once the service is killed by the
system it will be recreated and onStartCommand method will be invoked again.But here the
original intent is redelivered again.
3. onBind()
• This is invoked when any component starts the service by calling onBind. Basically the component
has now binded with the service. This method needs to return our implementation of IBinder which
will be used for Interprocess Communication. If you dont want our service to bind with any
component you should just return null nevertheless this method needs to be implemented
4. onUnbind()
• This is invoked when all the clients are disconnected from the service.
5. onRebind()
• This is invoked when new clients are connected to the service. It is called after onUnbind
6. onDestroy()
• This is a final clean up call from the system. This is invoked just before the service is being destroyed.
• Could be very useful to cleanup any resources such as threads, registered listeners, or receivers. But
very rarely it happens that the service is destroyed with onDestroy not being invoked
5.5.5 Permission
• Global access to a service can be required when it is declared when it is declared in its manifest’s
<service> tag. By doing so, other applications will require to declare a corresponding <uses-
permission> element in their own manifest to be capable to start, stop or bind to the service.
• In addition a service can guard individual IPC calls into it with permissions, by calling the
checkCallingPermission (string) before executing the implementation of that call.
• Services which run in the procedure of the application are occasionally called local services.
5.5.6 Example of Service
• In this example we will create a service with runs in background and prints logs until we stop it.
Step 1: Create a Custom Service: As we have already discussed Service doesn’t have a its own layout
hence no xml file is required.
• Right click on our package and select New → Java Class. Name our class as MyService. This should
extend the Android’s Service class.
• We will be using a Handler and Runnable implemenation to print the logs every 5 seconds as long as
the service is running
• Then implement all the callbacks as shown in the code snippet below
public class MyService extends Service {
//Declaring the handler
private Handler handler;
//Declaring our implementation of Runnable
private Runner runner;
/*
Regardless of whether you want our service to be binded
or not you should always implement onBind. You should return null if you
dont want it to bind
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/*
Mobile Application Development 5.21 Activity and Multimedia with Database

Initialization of Handler and Runner


*/
public void onCreate() {
super.onCreate();

Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();


handler = newHandler();
runner = newRunner();

}
// Starting the Runnable with handler
public int onStartCommand(Intent intent, int id, int startID) {
handler.post(runner);
return START_STICKY;
}
//Removing the callbacks from handler once the service is destroyed
@Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(runner);
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}

/*
A runnable class designed in such a way that it is runs every 5 seconds
*/
public class Runner implements Runnable {

@Override
public void run() {

Log.d("AndroidClarified", "Running");
handler.postDelayed(this, 1000 * 5);
}
}

}
Step 2: Declaring the service in Manifest: As for every android component we first need to declare our
service inside the AndroidManifest.xml. For this we just need to add the below code snippet under
the <application> tag
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidclarified.serviceapp">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
Mobile Application Development 5.22 Activity and Multimedia with Database

<activityandroid:name=".MainActivity">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<serviceandroid:name=".MyService"/>
</application>
</manifest>
Step 3: Starting the service: Since every service needs to be started from some other Android
component. We will first create a Android Activity. We can just right click on our package and
select New->Activity->Empty Activity. This will automatically create an Activity class and a
layout file. We add two buttons to the layout file as shown in the snippet below:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.androidclarified.serviceapp.MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/start_button"
android:layout_margin="20dp"
android:text="Start Service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:layout_width="wrap_content"
android:text="Stop Service"
android:layout_margin="20dp"
android:id="@+id/stop_button"
android:layout_height="wrap_content"/>
</LinearLayout>
</RelativeLayout>
• Now we have to initialize both the buttons and add click listeners. This is how our activity class will
look now
• Starting the service is similar to starting any other activity. You just need to create an Intent object
specifying the service and then call startService() .
publicclass MainActivity extends AppCompatActivity implements View.OnClickListener{

private Button startButton, stopButton;

@Override
protectedvoidonCreate(Bundle savedInstanceState){
Mobile Application Development 5.23 Activity and Multimedia with Database

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

startButton = (Button)findViewById(R.id.start_button);
stopButton = (Button)findViewById(R.id.stop_button);

startButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
}

@Override
publicvoidonClick(View v){

Intent intent = newIntent(this, MyService.class);

switch(v.getId()){
case R.id.start_button:
startService(intent);
break;
case R.id.stop_button:
stopService(intent);
break;

}
}
Output:

5.6 ANDROID SYSTEM ARCHITECTURE


• The Android operating system follows a layered architecture approach. All these layers are
responsible for different roles and features that we have discussed below.
Mobile Application Development 5.24 Activity and Multimedia with Database

1. Linux Kernel:
• This layer is the foundation of the Android Platform.
• It contains all low level drivers for various hardware components support.
• Android Runtime relies on Linux Kernel for core system services like,
o Memory, process management, threading etc.
o Network stack
o Driver model
o Security and more.
2. Hardware Abstraction Layer (HAL)
• Provides Abstraction between hardware and rest of the software stack.
• HAL can make Android port on different platforms more simply.
3. Android Runtime (ART):
• Designed to run apps in a constrained environment that has limited muscle power in terms of
battery, processing and memory.
• Since Android 5.0, each app runs in its own process within its own instance of ART virtual machine,
which makes process management more crucial.
• ART uses DEX files, which is a type of bytecode, specially designed for Android, which helps ART to
manage memory more efficiently. It contains set of core libraries that enables developers to write
Android Apps using Java Programming. Prior to Android 5.0, Dalvik was used as Android runtime.
• ART is capable of both Ahead-Of-Time (AOT) and Just-In-Time (JIT) compilation.
• It also has a very efficient garbage collection.
4. Libraries
• It exposed to developers through Android Application Framework. It contains C/C++ libraries used
by components of Android Systems.
• Few features include,
(i) SQLite Library used for data storage and light in terms of mobile memory footprints and task
execution.
(ii) WebKit Library mainly provides Web Browsing engine and a lot more related features.
(iii) The surface manager library is responsible for rendering windows and drawing surfaces of
various apps on the screen.
(iv) The media framework library provides media codecs for audio and video.
(v) The OpenGl (Open Graphics Library) and SGL (Scalable Graphics Library) are the graphics
libraries for 3D and 2D rendering, respectively.
(vi) The FreeType Library is used for rendering fonts.
5. Application Framework:
• It is a collection of APIs written in Java, which gives developers access to the complete feature set of
Android OS.
• Developers have full access to the same framework APIs used by the core applications, so that they
can enhance more in terms of functionalities of their application.
• Enables and simplify the reuse of core components and services, like:
(i) Activity Manager: Manages the Lifecycle of apps & provide common navigation back stack.
(ii) Window Manager: Manages windows and drawing surfaces, and is an abstraction of the
surface manager library.
(iii) Content Providers: Enables application to access data from other applications or to share their
own data i.e it provides mechanism to exchange data among apps.
(iv) View System: Contains User Interface building blocks used to build an application's UI,
including lists, grids, texts, boxes, buttons,etc. and also performs the event management of UI
elements(explained in later tutorials).
Mobile Application Development 5.25 Activity and Multimedia with Database

(v) Package Manager: Manages various kinds of information related to the application packages
that are currently installed on the device.
(vi) Telephony Manager: Enables app to use phone capabilities of the device.
(vii) Resource Manager: Provides access to non-code resources (localized Strings, bitmaps, Graphics
and Layouts).
(viii) Location Manager: Deals with location awareness capabilities.
(ix) Notification Manager: Enable apps to display custom alerts in the status bar.
6. Applications:
• Top of the Android Application Stack, is occupied by the System apps and tonnes of other Apps that
users can download from Android's Official Play Store, also known as Google Play Store.
• A set of Core applications are pre-packed in the handset like Email Client, SMS Program, Calendar,
Maps, Browser, Contacts and few more.
• This layer uses all the layers below it for proper functioning of these mobile apps.
• So as we can see and understand, Android holds layered or we can say grouped functionalities as
software stack that makes Android work very fluently in any device.

5.7 MULTIMEDIA FRAMEWORK


• The android multimedia system includes multimedia applications, multimedia frameworks,
OpenCore engine and hardware abstract for audio/video input/output devices. And the goal of the
android multimedia framework is to provide a reliable interface for java services. The multimedia
framework consists of several core dynamic libraries such as libmediajni, libmedia,
libmediaplayservice and so on. A general multimedia framework architecture is shown in the below
figure.
• From the figure, Java classes call the Native C library Libmedia through Java JNI(Java Native
Interface). Libmedia library communications with Media Server guard process through Android’s
Binder IPc (inter process communication) mechanism.
• Media Server process creates the corresponding multimedia service according to the Java
multimedia applications.
• The whole communication between Libmedia and Media Server forms a Client/Server model.

Java Class of Media

Media JNI

Native C Library

Media Server
Media Player Media
Recorder

I Media I Media PV PV
Player Recorder Player Author

Fig. 5.6: Android Multimedia Framework Architecture


Mobile Application Development 5.26 Activity and Multimedia with Database

• The hierarchy inheritance of multimedia is shown in Fig. 5.7.

Android.widget.VideoView

Android.media.MediaPlayer Android.View.Surface

Libmedia_jni

Libmedia

MediaPlayer Service Surface Flinger Audio Flinger

Vorbis Midi PV Player


Overlay Audio HAL
Player Player

Packet Video Framework (OpenCore)

Main Video Plane Audio Driver


framebuffe
r

Fig. 5.7: Android hierarchy inheritance of multimedia


• From the above Fig. 5.7, we can see that the typical video/audio data stream works in Android as
follows. Particularly, Java applications first set the URI of the media (from file or network) to
PVPlayer through Java framework, JNI and Native C. In this process, there are no data stream flows.
• Then PVPlayer processes the media data stream with the steps: demux the media data to separate
video/audio data stream, decode video/audio data, sync video.audio time, send the decoded data out.
• The below is the description of media codec/format, container and network protocol supported by
the Android platform.
1. Container: The audio file format is a file for storing digital audio data on a system. This data can
be manipulated to reduce the size or change the quality of the audio. It is a kind of container to
store audio information.
2. Audio Format: Any format or codec can be used including the ones provided by Android or those
which are specific devices. However it is recommended to use the specified file formats as per
devices.
3. Network Protocol: The following protocols are supported in audio and video playback:
• RTSP (RTP,SDP)
Mobile Application Development 5.27 Activity and Multimedia with Database

• HTTP/HTTPS progressive streaming


• HTTP/HTTPS live streaming draft protocol
o MPEG-2 TS media files only.
o Protocol version 3 (Android 4.0 and above)
o Protocol version 2(Android 3.x)
o Not supported before Android 3.0
5.8 PLAY AUDIO AND VIDEO
• The Android multimedia framework includes support for playing variety of common media types, so
that we can easily integrate audio, video and images into our applications.
5.8.1 Play Audio
• The following classes are used to play sound and video in the Android framework:
1. MediaPlayer: This class is the primary API for playing sound and video.
2. AudioManager: This class manages audio sources and audio output on a device.
Manifest Declarations:
• Before starting development on our application using MediaPlayer, make sure our manifest has the
appropriate declarations to allow use of related features.
• Internet Permission: If you are using MediaPlayer to stream network-based content, our application
must request network access.
• <uses-permissionandroid:name="android.permission.INTERNET"/>
Wake Lock Permission - If our player application needs to keep the screen from dimming
or the processor from sleeping, or uses the MediaPlayer.setScreenOnWhilePlaying() or
MediaPlayer.setWakeMode() methods, you must request this permission.
<uses-permissionandroid:name="android.permission.WAKE_LOCK"/>
Basic MediaPlayer Tasks:
• Here, are the basic tasks that MediaPlayer needs to handle:
1. Load a media file for playback. This is done with the methods setDataSource(), prepare(),
and prepareAsync().
2. Start playback / Play audio. This is handled by start().
3. Pause playback (once playback has started). This is handled by pause().
4. Stop playback and reset the MediaPlayer, so that you can load another media file into it. This
is handled by reset().
5. Find the length of a song (in ms). This is handled by getDuration().
6. Find what part of the song is playing. This is handled by getCurrentPosition().
7. Jump to a specific time position (in ms) in the song and play from there. This is handled
by seekTo(position).
8. Check to see if audio is being played back right now. This is handled by isPlaying().
9. Find out when a song is done playing. This is handled by attaching a
MediaPlayer.OnCompletionListener. Our code will get an onCompletion() callback from the
listener.
10. Deallocate resources used by the player. This is handled by release(), which releases all the
resources attached to the player. After being released the player is no longer usable.
Example:
XML File:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
Mobile Application Development 5.28 Activity and Multimedia with Database

android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.aasemjs.audioplayer.MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true">
<Button
android:text="Play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnPlay"
android:onClick="playSong" />
<Button
android:text="Pause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnPause"
android:onClick="pauseSong" />
<Button
android:text="Stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnStop"
android:onClick="stopSong" />
</LinearLayout>
</RelativeLayout>
Adding the demo sound file to our app
• Once, we are done with our interface, we have to add the audio file to our project.
• We have to add the files to the raw folder. We can find it here app → res → raw. If there is no raw
folder then create it by right-clicking on res → new → directory. Give the directory the name raw,
and nothing else.
• Inside this directory, all our audio files will be present. You can not simply drag and drop files here,
we have to copy our source file, then right-click on the raw directory and click paste. The following
popup will appear.
Mobile Application Development 5.29 Activity and Multimedia with Database

• We have to make sure that the new name you are giving contains all small alphabets. The only valid
characters for the name in any file will be [a-z; 0-9; _].
• If another popup comes asking you to verify the file type, then select the option text. As long as you
have given the correct file type in the name, Android will compile it as the file type we specified, mp3
in this case.
Why are special characters not allowed in Android File Names?
• Special characters are not allowed, except the underscore symbol. This is because each file inside the
folder is translated into java field name inside R.java class:
drawable/icon.png -> R.drawable.icon
• And since special characters are not allowed in Java names, they can’t be used. As for the capital
letters, theories suggest that it is made so because of Linux and Windows.
• Linux treats icon.png and Icon.png as two different files and Windows treats it as one file. So to
avoid any compile time error, we aren’t allowed to use capital letters either in file names.
• Add at least two audio files to our project, once we are done with that, we can start writing the code
in MainActivity.java file.
Coding the Functionality:
• As with all apps, we begin our coding in Java. First, we need to instantiate the MediaPlayer class. This
will create an object of the class:
MediaPlayer mp;
• What is basically happening here is that we have created an object mp of the class MediaPlayer. This
means that all the properties of the class MediaPlayer are stored in this object.
• Once we instantiate the MediaPlayer class, the package android.media.MediaPlayer will get
automatically added to our code. If it doesn’t then do it anywhere near the other imports like this:
import android.media.MediaPlayer;
Adding the Audio File to this Object:
• We want this code to run as soon as the app launches. So we’ll place it in the onCreate function:
mp = MediaPlayer.create(this, R.raw.abc);
• Just make sure that instead of ‘abc’ we mention the name we had given to our file. We don’t need to
add ‘.mp3’ or ‘.wav’ or whatever filetype we are using.
Playing the Sound:
• Now we have to define the function we are calling when we hit the play button. MediaPlayer has an
inbuilt function called start( ). We’ll use that to our advantage.
public void playSong(View v){
mp.start();
}
• Now, if everything is in order then the audio file would start playing.
Pausing the Sound:
• If instead of some sound effect, we added a full-length song then we have to add a way to pause the
song.
• Fortunately, MediaPlayer has an inbuilt function called pause( ) which we will run when we hit the
pause button.
public void pauseSong(View v) {
mp.pause();
}
• Now, if everything is in order then the audio file would pause. Hitting up the Play button will start
the file from where it was paused.
Stopping the Sound:
• Stopping the file will completely stop the file and we won’t be able to run it again.
Mobile Application Development 5.30 Activity and Multimedia with Database

• MediaPlayer has an inbuilt function called stop( ).


public void stopSong(View v) {
mp.stop();
}
• Now when we hit the Play button again, nothing happens. This is because the MediaPlayer object has
been cleared. There is no file present in the object anymore. So in the same function, add another
line of code.
mp = MediaPlayer.create(this, R.raw.abcd);
• This time, add the second file name to avoid confusion.
• Run our app to test it. If we have forgotten how to set up our virtual device, then refresh our memory
by going through the post again.
• Note: The files are stored in the app, so if we add audio files of size larger than 100mb, then our app
size would be larger than 100mb.
Java File:
package com.aasemjs.audioplayer;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
MediaPlayer mp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mp=MediaPlayer.create(this, R.raw.abc);
}
public void playSong(View v){
mp.start();
}
public void pauseSong(View v) {
mp.pause();
}
public void stopSong(View v) {
mp.stop();
mp=MediaPlayer.create(this, R.raw.abcd);
}
}
Example of Video:
File Structure :
Mobile Application Development 5.31 Activity and Multimedia with Database

Java File:
packagecom.android.AndroidVideoPlayer;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.VideoView;
//Implement SurfaceHolder interface to Play video
//Implement this interface to receive information about changes to the surface
publicclassAndroidVideoPlayer extendsActivity implementsSurfaceHolder.Callback{
MediaPlayer mediaPlayer;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
booleanpausing = false;;
/** Called when the activity is first created. */
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonPlayVideo = (Button)findViewById(R.id.playvideoplayer);
getWindow().setFormat(PixelFormat.UNKNOWN);
//Displays a video file.
VideoView mVideoView = (VideoView)findViewById(R.id.videoview);
String uriPath = "android.resource://com.android.AndroidVideoPlayer/"+R.raw.k;
Uri uri = Uri.parse(uriPath);
mVideoView.setVideoURI(uri);
mVideoView.requestFocus();
mVideoView.start();
buttonPlayVideo.setOnClickListener(newButton.OnClickListener(){
Mobile Application Development 5.32 Activity and Multimedia with Database

@Override
publicvoidonClick(View v) {
// VideoView refference see main.xml
VideoView mVideoView = (VideoView)findViewById(R.id.videoview);
String uriPath =
"android.resource://com.android.AndroidVideoPlayer/"+R.raw.k;
Uri uri = Uri.parse(uriPath);
mVideoView.setVideoURI(uri);
mVideoView.requestFocus();
mVideoView.start();
}});
}
@Override
publicvoidsurfaceChanged(SurfaceHolder holder, intformat, intwidth,
intheight) {
// TODO Auto-generated method stub
}
@Override
publicvoidsurfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
publicvoidsurfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
XML FILE : main.xml
• Define VideoView as xml element to play video on activity.
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/playvideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PLAY Video -"
/>
<VideoView
android:id="@+id/videoview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Mobile Application Development 5.33 Activity and Multimedia with Database

</LinearLayout>

XML FILE : AndroidManifest.xml


<?xmlversion="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.AndroidVideoPlayer"
android:versionCode="1"
android:versionName="1.0">
<uses-sdkandroid:minSdkVersion="10"/>

<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
<activityandroid:name=".AndroidVideoPlayer"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

</application>
</manifest>
5.9 TEXT TO SPEECH
• Text to speech (TTS) makes an android device read the text and convert it to audio out via the
speaker. Android TTS supports multiple languages.
• TTS is a simple but powerful feature. It can also be effectively used in mobile APPs dedicated to
visually impaired people or in educational app for kids or can be used in pronunciation learning app,
etc.
• These are some of the ways wecan use TTS. Using TextToSpeech enhances interaction between the
user and the mobile application.
• Android TTS was available from version 1.6. It has features to control speed, pitch of speech as well as
type of language.
Example:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
Mobile Application Development 5.34 Activity and Multimedia with Database

android:layout_marginBottom="50dp"
android:gravity="center_horizontal"
android:text="Android Text to Speech (TTS) Demo"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"/>
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/edit_text_style"
android:hint="Enter the text here"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"/>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
android:elevation="0dp"
android:paddingHorizontal="30dp"
android:text="Click to convert text to speech"/>
</LinearLayout>

MainActivity.java
import android.speech.tts.TextToSpeech;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.Locale;

publicclassMainActivityextendsAppCompatActivity{
privateTextToSpeech textToSpeech;
privateButton btn;
privateEditText editText;

@Override
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn =(Button) findViewById(R.id.btn);

editText =(EditText) findViewById(R.id.et);


textToSpeech
=newTextToSpeech(getApplicationContext(),newTextToSpeech.OnInitListener(){
Mobile Application Development 5.35 Activity and Multimedia with Database

@Override
publicvoid onInit(int status){
if(status ==TextToSpeech.SUCCESS){
int ttsLang = textToSpeech.setLanguage(Locale.US);

if(ttsLang ==TextToSpeech.LANG_MISSING_DATA
|| ttsLang ==TextToSpeech.LANG_NOT_SUPPORTED){
Log.e("TTS","The Language is not supported!");
}else{
Log.i("TTS","Language Supported.");
}
Log.i("TTS","Initialization success.");
}else{
Toast.makeText(getApplicationContext(),"TTS Initialization
failed!",Toast.LENGTH_SHORT).show();
}
}
});

btn.setOnClickListener(newView.OnClickListener(){

@Override
publicvoid onClick(View arg0){

String data = editText.getText().toString();


Log.i("TTS","button clicked: "+ data);
int speechStatus = textToSpeech.speak(data,TextToSpeech.QUEUE_FLUSH,null);

if(speechStatus ==TextToSpeech.ERROR){
Log.e("TTS","Error in converting Text to Speech!");
}
}

});
}

@Override
publicvoid onDestroy(){
super.onDestroy();
if(textToSpeech !=null){
textToSpeech.stop();
textToSpeech.shutdown();
}
}
}

Output:
Mobile Application Development 5.36 Activity and Multimedia with Database

5.10 SENSOR
• Most Android-powered devices have built-in sensors that measure motion, orientation, and various
environmental conditions.
• These sensors are capable of providing raw data with high precision and accuracy, and are useful if
we want to monitor three-dimensional device movement or positioning, or we want to monitor
changes in the ambient environment near a device.
• The Android platform supports following three broad categories of sensors:
1. Motion Sensors: These sensors measure acceleration forces and rotational forces along three axes.
This category includes accelerometers, gravity sensors, gyroscopes, and rotational vector sensors.
2. Environmental sensors: These sensors measure various environmental parameters, such as
ambient air temperature and pressure, illumination, and humidity. This category includes
barometers, photometers, and thermometers.
3. Position sensors: These sensors measure the physical position of a device. This category includes
orientation sensors and magnetometers.
• Following table lits Sensor types supported by the Android platform.
Sr. Common
Sensor Type Description
No. Uses
1. TYPE_ACCELEROMETER Hardware Measures the acceleration force in Motion
m/s2 that is applied to a device on all detection
three physical axes (x, y, and z), (shake, tilt,
including the force of gravity. etc.).

2. TYPE_AMBIENT_TEMPERATU Hardware Measures the ambient room Monitoring


RE temperature in degrees Celsius (°C). air
temperatur
es.
Mobile Application Development 5.37 Activity and Multimedia with Database

3. TYPE_GRAVITY Software Measures the force of gravity in Motion


or m/s2 that is applied to a device on all detection
Hardware three physical axes (x, y, z). (shake, tilt,
etc.).

4. TYPE_GYROSCOPE Hardware Measures a device's rate of rotation in Rotation


rad/s around each of the three detection
physical axes (x, y, and z). (spin, turn,
etc.).

5. TYPE_LIGHT Hardware Measures the ambient light level Controlling


(illumination) in lx. screen
brightness.

6. TYPE_LINEAR_ACCELERATIO Software Measures the acceleration force in Monitoring


N or m/s2 that is applied to a device on all acceleratio
Hardware three physical axes (x, y, and z), n along a
excluding the force of gravity. single axis.

7. TYPE_MAGNETIC_FIELD Hardware Measures the ambient geomagnetic Creating a


field for all three physical axes (x, y, z) compass.
in µT.

8. TYPE_ORIENTATION Software Measures degrees of rotation that a Determinin


device makes around all three g device
physical axes (x, y, z). As of API level 3 position.
you can obtain the inclination matrix
and rotation matrix for a device by
using the gravity sensor and the
geomagnetic field sensor in
conjunction with
the getRotationMatrix() method.

9. TYPE_PRESSURE Hardware Measures the ambient air pressure in Monitoring


hPa or mbar. air
pressure
changes.

10. TYPE_PROXIMITY Hardware Measures the proximity of an object Phone


in cm relative to the view screen of a position
device. This sensor is typically used to during a
determine whether a handset is being call.
held up to a person's ear.

11. TYPE_RELATIVE_HUMIDITY Hardware Measures the relative ambient Monitoring


humidity in percent (%). dewpoint,
absolute,
and
relative
Mobile Application Development 5.38 Activity and Multimedia with Database

humidity.

12. TYPE_ROTATION_VECTOR Software Measures the orientation of a device Motion


or by providing the three elements of detection
Hardware the device's rotation vector. and
rotation
detection.

13. TYPE_TEMPERATURE Hardware Measures the temperature of the Monitoring


device in degrees Celsius (°C). This temperatur
sensor implementation varies across es.
devices and this sensor was replaced
with
the TYPE_AMBIENT_TEMPERATURE se
nsor in API Level 14

5.10.1 Sensor Framework


• You can access these sensors and acquire raw sensor data by using the Android sensor framework.
The sensor framework is part of the android.hardware package and includes the following classes
and interfaces:
SensorManager:
• We can use this class to create an instance of the sensor service. This class provides various methods
for accessing and listing sensors, registering and unregistering sensor event listeners, and acquiring
orientation information. This class also provides several sensor constants that are used to report
sensor accuracy, set data acquisition rates, and calibrate sensors.
Sensor:
• You can use this class to create an instance of a specific sensor. This class provides various methods
that let you determine a sensor's capabilities.
SensorEvent:
• The system uses this class to create a sensor event object, which provides information about a sensor
event. A sensor event object includes the following information: the raw sensor data, the type of
sensor that generated the event, the accuracy of the data, and the timestamp for the event.
SensorEventListener:
• You can use this interface to create two callback methods that receive notifications (sensor events)
when sensor values change or when sensor accuracy changes.
5.11 ANDROID ASYNCTASK
• Android AsyncTask is an abstract category provided by android which provides United States the
freedom to perform significant tasks within the background and keep the UI thread lightweight thus
making the application more responsive.
• Android application runs on one thread once launched. because of this single thread model tasks
that take longer time to fetch the response can make the application non-responsive.
• To avoid this we have a tendency to use Android AsyncTask to perform the significant tasks in
background on a dedicated thread and passing the results back to the UI thread. Hence use of
AsyncTask in android application keeps the UI thread responsive at all times.
• The basic methods used in an android AsyncTask class are defined below :
1. doInBackground() : This method contains the code which needs to be executed in background. In
this method we can send results multiple times to the UI thread by publishProgress() method. To
Mobile Application Development 5.39 Activity and Multimedia with Database

notify that the background processing has been completed we just need to use the return
statements
2. onPreExecute() : This method contains the code which is executed before the background
processing starts
3. onPostExecute() : This method is called after doInBackground method completes processing.
Result from doInBackground is passed to this method
4. onProgressUpdate() : This method receives progress updates from doInBackground method,
which is published via publishProgress method, and this method can use this progress update to
update the UI thread
• The three generic types used in an android AsyncTask class are given below :
1. Params : The type of the parameters sent to the task upon execution
2. Progress : The type of the progress units published during the background computation
3. Result : The type of the result of the background computation
Example:
Activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10pt"
android:textColor="#444444"
android:layout_alignParentLeft="true"
android:layout_marginRight="9dip"
android:layout_marginTop="20dip"
android:layout_marginLeft="10dip"
android:text="Sleep time in Seconds:"/>
<EditText
android:id="@+id/in_time"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background"
android:layout_toRightOf="@id/tv_time"
android:layout_alignTop="@id/tv_time"
android:inputType="number"
/>
<Button
android:id="@+id/btn_run"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Run Async task"
android:layout_below="@+id/in_time"
android:layout_centerHorizontal="true"
android:layout_marginTop="64dp" />
Mobile Application Development 5.40 Activity and Multimedia with Database

<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="7pt"
android:layout_below="@+id/btn_run"
android:layout_centerHorizontal="true" />
</RelativeLayout>
MainActivity.java
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
publicclass MainActivity extends AppCompatActivity {
private Button button;
private EditText time;
private TextView finalResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = (EditText) findViewById(R.id.in_time);
button = (Button) findViewById(R.id.btn_run);
finalResult = (TextView) findViewById(R.id.tv_result);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AsyncTaskRunner runner = new AsyncTaskRunner();
String sleepTime = time.getText().toString();
runner.execute(sleepTime);
}
});
}

privateclass AsyncTaskRunner extends AsyncTask<String, String, String>{


private String resp;
ProgressDialog progressDialog;
@Override
protected String doInBackground(String... params) {
publishProgress("Sleeping..."); // Calls onProgressUpdate()
try {
int time = Integer.parseInt(params[0])*1000;

Thread.sleep(time);
resp = "Slept for " + params[0] + " seconds";
} catch (InterruptedException e) {
Mobile Application Development 5.41 Activity and Multimedia with Database

e.printStackTrace();
resp = e.getMessage();
} catch (Exception e) {
e.printStackTrace();
resp = e.getMessage();
}
return resp;
}
@Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
progressDialog.dismiss();
finalResult.setText(result);
}
@Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(MainActivity.this,
"ProgressDialog",
"Wait for "+time.getText().toString()+ " seconds");
}
@Override
protected void onProgressUpdate(String... text) {
finalResult.setText(text[0]);

}
}
}
Output:

5.12 AUDIO CAPTURE


Mobile Application Development 5.42 Activity and Multimedia with Database

• The Android multimedia system framework includes support for capturing and encoding variety of
common audio formats, so we will simply integrate audio into our applications. We can record
audio using the MediaRecorder APIs if supported by the device hardware.
Performing Audio Capture:
1. Create a new instance of android.media.MediaRecorder.
2. Set the audio source using MediaRecorder.setAudioSource(). We will probably want to
use MediaRecorder.AudioSource.MIC.
3. Set output file format using MediaRecorder.setOutputFormat().
4. Set output file name using MediaRecorder.setOutputFile().
5. Set the audio encoder using MediaRecorder.setAudioEncoder().
6. Call MediaRecorder.prepare() on the MediaRecorder instance.
7. To start audio capture, call MediaRecorder.start().
8. To stop audio capture, call MediaRecorder.stop().
9. When we are done with the MediaRecorder instance, call MediaRecorder.release() on it.
Calling MediaRecorder.release() is always recommended to free the resource immediately.
Example: Record audio and play the recorded audio: The example class below illustrates how to set
up, start and stop audio capture, and to play the recorded audio file.
/*
* The application needs to have the permission to write to external storage
* if the output file is written to the external storage, and also the
* permission to record audio. These permissions must be set in the
* application's AndroidManifest.xml file, with something like:
*
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
* <uses-permission android:name="android.permission.RECORD_AUDIO" />
*
*/
package com.android.audiorecordtest;

import android.app.Activity;
import android.widget.LinearLayout;
import android.os.Bundle;
import android.os.Environment;
import android.view.ViewGroup;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;
import android.content.Context;
import android.util.Log;
import android.media.MediaRecorder;
import android.media.MediaPlayer;
import java.io.IOException;
publicclassAudioRecordTestextendsActivity
{
privatestaticfinalString LOG_TAG ="AudioRecordTest";
privatestaticString mFileName =null;
privateRecordButton mRecordButton =null;
privateMediaRecorder mRecorder =null;
privatePlayButton mPlayButton =null;
privateMediaPlayer mPlayer =null;
privatevoid onRecord(boolean start){
Mobile Application Development 5.43 Activity and Multimedia with Database

if(start){
startRecording();
}else{
stopRecording();
}
}
privatevoid onPlay(boolean start){
if(start){
startPlaying();
}else{
stopPlaying();
}
}
privatevoid startPlaying(){
mPlayer =newMediaPlayer();
try{
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
}catch(IOException e){
Log.e(LOG_TAG,"prepare() failed");
}
}
privatevoid stopPlaying(){
mPlayer.release();
mPlayer =null;
}
privatevoid startRecording(){
mRecorder =newMediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

try{
mRecorder.prepare();
}catch(IOException e){
Log.e(LOG_TAG,"prepare() failed");
}
mRecorder.start();
}
privatevoid stopRecording(){
mRecorder.stop();
mRecorder.release();
mRecorder =null;
}
classRecordButtonextendsButton{
boolean mStartRecording =true;
OnClickListener clicker =newOnClickListener(){
publicvoid onClick(View v){
onRecord(mStartRecording);
if(mStartRecording){
setText("Stop recording");
}else{
Mobile Application Development 5.44 Activity and Multimedia with Database

setText("Start recording");
}
mStartRecording =!mStartRecording;
}
};
publicRecordButton(Context ctx){
super(ctx);
setText("Start recording");
setOnClickListener(clicker);
}
}
classPlayButtonextendsButton{
boolean mStartPlaying =true;
OnClickListener clicker =newOnClickListener(){
publicvoid onClick(View v){
onPlay(mStartPlaying);
if(mStartPlaying){
setText("Stop playing");
}else{
setText("Start playing");
}
mStartPlaying =!mStartPlaying;
}
};
publicPlayButton(Context ctx){
super(ctx);
setText("Start playing");
setOnClickListener(clicker);
}
}
publicAudioRecordTest(){
mFileName =Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName +="/audiorecordtest.3gp";
}
@Override
publicvoid onCreate(Bundle icicle){
super.onCreate(icicle);

LinearLayout ll =newLinearLayout(this);
mRecordButton =newRecordButton(this);
ll.addView(mRecordButton,
newLinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
mPlayButton =newPlayButton(this);
ll.addView(mPlayButton,
newLinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
setContentView(ll);
}
@Override
Mobile Application Development 5.45 Activity and Multimedia with Database

publicvoid onPause(){
super.onPause();
if(mRecorder !=null){
mRecorder.release();
mRecorder =null;
}

if(mPlayer !=null){
mPlayer.release();
mPlayer =null;
}
}
}
5.13 CAMERA
• There are two ways to integrate the camera module.
1. Using In-built Camera App:
• The easiest way to integrate camera feature is, use the in-built camera app that comes with the
device. To launch the camera app, we simply need to pass the acceptable intent with necessary flags.
Rest are taken care by the camera app and it'll come back the information (image or video) to our
app. The disadvantage of this methodology is, we can not customize the camera interface as you'd be
launching third party camera app.
2. Writing Custom Camera App:
• Building our own camera module takes some effort as you would like to create everything from
scratch starting with user interface to integrating camera API (rending camera preview, toggling
front and back cameras, flash, focus etc.).
• However the advantage up here is, you'll be able to build the uniform camera UI which is able to be
same for all the users. we will be able to see custom camera in apps like Instagram, Facebook etc.,
Basics for Camera:
• The Android framework supports capturing images and video through the Camera API or
camera Intent. Here are the relevant classes:
1. Camera: This class is the primary API for controlling device cameras. This class is used to take
pictures or videos when you are building a camera application.
2. SurfaceView: This class is used to present a live camera preview to the user.
3. MediaRecorder: This class is used to record video from the camera.
4. Intent: An intent action type of MediaStore. ACTION_IMAGE_CAPTURE or MediaStore.
ACTION_VIDEO_CAPTURE can be used to capture images or videos without directly using
the Camera object.
• Before starting development on our application with the Camera API, we should make sure our
manifest has the appropriate declarations to allow use of camera hardware and other related
features.
1. Camera Permission: Our application must request permission to use a device camera.
<uses-permission android:name="android.permission.CAMERA" />
2. Camera Features: Our application must also declare use of camera features, for example:
<uses-feature android:name="android.hardware.camera" />
• For a list of camera features, see the manifest Features Reference.
• Adding camera features to our manifest causes Google Play to prevent our application from being
installed to devices that do not include a camera or do not support the camera features we specify.
For more information about using feature-based filtering with Google Play.
Mobile Application Development 5.46 Activity and Multimedia with Database

• If our application can use a camera or camera feature for proper operation, but does not require it,
you should specify this in the manifest by including the android:required attribute, and setting it
to false:
<uses-feature android:name="android.hardware.camera" android:required="false" />
3. Storage Permission: If our application saves images or videos to the device's external storage (SD
Card), we must also specify this in the manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
4. Audio Recording Permission: For recording audio with video capture, our application must request
the audio capture permission.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
5. Location Permission: If our application tags images with GPS location information, you must
request location permission:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Using Existing Camera Apps:
• A quick way to enable taking pictures or videos in our application without a lot of extra code is to use
an Intent to invoke an existing Android camera application.
• A camera intent makes a request to capture a picture or video clip through an existing camera app
and then returns control back to our application. This section shows we how to capture an image or
video using this technique.
• The procedure for invoking a camera intent follows these general steps:
1. Compose a Camera Intent - Create an Intent that requests an image or video, using one of these
intent types:
(i) MediaStore.ACTION_IMAGE_CAPTURE: Intent action type for requesting an image from an
existing camera application.
(ii) MediaStore.ACTION_VIDEO_CAPTURE: Intent action type for requesting a video from an
existing camera application.
2. Start the Camera Intent: Use the startActivityForResult() method to execute the camera intent.
After you start the intent, the Camera application user interface appears on the device screen and
the user can take a picture or video.
3. Receive the Intent Result: Set up an onActivityResult() method in our application to receive the
callback and data from the camera intent. When the user finishes taking a picture or video (or
cancels the operation), the system calls this method.
Creating New Project:
1. Create a new project in Android Studio from File ⇒ New Project and select Basic Activity from
templates.
2. Open app/build.gradle and add Dexter dependency to request the runtime permissions.
app/build.gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// ...

// dexter runtime permissions


implementation 'com.karumi:dexter:4.2.0'
}
3. Add the below resources to respective strings.xml, colors.xml and dimens.xml
strings.xml
<resources>
<string name="app_name">Android Camera</string>
<string name="action_settings">Settings</string>
Mobile Application Development 5.47 Activity and Multimedia with Database

<string name="preview_description">Image and Video preview will appear here</string>


<string name="btn_take_picture">Take Picture</string>
<string name="btn_record_video">Record Video</string>
</resources>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#1fb49c</color>
<color name="colorPrimaryDark">#1fb49c</color>
<color name="colorAccent">#FF4081</color>
</resources>
dimens.xml
<resources>
<dimen name="activity_margin">16dp</dimen>
<dimen name="dimen_8">8dp</dimen>
</resources>
4. Under res, create a new folder named xml. Inside xml folder, create a new xml file
name file_paths.xml
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
5. Open AndroidManifest.xml and add CAMERA, WRITE_EXTERNAL_STORAGE and RECORD_AUDIO
permissions.
• Here we also added camera feature that defines the rules to list the app on Playstore. If we
keep android:required=”true”, Google Playstore won’t let the users to install the app on the devices
that doesn’t have camera feature. Incase of false, the app will be listed but camera feature is
optional.
• We also need <provider> tag to prepare the file paths properly across all the android platforms.
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.androidhive.androidcamera">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
Mobile Application Development 5.48 Activity and Multimedia with Database

android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
6. Create a class named CameraUtils.java and add the below methods. This is a helper class that
provides necessary methods that we need in our camera module.
(i) refreshGallery(): Refreshes the image gallery after taking a new picture or video so that they
will be instantly available in the gallery. In older android devices, gallery won’t be refreshed
until the device is rebooted.
(ii) checkPermissions(): Checks whether all the permissions are granted or not. This would be
called before requesting the camera.
(iii) getOutputMediaFile(): Create a new file in gallery and returns the file. This reference will be
passed to camera intent so that newly taken image / video will be stored in this location.
(iv) optimizeBitmap(): Compresses the bitmap before displaying it on UI to avoid the OutOfMemory
exceptions.
CameraUtils.java
package info.androidhive.androidcamera;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class CameraUtils {


/**
* Refreshes gallery on adding new image/video. Gallery won't be refreshed
* on older devices until device is rebooted
Mobile Application Development 5.49 Activity and Multimedia with Database

*/
public static void refreshGallery(Context context, String filePath) {
// ScanFile so it will be appeared on Gallery
MediaScannerConnection.scanFile(context,
new String[]{filePath}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
});
}
public static boolean checkPermissions(Context context) {
return ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
}
/**
* Downsizing the bitmap to avoid OutOfMemory exceptions
*/
public static Bitmap optimizeBitmap(int sampleSize, String filePath) {
// bitmap factory
BitmapFactory.Options options = new BitmapFactory.Options();
// downsizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = sampleSize;
return BitmapFactory.decodeFile(filePath, options);
}
/**
* Checks whether device has camera or not. This method not necessary if
* android:required="true" is used in manifest file
*/
public static boolean isDeviceSupportCamera(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/**
* Open device app settings to allow user to enable permissions
*/
public static void openSettings(Context context) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", BuildConfig.APPLICATION_ID, null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
public static Uri getOutputMediaFileUri(Context context, File file) {
return FileProvider.getUriForFile(context, context.getPackageName() +
".provider", file);
}
/**
* Creates and returns the image or video file before opening the camera
Mobile Application Development 5.50 Activity and Multimedia with Database

*/
public static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
MainActivity.GALLERY_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.e(MainActivity.GALLERY_DIRECTORY_NAME, "Oops! Failed create "
+ MainActivity.GALLERY_DIRECTORY_NAME + " directory");
return null;
}
}
// Preparing media file naming convention
// adds timestamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MainActivity.MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + "." + MainActivity.IMAGE_EXTENSION);
} else if (type == MainActivity.MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + "." + MainActivity.VIDEO_EXTENSION);
} else {
return null;
}
return mediaFile;
}
}
7. Now open the layout files of main activity i.e activity_main.xml and content_main.xml and add the
below layout code. Here we are defining couple of Buttons, ImageView and VideoView to preview the
captured media.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
content_main.xml
Mobile Application Development 5.51 Activity and Multimedia with Database

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/activity_main">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/activity_margin"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/txt_desc"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="10dp"
android:text="@string/preview_description"
android:textSize="15dp" />
<!-- To display picture taken -->
<ImageView
android:id="@+id/imgPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:visibility="gone" />
<!-- To preview video recorded -->
<VideoView
android:id="@+id/videoPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<!-- Capture picture button -->
<Button
android:id="@+id/btnCapturePicture"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/dimen_8"
android:layout_weight="1"
android:background="@color/colorPrimary"
android:foreground="?attr/selectableItemBackground"
android:text="@string/btn_take_picture"
android:textColor="@android:color/white" />
<!-- Record video button -->
<Button
android:id="@+id/btnRecordVideo"
Mobile Application Development 5.52 Activity and Multimedia with Database

android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dimen_8"
android:layout_weight="1"
android:background="@color/colorPrimary"
android:foreground="?attr/selectableItemBackground"
android:text="@string/btn_record_video"
android:textColor="@android:color/white" />
</LinearLayout>
</LinearLayout>
8. Finally open MainActivity.java and modify the code as shown below.
• In onCreate(), the availability of the camera is checked using isDeviceSupportCamera() method and
activity is closed if the camera is absent on the device.
• On button click, checkPermissions() method is used the check whether required permissions are
granted or not. If not granted, requestCameraPermission() method shows the permissions dialog to
user.
• captureImage() open the camera app to capture the image.
• captureVideo() opens the camera app to record the video.
• Once the media is captured, the image or video will be saved to gallery. previewCapturedImage()
and previewVideo() renders the captured image / video on the screen.
• showPermissionsAlert() shows an alert dialog propting user to enable the permissions in app
settings incase they are denied permanently.
MainActivity.java
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
import java.io.File;
import java.util.List;
public class MainActivity extends AppCompatActivity {
// Activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
Mobile Application Development 5.53 Activity and Multimedia with Database

// key to store image path in savedInstance state


public static final String KEY_IMAGE_STORAGE_PATH = "image_path";
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
// Bitmap sampling size
public static final int BITMAP_SAMPLE_SIZE = 8;
// Gallery directory name to store the images or videos
public static final String GALLERY_DIRECTORY_NAME = "Hello Camera";
// Image and Video file extensions
public static final String IMAGE_EXTENSION = "jpg";
public static final String VIDEO_EXTENSION = "mp4";
private static String imageStoragePath;
private TextView txtDescription;
private ImageView imgPreview;
private VideoView videoPreview;
private Button btnCapturePicture, btnRecordVideo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Checking availability of the camera
if (!CameraUtils.isDeviceSupportCamera(getApplicationContext())) {
Toast.makeText(getApplicationContext(),
"Sorry! our device doesn't support camera",
Toast.LENGTH_LONG).show();
// will close the app if the device doesn't have camera
finish();
}
txtDescription = findViewById(R.id.txt_desc);
imgPreview = findViewById(R.id.imgPreview);
videoPreview = findViewById(R.id.videoPreview);
btnCapturePicture = findViewById(R.id.btnCapturePicture);
btnRecordVideo = findViewById(R.id.btnRecordVideo);
/**
* Capture image on button click
*/
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (CameraUtils.checkPermissions(getApplicationContext())) {
captureImage();
} else {
requestCameraPermission(MEDIA_TYPE_IMAGE);
}
}
});

/**
Mobile Application Development 5.54 Activity and Multimedia with Database

* Record video on button click


*/
btnRecordVideo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (CameraUtils.checkPermissions(getApplicationContext())) {
captureVideo();
} else {
requestCameraPermission(MEDIA_TYPE_VIDEO);
}
}
});
// restoring storage image path from saved instance state
// otherwise the path will be null on device rotation
restoreFromBundle(savedInstanceState);
}
/**
* Restoring store image path from saved instance state
*/
private void restoreFromBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(KEY_IMAGE_STORAGE_PATH)) {
imageStoragePath = savedInstanceState.getString(KEY_IMAGE_STORAGE_PATH);
if (!TextUtils.isEmpty(imageStoragePath)) {
if
(imageStoragePath.substring(imageStoragePath.lastIndexOf(".")).equals("." +
IMAGE_EXTENSION)) {
previewCapturedImage();
} else if
(imageStoragePath.substring(imageStoragePath.lastIndexOf(".")).equals("." +
VIDEO_EXTENSION)) {
previewVideo();
}
}
}
}
}

/**
* Requesting permissions using Dexter library
*/
private void requestCameraPermission(final int type) {
Dexter.withActivity(this)
.withPermissions(Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO)
.withListener(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (report.areAllPermissionsGranted()) {
Mobile Application Development 5.55 Activity and Multimedia with Database

if (type == MEDIA_TYPE_IMAGE) {
// capture picture
captureImage();
} else {
captureVideo();
}

} else if (report.isAnyPermissionPermanentlyDenied()) {
showPermissionsAlert();
}
}
@Override
public void
onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken
token) {
token.continuePermissionRequest();
}
}).check();
}
/**
* Capturing Camera Image will launch camera app requested image capture
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = CameraUtils.getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (file != null) {
imageStoragePath = file.getAbsolutePath();
}
Uri fileUri = CameraUtils.getOutputMediaFileUri(getApplicationContext(), file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
/**
* Saving stored image path to saved instance state
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

// save file url in bundle as it will be null on screen orientation


// changes
outState.putString(KEY_IMAGE_STORAGE_PATH, imageStoragePath);
}

/**
* Restoring image path from saved instance state
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Mobile Application Development 5.56 Activity and Multimedia with Database

super.onRestoreInstanceState(savedInstanceState);
// get the file url
imageStoragePath = savedInstanceState.getString(KEY_IMAGE_STORAGE_PATH);
}
/**
* Launching camera app to record video
*/
private void captureVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
File file = CameraUtils.getOutputMediaFile(MEDIA_TYPE_VIDEO);
if (file != null) {
imageStoragePath = file.getAbsolutePath();
}
Uri fileUri = CameraUtils.getOutputMediaFileUri(getApplicationContext(), file);
// set video quality
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file
// start the video capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
/**
* Activity result method will be called after closing the camera
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Refreshing the gallery
CameraUtils.refreshGallery(getApplicationContext(), imageStoragePath);
// successfully captured the image
// display it in image view
previewCapturedImage();
} else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
} else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Refreshing the gallery
CameraUtils.refreshGallery(getApplicationContext(), imageStoragePath);
// video successfully recorded
// preview the recorded video
Mobile Application Development 5.57 Activity and Multimedia with Database

previewVideo();
} else if (resultCode == RESULT_CANCELED) {
// user cancelled recording
Toast.makeText(getApplicationContext(),
"User cancelled video recording", Toast.LENGTH_SHORT)
.show();
} else {
// failed to record video
Toast.makeText(getApplicationContext(),
"Sorry! Failed to record video", Toast.LENGTH_SHORT)
.show();
}
}
}
/**
* Display image from gallery
*/
private void previewCapturedImage() {
try {
// hide video preview
txtDescription.setVisibility(View.GONE);
videoPreview.setVisibility(View.GONE);
imgPreview.setVisibility(View.VISIBLE);
Bitmap bitmap = CameraUtils.optimizeBitmap(BITMAP_SAMPLE_SIZE,
imageStoragePath);
imgPreview.setImageBitmap(bitmap);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
/**
* Displaying video in VideoView
*/
private void previewVideo() {
try {
// hide image preview
txtDescription.setVisibility(View.GONE);
imgPreview.setVisibility(View.GONE);
videoPreview.setVisibility(View.VISIBLE);
videoPreview.setVideoPath(imageStoragePath);
// start playing
videoPreview.start();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Alert dialog to navigate to app settings
* to enable necessary permissions
*/
Mobile Application Development 5.58 Activity and Multimedia with Database

private void showPermissionsAlert() {


AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Permissions required!")
.setMessage("Camera needs few permissions to work properly. Grant them
in settings.")
.setPositiveButton("GOTO SETTINGS", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
CameraUtils.openSettings(MainActivity.this);
}
})
.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
}
• Run and test the app on a real device. You can see the app working as shown in the demo
screenshots.

5.14 BLUETOOTH
• Android platform includes support for the Bluetooth framework that allows a device to wirelessly
exchange data with other Bluetooth devices.
• In android, Bluetooth is a communication network protocol, which allow a devices to connect
wirelessly to exchange the data with other Bluetooth devices.
• By using android Bluetooth API’s in android applications, we can perform following functionalities.
1. Scan for the available Bluetooth devices within the range
2. Use local Bluetooth adapter for paired Bluetooth devices
3. Connect to other devices through service discovery
4. Transfer data to and from other devices
5. Manage multiple connections
• To transfer the data between two Bluetooth devices, first they must establish a communication
channel using pairing process. The devices which we are going to pair must be discoverable and
should accept the incoming connection requests. Generally, the devices will find the discoverable
devices using a service discovery process. Once the device accepts the pairing request, the two
devices will exchange a security keys to complete the bonding process and the devices will cache
these security keys for later use.
• Once the pairing and bonding process completes, the devices are ready to exchange the required
information. When the session is complete, the device that initiated the pairing request will release
the channel that linked to the discoverable device. The two devices remain bonded, so they can
reconnect automatically during a future session as long as they're in the range of each other.
Example:
activity_main.xml:
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
Mobile Application Development 5.59 Activity and Multimedia with Database

<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/Text"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="30dp">
<Button
android:id="@+id/turnOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/on"/>
<Button
android:id="@+id/turnOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/off"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="80dp">
<Button
android:id="@+id/paired"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/List"/>
<Button
android:id="@+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Find"/>
<ListView
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="200dp">
</ListView>
</LinearLayout>
</RelativeLayout>
strings.xml::
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">BluetoothTest</string>
<string name="action_settings">Settings</string>
<string name="Text">Status: -</string>
Mobile Application Development 5.60 Activity and Multimedia with Database

<string name="on">Turn On</string>


<string name="off">Turn Off</string>
<string name="List">List paired Devices</string>
<string name="Find">Search new Devices / Cancel</string>
</resources>
MainActivity.java:
import android.os.Bundle;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import java.util.Set;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final int REQUEST_ENABLE_BT = 1;
private Button onBtn;
private Button offBtn;
private Button listBtn;
private Button findBtn;
private TextView text;
private BluetoothAdapter myBluetoothAdapter;
private Set<BluetoothDevice> pairedDevices;
private ListView myListView;
private ArrayAdapter<String> BTArrayAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// take an instance of BluetoothAdapter - Bluetooth radio
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(myBluetoothAdapter == null) {
onBtn.setEnabled(false);
offBtn.setEnabled(false);
listBtn.setEnabled(false);
findBtn.setEnabled(false);
text.setText("Status: not supported");
Toast.makeText(getApplicationContext(),"Our device does not support
Bluetooth",
Toast.LENGTH_LONG).show();
} else {
text = (TextView) findViewById(R.id.text);
Mobile Application Development 5.61 Activity and Multimedia with Database

onBtn = (Button)findViewById(R.id.turnOn);
onBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
on(v);
}
});
offBtn = (Button)findViewById(R.id.turnOff);
offBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
off(v);
}
});
listBtn = (Button)findViewById(R.id.paired);
listBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
list(v);
}
});
findBtn = (Button)findViewById(R.id.search);
findBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
find(v);
}
});
myListView = (ListView)findViewById(R.id.listView1);
// create the arrayAdapter that contains the BTDevices, and set it to the
ListView
BTArrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1);
myListView.setAdapter(BTArrayAdapter);
}
}
public void on(View view){
if (!myBluetoothAdapter.isEnabled()) {
Intent turnOnIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOnIntent, REQUEST_ENABLE_BT);
Toast.makeText(getApplicationContext(),"Bluetooth turned on" ,
Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(),"Bluetooth is already on",
Toast.LENGTH_LONG).show();
Mobile Application Development 5.62 Activity and Multimedia with Database

}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if(requestCode == REQUEST_ENABLE_BT){
if(myBluetoothAdapter.isEnabled()) {
text.setText("Status: Enabled");
} else {
text.setText("Status: Disabled");
}
}
}
public void list(View view){
// get paired devices
pairedDevices = myBluetoothAdapter.getBondedDevices();
// put it's one to the adapter
for(BluetoothDevice device : pairedDevices)
BTArrayAdapter.add(device.getName()+ "\n" + device.getAddress());
Toast.makeText(getApplicationContext(),"Show Paired Devices",
Toast.LENGTH_SHORT).show();
}
final BroadcastReceiver bReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name and the MAC address of the object to the arrayAdapter
BTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
BTArrayAdapter.notifyDataSetChanged();
}
}
};
public void find(View view) {
if (myBluetoothAdapter.isDiscovering()) {
// the button is pressed when it discovers, so cancel the discovery
myBluetoothAdapter.cancelDiscovery();
}
else {
BTArrayAdapter.clear();
myBluetoothAdapter.startDiscovery();
registerReceiver(bReceiver,new IntentFilter (BluetoothDevice.ACTION_FOUND));
}
}
public void off(View view){
myBluetoothAdapter.disable();
text.setText("Status: Disconnected");
Mobile Application Development 5.63 Activity and Multimedia with Database

Toast.makeText(getApplicationContext(),"Bluetooth turned off",


Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(bReceiver);
}
}
• We have to declare the permissions in the AndroidManifest.xml file of our project. For this reason we
add BLUETOOTH permission if we want to use any of the Bluetooth features. Also we should
add BLUETOOTH_ADMIN permission, in order to discover other devices.
• Open AndroidManifest.xml file and go to the respective xml tab.
AndroidManifest.xml
<?xmlversion="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.javacodegeeks.android.bluetoothtest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.javacodegeeks.android.bluetoothtest.MainActivity"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Output:
Mobile Application Development 5.64 Activity and Multimedia with Database

• Lets press “Turn On” button in order to activate Bluetooth. A popup window will be shown as we can
see below.

• If we choose “No” option the status will be “Disabled” as the Bluetooth will not be activated.
Mobile Application Development 5.65 Activity and Multimedia with Database

• Select “Yes” option and Bluetooth will be turned on.

• Now click “List paired Devices”, in order to see the paired Bluetooth devices that we had been
connected in the past. We can see the list in the next picture. Also notice that the status is now
“Enabled” and a appropriate icon is appeared, because Bluetooth is active.

• If we click the “Search new Devices/Cancel” button, the list of the enabled Bluetooth devices will be
shown. If we press again the button, the discovery of these devices will be canceled.

• Finally, press “Turn off” button. The Bluetooth is disabled and the default icon for Bluetooth is
disappeared, as you can see in the next image.
Mobile Application Development 5.66 Activity and Multimedia with Database

5.15 ANIMATION
• Animation is the process of creating motion and shape change. Animation in android is possible
from many ways. In this section we will discuss one easy and widely used way of making animation
called tweened animation. Animations are useful when the screen changes state, i.e when the
content loads or new actions become available.
• Animation is the process of creating motion and shape change. In this Tutorial we will show how
simple animations encourage you to use them more freely and confidently.
• Animations notify users about what’s going on in our app and improve the mental model of our
app’s interface.
Android Defines Three Types of Animations:
1. View Animation:
• This is the simplest animation used in Android. It define the properties of our Views that should be
animated using a technique called Tween Animation.It take the following parameters i.e. size, time
duration , rotation angle, start value , end value, and perform the required animation on that
object.You can execute the animation by specifying transformations on our View. This can be done
in XML resource files or programmatically.
• Android View animation can make animation on any View objects, such as ImageView, TextView or
Button objects. View animation can only animate simple properties like position, size, rotation, and
the alpha property that allows you animate the transparency of a View.
• The drawback of this mechanism is that it can only be applied to Views.
2. Property Animation:
• This animation was introduced in Android 3.0 (API level 11). It allows the user to animate anything.
• Property animations are highly customizable, we can specify the duration, the number of repeats,
the type of interpolation, and the frame rate of the animation. The Property Animation system is
always preferred for more complex animations.
• Property animations allow us to animate any property of any object from one value to another over a
specified duration.
• Let us take an example, imagine we wanted to animate the 3d rotation using the rotationX or
rotationY properties that were introduced in API 11. Or maybe you want to animate a color change or
animate the change of a drawable. This is not possible by using View Animations. For this purpose
Property Animation is used .
• We are not limited by predefined animation types or by the type of object that you want to animate.
At first the usage of the Property Animation System might seem a little complicated. However, in
most cases you can use the very versatile ObjectAnimator that uses reflection. The ObjectAnimator
makes creating Property Animations almost as easy as creating View Animations.
• Common properties commonly animated on views include:
Mobile Application Development 5.67 Activity and Multimedia with Database

Sr. No. Property Description


1. alpha Fade in or out
2. rotation, rotationX, rotationY Spin or flip
3. scaleX ,scaleY Grow or shrink
4. x,y,z Position
5. translationX, translationY, translationZ (API 21+) Offset from Position
3. Drawable Animation:
• This animation allows the user to load drawable resources and display them one frame after
another. This method of animation is useful when user wants to animate things that are easier to
represent with Drawable resources.
• To use Animations in Android, Android has provided us a class called Animation.
• The Animation class has many methods given below:
1. start(): This method will start the animation.
2. setDuration(long duration): This method sets the duration of an animation.
3. getDuration(): This method gets the duration.
4. end(): This method ends the animation.
5. cancel(): This method cancels the animation.
Example: Animation example in Android Studio showing 14 types of animation:
activity_main.xml code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayoutxmlns:android="http://schemas.android.com/apk/res
/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayoutxmlns:android="http://schemas.android.com/apk/res
/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
Mobile Application Development 5.68 Activity and Multimedia with Database

android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayoutxmlns:android="http://schemas.android.com/apk/res
/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
content_main.xml code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
Mobile Application Development 5.69 Activity and Multimedia with Database

android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/app_bar_main">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
nav_header.xml code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:weightSum="1">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/animation"
android:layout_alignParentTop="true"
android:layout_alignRight="@+id/textView"
android:layout_alignEnd="@+id/textView"
android:layout_marginRight="172dp"
android:layout_marginEnd="172dp"/>
<TextView
android:id="@+id/textView"
android:layout_width="140dp"
android:layout_height="55dp"
android:text="ANIMATION EXAMPLE"
android:textColor="#0606ea"
android:textSize="11dp"
android:textStyle="bold"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="17dp"/>
</RelativeLayout>
activity_main_drawer.xml file available in res=>menu folder:
<?xml version="1.0" encoding="utf-8"?>
Mobile Application Development 5.70 Activity and Multimedia with Database

<menuxmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<groupandroid:checkableBehavior="single">
<item
android:id="@+id/nav_zoomin"
android:title="Zoom In"/>
<item
android:id="@+id/nav_zoomout"
android:title="Zoom Out"/>
<item
android:id="@+id/nav_rotate"
android:title="Rotate"/>
<item
android:id="@+id/nav_move"
android:title="Move"/>
<item
android:id="@+id/nav_bounce"
android:title="Bounce"/>
<item
android:id="@+id/nav_Blink"
android:title="Blink"/>
<item
android:id="@+id/nav_slideup"
android:title="Slide Up"/>
<item
android:id="@+id/nav_slidedown"
android:title="Slide Down"/>
<item
android:id="@+id/nav_fade"
android:title="Fade Animation"/>
<item
android:id="@+id/nav_sequentialanimation"
android:title="Sequential Animation"/>
<item
android:id="@+id/nav_togetheranimation"
android:title="Together Animation"/>
<item
android:id="@+id/nav_flip"
android:title="Flip Animation"/>
<item
android:id="@+id/nav_drawable"
android:title="Drawable Animation"/>
<item
android:id="@+id/nav_swap"
android:title="Swap Animation"/>
</group>
</menu>
MainActivity.java
import android.support.v4.app.Fragment;
import android.os.Bundle;
Mobile Application Development 5.71 Activity and Multimedia with Database

import android.support.v4.app.FragmentTransaction;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import com.example.abhishek.animationexample.fragment.blinkfragment;
import com.example.abhishek.animationexample.fragment.bouncefragment;
import com.example.abhishek.animationexample.fragment.drawableanimationfragment;
import com.example.abhishek.animationexample.fragment.fadefragment;
import com.example.abhishek.animationexample.fragment.flipfragment;
import com.example.abhishek.animationexample.fragment.movefragment;
import com.example.abhishek.animationexample.fragment.rotatefragment;
import com.example.abhishek.animationexample.fragment.sequentialanimationfragment;
import com.example.abhishek.animationexample.fragment.slidedownfragment;
import com.example.abhishek.animationexample.fragment.slideupfragment;
import com.example.abhishek.animationexample.fragment.swapanimationfragment;
import com.example.abhishek.animationexample.fragment.togetheranimationfragment;
import com.example.abhishek.animationexample.fragment.zoominfragment;
import com.example.abhishek.animationexample.fragment.zoomoutfragment;
publicclassMainActivityextendsAppCompatActivity
implementsNavigationView.OnNavigationItemSelectedListener{
@Override
protectedvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar =(Toolbar) findViewById(R.id.toolbar);
DrawerLayout drawer =(DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle =newActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView =(NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
publicvoid onBackPressed(){
DrawerLayout drawer =(DrawerLayout) findViewById(R.id.drawer_layout);
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else{
super.onBackPressed();
}
}
privatevoid displaySelectedScreen(int itemId){
Fragment fragment =null;
Mobile Application Development 5.72 Activity and Multimedia with Database

switch(itemId){
case R.id.nav_bounce:
fragment =new bouncefragment();
break;
case R.id.nav_Blink:
fragment =new blinkfragment();
break;
case R.id.nav_zoomin:
fragment =new zoominfragment();
break;
case R.id.nav_zoomout:
fragment =new zoomoutfragment();
break;
case R.id.nav_rotate:
fragment =new rotatefragment();
break;
case R.id.nav_move:
fragment =new movefragment();
break;
case R.id.nav_slideup:
fragment =new slideupfragment();
break;
case R.id.nav_slidedown:
fragment =new slidedownfragment();
break;
case R.id.nav_sequentialanimation:
fragment =new sequentialanimationfragment();
break;
case R.id.nav_togetheranimation:
fragment =new togetheranimationfragment();
break;
case R.id.nav_flip:
fragment =new flipfragment();
break;
case R.id.nav_fade:
fragment=new fadefragment();
break;
case R.id.nav_drawable:
fragment =new drawableanimationfragment();
break;
case R.id.nav_swap:
fragment =new swapanimationfragment();
break;
}
if(fragment !=null){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
DrawerLayout drawer =(DrawerLayout) findViewById(R.id.drawer_layout);
Mobile Application Development 5.73 Activity and Multimedia with Database

drawer.closeDrawer(GravityCompat.START);
}
@Override
publicboolean onNavigationItemSelected(MenuItem item){
displaySelectedScreen(item.getItemId());
returntrue;
}
}
5.16 SQLITE DATABASE
• Android SQLite is a very lightweight database which comes with Android OS. Android SQLite
combines a clean SQL interface with a very small memory footprint and decent speed.
• For Android, SQLite is “baked into” the Android runtime, so every Android application can create its
own SQLite databases.
• SQLite is a typical relational database, containing tables (which consists of rows and columns),
indexes etc. SQLiteDatabase has methods to create, delete, execute SQL commands, and perform
other common relational database management tasks.
5.16.1 What is SQLite Database?
• SQLite is an embedded, relational database management system (RDBMS).
• Most relational databases (Oracle and MySQL being prime examples) are standalone server processes
that run independently, and in cooperation with, applications that require database access.
• SQLite is referred to as embedded because it is provided in the form of a library that is linked into
applications. As such, there is no standalone database server running in the background.
• All database operations are handled internally within the application through calls to functions
contained in the SQLite library.
• The developers of SQLite have placed the technology into the public domain with the result that it is
now a widely deployed database solution.
• SQLite is written in the C programming language and as such, the Android SDK provides a Java based
“wrapper” around the underlying database interface. This essentially consists of a set of classes that
may be utilized within the Java code of an application to create and manage SQLite based databases..
5.16.2 Why SQLite/Necessity of SQLite
1. Serverless: SQLite is serverless which does not need a detach server process or system to operate.
2. Zero Configurations: SQLite does not require any setup or administration.
3. Cross-platform: a complete SQLite database is stored in a single cross-platform disk file.
4. Less Memory: SQLite is very small and light weight, less than 400 KiB completely configured or less
than 250 KiB with optional featues omitted.
5. Self-Contained: SQLite has no external dependencies.
6. Transaction: SQLite transactions are supported ACID properties to allow safe access from multiple
processes or threads.
7. Languages and operating system: SQLite supports most of the query language featueres found in
SQL92(SQL2) standared.
5.16.3 Creation and Connetion of Database
1. The package imported into the application is android.database.sqlite.SQLiteDatabase.
2. Here the class used is SQLiteDatabase
3. The method used to create the database or connect to the database is openOrCreateDatabse() method.
Mobile Application Development 5.74 Activity and Multimedia with Database

Example:
Create a new project in Eclipse called Database and select the API version.
Use the package name com.db.DataBase with an activity Database and click finish.
package com.db.DataBase;
import android.app.Activity;
import android.database.sqlite.SQLiteDatabse;
public class Databse extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SQLiteDatabase.CRETE_IF_NECESSARY,null);
}
}
• Import the package android.database.sqlite.SQLLiteDatabse to the new android project. Then after
the standard layout setup it initializes a SQLiteDatabse variable to hold the database instance. Next
we use the openOrCreateDatabase() method to open the database. The openOrCreateDatabse()
method to open the databse.
Properties to setting the database:
• There are some databse properties that must be set after connecting to the database. Some methods
are used to set these properties. These are:
1. setVersion(): It sets the databse version.
2. setLocale(): It sets the default locale for the database.
3. setLockingEnabled(): It enables locking on the databse.
• How we create a table:
1. After executing the statements the table is created on the databse.
2. The queries are executed by the execSQL() statements.
DataBase.java
package com.db.DataBase;
import java.util.Locale;
import android.app.activity;
import android.os.Bundle;
import android.database.sqlite.SQLiteDatabase;
public class DataBase extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

SQLiteDatabase sdb;
sdb = openOrCreateDatabase(“Database.db”, SQLiteDatabase.CREATE_IF_NECESSARY,
null);
sdb.setVersion(1);
sdb.setLocale(Locale.getDefault());
sdb.setLockingEnabled(true);
AUTOINCREMENT,” + “country_name_TEXT);” ;
final String CREATE_TABLE_COUNTRIES = “CREATE TABLE tbl_countries (“+” id INTEGER
PRIMARY KEY
final String CREATE_TABLE_STATES = “CREATE TABLE tbl_states (“
Mobile Application Development 5.75 Activity and Multimedia with Database

+ “id INTEGER PRIMARY KEY AUTOINCREMENT,”


+ “state_name TEXT,”
+ “country_id INTEGER NOT NULL CONSTRAINT “
+ “country_id REFERENCES tbl_contries(id) “
+ “ON DELETE CASCADE);”;
sdb.execSQL(CREATE_TABLE_COUNTRIES);
sdb.execSQL(CREATE_TABLE_STATES);
final String CREATE_TRIGGER_STATES =
“CREATE TRIGGER fk_insert_state BEFORE “
+ “INSERT on tbl_states”
+ “FOR EACH ROW “
+ “BEGIN “
+ “ SELECT RAISE(ROLLBACK, ‘ insert on table “
+ ““tbl_states” violets foreign key constraint “
+ ““fk_insert_state”’) WHERE (SELECT id FROM “
+ ” tbl_countries WHERE id = NEW.country_id) IS NULL; “ + “END;”;
sdb.execSQL(CREATE_TRIGGER_STATES);
}
}
3. After opening the databse by openOrCreateDatabase(), we configure the database connection
with setVersion() to set the database version.
4. The setLocale() method sets the default locale for the database and setLockingEnabled() enables
locking on the databse.
5. Then we setup final string variables to hold the SQLite table creation statements and execute
them with execSQL().
6. We should create triggers to handle the foreign key relationships between the tables.
7. In the application, there also require foreign key triggers to handle row updates and deletes.
How to insert the records?
1. Android contains a series of classes that make simpler database handling.
2. We use a contentValues instance to create a series of table filed to data matchings that will be
passed into an insert() method.
3. Android has created alike methods for updating and deleting records.
ContentValues values = new ContentValues();
values.put(“country_name”, “US”);
long countryId = sdb.insert(“tbl_countries”, null, values);
ContentValues statevalues = new ContentValues();
stateValues.put(“state_name”, “Texas”);
stateValues.put(“contry_id”, Long.tostring(countryId));
try
{
db.insertOrThrow(“tbl_states”, null, statevalues);
}catch(Exception e)
{
}
Add this code to previous example.
4. First we creae a contentValues object to store the data to insert and use the put() method to load
the data.
5. Then we use the insert() method to insert records into SQLite. The insert() method contains three
parameters: (a) Table name, (b) Null, (c) ContentValues pairs
6. The insert() function returns long which holds the primary key of the inserted row.
Mobile Application Development 5.76 Activity and Multimedia with Database

7. Then we create a new ContentValues pair for thr state and execute a second insert using the
insertOrThrow() method.
8. Using insertOrThrow() will through an exception if the insert isn’t successful and should ne
enclosed by a try/catch block.
9. We observe that presently the application terminates with an unhandled exception because the
tables we are trying to create previously exist.
10. Then we have to go back into the adb shell and attach to the SQLite database for the application
and drop the tables.
How we can update the data in database:
1. The update() method is used to update the records in databse.
2. The update() function supports WHERE clause with the replacement passed as an array in
parameter 4 to update.
ContentValues updateCountry = new ContentValues();
updateCountry.put(“country_name”, “United States”);
db.update(“tbl_countries”,updateCountry,”id=?”,new String[]
{Long.toString(countryId)});
5. First we remove the table the create statements from the code. Here there is no requirement of
creating and droping tables.
6. Here updateCountry is an instance of ContentValues which is created to hold tha data to be
updated. Then use the update() method to update the table. The where cluse in parameter 3 uses
substitute of the ? with the values stored in parameter 4.
If If multiple ? existed in the whwre statement they would be replaced in order by the values of
the array.
How we can delete the data from the databse?
1. If data is no more longer required, then we can be removed from the databse with the delete()
method.
2. The delete() method excepts 3 parameters.
a. the database name,
b. a WHERE clause and
c. an argument array for the WHERE clause
3. To delete all records from the table pass null for the WHERE clause and WHERE clause argument
array.
sdb.delete(“tbl_states”, “id=?”, new String[] {Long.toString(contryID)});
4. Only we call the delete() method to remove records from the SQLite databse.
5. The delete method contains, the table name, and optionally a where clause and anywhere clause
argument replacement arrays as parameters.
6. The where clause and argument replacement array work just as with update where? Is replaced
by the values in the array.
5.16.4 Extracting values from a cursors
• Cursor store query result records in rows and grant many methods to access and interact through
the records.
• Cursors should be closed when no longer used, and can be deactivated with a call to Cursor.
decactivate() statement when the application pauses or exists.
• On resume the Cursor.requery() statement is executed to re-enable the cursor with fresh data. These
functions can be manage by the parent Activity by calling startManagingCursor().
DataBase.java
Mobile Application Development 5.77 Activity and Multimedia with Database

package com.db.DataBase;
import java.util.locale;
import android.app.Activity;
import java.os.Bundle;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DataBase extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstancestate);
setContentView(R.layout.main);
SQLiteDatabase sdb;
sdb = openOrCreateDatabase(“TestingData.db”, SQLiteDatabase.CREATE_IF_NECESSARY,
null);
sdb.setVersion(1);
sdb.setLocale(Locale.getDefault());
sdb.setLockingEnabled(true);
Cursor cur = sdb.query(“tbl_countries”, null, null, null, null, null, null);
cur.close();
}
}
• The query performed will return all records from the table tbl_countries.
Iterating through records:
• The Cursor class provides a couple of simple methods to allow iterating through Cursor data easily.
• Use moveToFirst() to position the Cursor pointer at the first record then use the moveToNext()
function to iterate the records.
• The isAfterLast() method performs a check to see if the cursor is pointed after the last record. When
looping throughout the records break the loop when this become false
• First add the following attribute to the TextView element in the main layout which is the xml file
located at res/layouts/main.xml.
• We require giving this TextView element an ID that we can reference to update the view.
android:id=”@+id/hello”
• Java code to ierate through entries in a cursor.:
DataBase.java
package com.db.DataBase;
import java.util.locale;
import android.app.Activity;
import java.os.Bundle;
import android.widget.Textview;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DataBase extends Activity
{
public void onCreate(Bundle savedInstanceState)
Mobile Application Development 5.78 Activity and Multimedia with Database

{
super.onCreate(savedInstancestate);
setContentView(R.layout.main);
TextView view = (TextView) findViewById(R.id.hello);

SQLiteDatabase sdb;
sdb = openOrCreateDatabase(“Databse.db”, SQLiteDatabase.CREATE_IF_NECESSARY, null);
sdb.setVersion(1);
sdb.setLocale(Locale.getDefault());
sdb.setLockingEnabled(true);
Cursor cur = sdb.query(“tbl_countries”, null, null, null, null, null, null);
cur.moveToFirst();
while (cur.isAfetrLast() = = false)
{
view.append(“n” + cur.getString(1));
cur.moveToNext();
}
cur.close();
}
}
• The moveTofirst() method is used to location the cursor pointer at the beginning of the data set. The
loop throughout the records in the cursor.
• The method is AfterLast() returns a Boolean if the pointer is past the last record in the cursor. Here
we use the moveToNext() method to traverse through the records in the cursor.
• Retriving a specific record:
• The cursor also allows direct access to particular records:
Cursor cur = sdb.query(“tbl_countries, null, null, null, null, null, null);
cur.moveToPosition(0);
view.append(“n” + cur.getstring(1));
cur.close();

cur.close();
}
}
5.16.5 Transactions
• All of the previously discussed insert, update, and delete operations manipulate tables and rows in a
database. While each operation is atomic (will either succeed or fail on its own), it is sometimes
necessary to group a set of operations together and have the set of operations be atomic.
• There are times when a set of related operations should be allowed to manipulate the database only
if all operations succeed to maintain database integrity. For these cases, a database transaction is
usually used to ensure that the set of operations is atomic.
• A transaction is a unit of work that is performed against a database. Transactions are units or
sequences of work accomplished in a logical order, whether in a manual fashion by a user or
automatically by some sort of a database program.
Mobile Application Development 5.79 Activity and Multimedia with Database

• A transaction is the propagation of one or more changes to the database. For example, if you are
creating, updating, or deleting a record from the table, then you are performing transaction on the
table. It is important to control transactions to ensure data integrity and to handle database errors.
• Transactions have the following four standard properties, usually referred to by the acronym ACID.
1. Atomicity: Ensures that all operations within the work unit are completed successfully;
otherwise, the transaction is aborted at the point of failure and previous operations are rolled
back to their former state.
2. Consistency: Ensures that the database properly changes states upon a successfully committed
transaction.
3. Isolation: Enables transactions to operate independently of and transparent to each other.
4. Durability: Ensures that the result or effect of a committed transaction persists in case of a
system failure.
• In Android, the SQLiteDatabase class contains the following methods to support transaction
processing:
1. void beginTransaction(): Begins a transaction
2. void setTransactionSuccessful(): Indicates that the transaction should be committed
3. void endTransaction(): Ends the transaction causing a commit if setTransactionSuccessful() has
been called
Using a Transaction:
• A transaction is started with the SQLiteDatabase.beginTransaction() method. Once a transaction is
started, calls to any of the data manipulation method calls (insert(), update(), delete()) may be
made.
• Once all of the manipulation calls have been made, the transaction is ended with
SQLiteDatabase.endTransaction().
• To mark the transaction as successful, allowing all the operations to be committed, SQLiteDatabase.
setTransactionSuccessful() must be called before the call to SQLiteDatabase.endTransaction() is
made. If endTransaction() is called without a call to setTransactionSuccessful(), the transaction will
be rolled back, undoing all of the operations in the transaction.
• Because the call to setTransactionSuccessful() affects what happens during the endTransaction()
call, it is considered a best practice to limit the number of non-database operations between a call
to setTransactionSuccessful() and endTransaction().
• Additionally, do not perform any additional database manipulation operations between the call to
setTransactionSuccessful() and endTransaction(). Once the call to setTransactionSuccessful() is
made, the transaction is marked as clean and is committed in the call to endTransaction() even if
errors have occurred after the call to setTransactionSuccessful(
• Transaction Example
SQLiteDatabase db = getDatabase();
db.beginTransaction();

try {
// insert/update/delete
// insert/update/delete
// insert/update/delete
db.setTransactionSuccessful();
} finally {
db.endTransaction();
Mobile Application Development 5.80 Activity and Multimedia with Database

}
• Database operations that happen in a transaction as well as the call to setTransaction() should take
place in a try block with the call to endTransaction() happening in a finally block. This ensures that
the transaction will be ended even if an unhandled exception is thrown while modifying the
database.
Practice Questions
1. What is activity?
2. What is multimedai database?
3. What is service?
4. What is indent?
5. What is SQLite?
6. Enlist features of service.
7. Describe the term Indent Filter with example.
8. What is sensor? Enlist its types in Android.
9. Explain activity life cycle diagramatically.
10. What is fragment ? Describe with example.
11. Explain content provider in detai.
12. With the help of diagram exaplin activity broadcast life cycle.
13. What is meant by content provider?
14. Enlist various permission for servcies.
15. What is animation? Enlist its types.
16. Describe th term audio capture in detail.
17. How to play audio and video in Android?
18. How to create and connect SQLite ? Explain with example.
19. With the help of diagram describe following frame works:
(i) Multimedia (ii) Android system architecture
20. Describe the term text to speech in detail.
21. How to extracting values from cursors in Android?
22. What is transaction? Describe with example.
23. Explain service life cycle diagrammatically.

You might also like