0% found this document useful (0 votes)
281 views431 pages

Mobile App Development Overview

This document describes the course contents for CSE 4027 - Mobile Application Development. The course covers topics such as getting started with mobility, building blocks of mobile apps, enhancing apps with Android features, and testing mobile apps. It lists 5 textbooks and 4 reference books related to mobile app development. The class will be held weekly for 3 hours, with 2 hours of theory lecture, 1 hour of demo/hands-on sessions. Students are expected to bring fully charged laptops to class. Evaluation includes two sessionals worth 15 marks each, one assignment worth 20 marks.

Uploaded by

sanjay prabhu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
281 views431 pages

Mobile App Development Overview

This document describes the course contents for CSE 4027 - Mobile Application Development. The course covers topics such as getting started with mobility, building blocks of mobile apps, enhancing apps with Android features, and testing mobile apps. It lists 5 textbooks and 4 reference books related to mobile app development. The class will be held weekly for 3 hours, with 2 hours of theory lecture, 1 hour of demo/hands-on sessions. Students are expected to bring fully charged laptops to class. Evaluation includes two sessionals worth 15 marks each, one assignment worth 20 marks.

Uploaded by

sanjay prabhu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 431

CSE 4027 - Mobile Application Development

Contents
Contents

1 Getting started with Mobility


Contents

1 Getting started with Mobility


2 Building blocks of mobile apps
Contents

1 Getting started with Mobility


2 Building blocks of mobile apps
3 Sprucing up mobile apps
Contents

1 Getting started with Mobility


2 Building blocks of mobile apps
3 Sprucing up mobile apps
4 Enhancing Application with Powerful Android Features
Contents

1 Getting started with Mobility


2 Building blocks of mobile apps
3 Sprucing up mobile apps
4 Enhancing Application with Powerful Android Features
5 Testing mobile apps
Contents

1 Getting started with Mobility


2 Building blocks of mobile apps
3 Sprucing up mobile apps
4 Enhancing Application with Powerful Android Features
5 Testing mobile apps
6 Taking apps to Market
Text Books
Text Books

1 Anubhav Pradhan, Anil V Deshpande, "Composing Mobile


Apps", Wiley
Text Books

1 Anubhav Pradhan, Anil V Deshpande, "Composing Mobile


Apps", Wiley
2 Reto Meier, "Professional Android 4 Application
Development", Wrox Publications, 2012
Text Books

1 Anubhav Pradhan, Anil V Deshpande, "Composing Mobile


Apps", Wiley
2 Reto Meier, "Professional Android 4 Application
Development", Wrox Publications, 2012
3 Wei-Meng Lee, "Beginning Android 4 Application
Development", Wrox Publications, 2012
Text Books

1 Anubhav Pradhan, Anil V Deshpande, "Composing Mobile


Apps", Wiley
2 Reto Meier, "Professional Android 4 Application
Development", Wrox Publications, 2012
3 Wei-Meng Lee, "Beginning Android 4 Application
Development", Wrox Publications, 2012
4 Zigurd Mednieks, Laird Dornin, G. Blake Meike and Masumi
Nakumara, "Programming Android", O'Reilly Publications,
2011
Text Books

1 Anubhav Pradhan, Anil V Deshpande, "Composing Mobile


Apps", Wiley
2 Reto Meier, "Professional Android 4 Application
Development", Wrox Publications, 2012
3 Wei-Meng Lee, "Beginning Android 4 Application
Development", Wrox Publications, 2012
4 Zigurd Mednieks, Laird Dornin, G. Blake Meike and Masumi
Nakumara, "Programming Android", O'Reilly Publications,
2011
5 Jerome DiMarzio, "Android A Programmer's Guide",
McGrawHill Publications, 2008
Reference Books
Reference Books

1 Brian Hardy, Bill Phillips, "Android Programming : The Big


Nerd Ranch Guide", Big Nerd Ranch Inc., 2013
Reference Books

1 Brian Hardy, Bill Phillips, "Android Programming : The Big


Nerd Ranch Guide", Big Nerd Ranch Inc., 2013

2 Android Studio 3.0 - Development Essentials - Android 8


Edition, 2017
Additional Materials
Additional Materials

http://developer.android.com/reference/packages.html
Additional Materials

http://developer.android.com/reference/packages.html

Design Patterns in Java


Class Pattern
Class Pattern

Weekly 3 Hours
Class Pattern

Weekly 3 Hours

2 Hours Theory
Class Pattern

Weekly 3 Hours

2 Hours Theory

1 Hours Demo / Hands On


Class Pattern

Weekly 3 Hours

2 Hours Theory

1 Hours Demo / Hands On

During Demo classes bring fully-charged Laptops


Evaluation
Evaluation

Sessional-I - 15 Marks
Evaluation

Sessional-I - 15 Marks

Sessional-II - 15 Marks
Evaluation

Sessional-I - 15 Marks

Sessional-II - 15 Marks

Assignment- 20 Marks
Introduction
Introduction

Initial mobiles - media player, reading e-books, web browsing


Introduction

Initial mobiles - media player, reading e-books, web browsing

Today - banking, travel itenary, education, watching television


Introduction

Initial mobiles - media player, reading e-books, web browsing

Today - banking, travel itenary, education, watching television

Any one can become App Developer


Mobility Panorama
Contents

1 Introduction

2 Mobility Panorama

3 Mobile Platforms

4 App Development Approaches

5 Android Overview
Mobility Panorama
Logical landscape of mobility
Logical landscape of mobility
Physical ecosystem of mobility
Mobile Components

Mobile Devices
Mobile Platforms
Mobile App Stores
Mobile Devices

Smart phones, tablets, phablets, e-readers, music players, smart


watches
Mobile Platforms

Android, Apple iOS


Play Stores

Apple App Store, Google Play


App Development Approaches
App Development Approaches

1 business case - B2C, B2B

2 user prole - customer, agent, vendor, supplier, senior


executive

3 mobile device - device type, device connectivity, operating


environment
App Development Approaches
Hybrid Approaches
Hybrid Approaches

1 Web-based Philosophy
App is created using web technology. App is wrapped in a
wrapper. Native wrapper will allow the app to leverage device
capabilities. e.g. JQuery Mobile, Sencha Touch used to create
the app. Adobe Phone Gap is used to wrap.
Hybrid Approaches

1 Web-based Philosophy
App is created using web technology. App is wrapped in a
wrapper. Native wrapper will allow the app to leverage device
capabilities. e.g. JQuery Mobile, Sencha Touch used to create
the app. Adobe Phone Gap is used to wrap.
2 Cross-compiler Philosophy
App is created using web technology. App is cross compiled to
native app.
Hybrid Approaches

1 Web-based Philosophy
App is created using web technology. App is wrapped in a
wrapper. Native wrapper will allow the app to leverage device
capabilities. e.g. JQuery Mobile, Sencha Touch used to create
the app. Adobe Phone Gap is used to wrap.
2 Cross-compiler Philosophy
App is created using web technology. App is cross compiled to
native app.
3 Middleware Philosophy
Allows hybrid app to be hosted on a middleware server. Users
can retrieve the app from the middleware server. Middleware
server acts as interface between app and enterprise systems.
e.g. SAP SMP, Kony(middleware)
Hybrid App Development Approaches

1 Web based philosophy

2 Cross compiler philosophy

3 Middleware philosophy - SAP SMP, Kony


Android Overview
Android Overview

An Open source mobile native platform


governed by Open Handset Alliance(OHA), led by Google
accepted by customers, app developers, OEMs
Android Software Stack
Android Software Stack
Mobile Platforms
Mobile Platforms

OS have come o the ages


Mobile Platforms

OS have come o the ages

A mobile platform is a software stack


Mobile Platforms

OS have come o the ages

A mobile platform is a software stack

Comprises OS, libraries and Application Development Frameworks


Mobile Platforms

OS have come o the ages

A mobile platform is a software stack

Comprises OS, libraries and Application Development Frameworks

OS does memory management, process management


Mobile Platforms

OS have come o the ages

A mobile platform is a software stack

Comprises OS, libraries and Application Development Frameworks

OS does memory management, process management

Libraries - media libraries, libraries for native data storage, rendering


screens and libraries for graphics
Mobile Platforms
Mobile Platforms

Android
Mobile Platforms

Android

Apple iOS
Mobile Platforms

Android

Apple iOS

Blackberry
Mobile Platforms

Android

Apple iOS

Blackberry

Windows Phone
XML

XML stands for Extensible Markup Language.


Tags(Elements) are not predened in XML
XML is readable both by humans and machine
Layouts
Basics of User Interface

The whole concept of Android User Interface is dened using


the hierarchy of View and ViewGroup objects
View class is dened in android.view package
ViewGroup class is dened in android.view package
ViewGroup class is subclass of View class
A ViewGroup can contain Views and other ViewGroups
View and ViewGroup
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.
com/apk/res/android"
android:orientation="vertical" android:layout_width="
match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/buton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"/>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sample Text"
android:layout_marginTop="15dp"
android:textSize="30dp"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editTextName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="First Name"
/>
<EditText
android:id="@+id/editTextLastName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Last Name"/>
</RelativeLayout>
</LinearLayout>
Layouts

Linear Layout, Relative Layout, Absolute Layout, Table Layout,


Frame Layout and ConstraintLayout
Layout

Layouts are examples for ViewGroups


every Layout class is dened in android.widget package
every Layout class inherited from android.view.ViewGroup
Layout XML Files

Layout XML les are used to dene the actual UI of our application.
It holds all the elements(views) like the TextView, Buttons and
other UI elements that we want to use in our application.
Manifest XML File

This XML le is used to dene all the components of our


application
It includes the names of our application packages, Activities,
Receievers, Services and the permission that our application
needed
Suppose we need to use the internet in our app then we need
to dene Internet permission in this le
AndroidManifest.xml le
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/
apk/res/android"
package="example.abhiandroid.MyApplication"> <!--
application package name -->
<uses-permission android:name="ANDROID.PERMISSION.
INTERNET" />
<!-- define Internet Permission -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<!-- add your Activities, Receivers, Services Names
Here -->
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.
LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Strings XML File

This XML le is used to replace hard-coded strings.


We dene all the strings in this XML le and then access them
in our Layout XML les
Strings.xml

<resources>
<string name="app_name">My Application</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="login">User Login</string>
<!-- define your strings here -->
</resources>
Styles XML File

This XML is used to dene dierent styles and looks for the UI of
application.
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.
DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
Color XML File

This le is used to dene the color codes that we use in our app.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- define your colors Here -->
<color name="greenColor">#0f0</color>
<color name="white">#fff</color>
</resources>
Dimension XML File

This XML is used to dene the dimensions of the Views.


dimens.xml File

<resources>
<!-- Default screen margins, per the Android Design
guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen><
dimen name="btnheight">50dp</dimen>
</resources>
TextView

Attributes of TextView
padding
text
textColor
textSize
textStyle
Example of TextView

<TextView
android:id="@+id/firstTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_margin="20dp"
android:padding="10dp"
android:text="First Text View"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
Android Application Lifecycle
Android Application Life-Cycle
Android Application Life-Cycle

onCreate() - called when the activity is rst created


Android Application Life-Cycle

onCreate() - called when the activity is rst created

onStart() - called when the activity becomes visible to the user


Android Application Life-Cycle

onCreate() - called when the activity is rst created

onStart() - called when the activity becomes visible to the user

onResume() - called when the activity starts interacting with


the user
Android Application Life-Cycle

onCreate() - called when the activity is rst created

onStart() - called when the activity becomes visible to the user

onResume() - called when the activity starts interacting with


the user

Process specic events(such as launching activities, dialing


phone etc.)
Android Application Life-Cycle

onCreate() - called when the activity is rst created

onStart() - called when the activity becomes visible to the user

onResume() - called when the activity starts interacting with


the user

Process specic events(such as launching activities, dialing


phone etc.)

onPause() - called when the current activity is being paused


and the previous activity is resumed
Android Application Life-Cycle
Android Application Life-Cycle

onStop() - called when the activity is no longer visible to the


user
Android Application Life-Cycle

onStop() - called when the activity is no longer visible to the


user

onDestroy() - called before the activity is destroyed by the


system
Android Application Life-Cycle

onStop() - called when the activity is no longer visible to the


user

onDestroy() - called before the activity is destroyed by the


system

onRestart() - called when the activity has been stopped and is


restarting again
Android Activity Life-Cycle
Linear Layout
Linear Layout

Linear layout is a simple layout in Android for desujgning User


Interface
All the elements are displayed in linear fashion according to its
orientation
Linear Layout Horizontal
Linear Layout Vertical
Main Attributes in Linear Layout

orientation
This attribute is used to set childs/views horizontally or
vertically.
gravity
Used to control the alignment of the layout like left, right,
center, top, bottom etc.
layout_weight
The layout weight attribute specify each child control's relative
importance within the parent linear layout
Linear Layout with gravity=Right
Linear Layout layout_weight=2
Linear Layout without layout_weight
Linear Layout without layout_weight
android.widget.Relative Layout
Relative Layout

Relative Layout is a exible Layout


used to position UI components based on relative sibling or
parent's position
can use above another UI item, below, left, right of other item
RelativeLayout
Positions the bottom edge of this
android:layout_above view above the given anchor view
ID.
Positions the baseline of this view
android:layout_alignBaseline on the baseline of the given anchor
view ID
Makes the bottom edge of this
android:layout_alignBottom view match the bottom edge of the
given anchor view ID.
Makes the end edge of this view
android:layout_alignEnd match the end edge of the given
anchor view ID
Makes the left edge of this view
android:layout_alignLeft match the left edge of the given
anchor view ID
If true, makes the bottom edge of
android:layout_alignParentBottomthis view match the bottom edge
of the parent
RelativeLayout
If true, makes the end edge of this
android:layout_alignParentEnd view match the end edge of the
parent
If true, makes the left edge of this
android:layout_alignParentLeft view match the left edge of the par-
ent
If true, makes the right edge of this
android:layout_alignParentRight view match the right edge of the
parent
If true, makes the start edge of this
android:layout_alignParentStart view match the start edge of the
parent
If true, makes the top edge of this
android:layout_alignParentTop view match the top edge of the par-
ent
Makes the right edge of this view
android:layout_alignRight match the right edge of the given
anchor view ID
RelativeLayout
Makes the start edge of this view
android:layout_alignStart match the start edge of the given
anchor view ID
Makes the top edge of this view
android:layout_alignTop match the top edge of the given
anchor view ID
If set to true, the parent will be
android:layout_alignWithParentIfMissing
used as the anchor when the an-
chor cannot be be found for lay-
out_toLeftOf, layout_toRightOf,
etc
Positions the top edge of this view
android:layout_below below the given anchor view ID
If true, centers this child horizon-
android:layout_centerHorizontal tally within its parent
If true, centers this child horizon-
android:layout_centerInParent tally and vertically within its parent
RelativeLayout

If true, centers this child vertically


android:layout_centerVertical within its parent
Positions the start edge of this view
android:layout_toEndOf to the end of the given anchor view
ID
Positions the right edge of this view
android:layout_toLeftOf to the left of the given anchor view
ID
Positions the left edge of this view
android:layout_toRightOf to the right of the given anchor
view ID
Positions the end edge of this view
android:layout_toStartOf to the start of the given anchor
view ID
RelativeLayout

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


<RelativeLayout
android:id="@+id/RLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/lblComments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Comments"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
RelativeLayout

<EditText
android:id="@+id/txtComments"
android:layout_width="match_parent"
android:layout_height="170px"
android:textSize="18sp"
android:layout_alignLeft="@+id/lblComments"
android:layout_below="@+id/lblComments"
android:layout_centerHorizontal="true"/>
<Button
android:id="@+id/btnSave"
android:layout_width="125px"
android:layout_height="wrap_content"
android:text="Save"
android:layout_below="@+id/txtComments"
android:layout_alignRight="@+id/txtComments"/>
RelativeLayout

<Button
android:id="@+id/btnCancel"
android:layout_width="124px"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_below="@+id/txtComments"
android:layout_alignLeft="@+id/txtComments"/>
</RelativeLayout>
Practice Questions
Practice Questions

1 Develop an App for understanding an Activity Life Cycle. The


life cycle methods have to be shown both on screen and in Log.
Practice Questions

1 Develop an App for understanding an Activity Life Cycle. The


life cycle methods have to be shown both on screen and in Log.

2 Develop an App for showing three buttons vertically. The


width of the buttons should be just enough to display its text.
The height of the three buttons should be in the ratio 1:2:3.
Practice Questions

1 Develop an App for understanding an Activity Life Cycle. The


life cycle methods have to be shown both on screen and in Log.

2 Develop an App for showing three buttons vertically. The


width of the buttons should be just enough to display its text.
The height of the three buttons should be in the ratio 1:2:3.

3 Develop an Activity for Login Screen. Use Relative Layout.


android.widget.TableLayout
TableLayout
TableLayout

groups views into rows and columns


TableLayout

groups views into rows and columns

use <TableRow> element to designate a row


Table Layout
TableLayout

<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent" >
<TableRow>
<TextView
android:text="User Name:"
android:width ="120dp"/>
<EditText
android:id="@+id/txtUserName"
android:width="200dp" /> </TableRow>
TableLayout

<TableRow>
<TextView
android:text="Password:"/ >
<EditText
android:id="@+id/txtPassword"
android:password="true" />
</TableRow>
<TableRow>
<TextView/ >
<CheckBox
android:id="@+id/chkRememberPassword"
android:layout_width="match_parent" />
android:layout_height="wrap_content" />
android:text="Remember Password" />
</TableRow>
TableLayout

<TableRow>
<Button
android:id="@+id/buttonSignIn"
android:text="Log In"/ >
</TableRow>
Attributes of TableLayout

id attribute is used to uniquely identify a Table Layout.


<TableLayout
android:id="@+id/simpleTableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent/>
Attributes of TableLayout

stretchColumns
Stretch column attribute is used to stretch columns to take up
available free space. The value that assigned to this attribute can
be a single column number or a comma delimited list of column
numbers (1, 2, 3...n).
If the value is 1 then the second column is stretched to take up any
available space in the row, because of the column numbers are
started from 0.
If the value is 0,1 then both the rst and second columns of table
are stretched to take up the available space in the row.
If the value is `*' then all the columns are stretched to take up the
available space.
Attributes of TableLayout

shrinkColumns
Shrink column attribute is used to shrink or reduce the width of the
column`s. We can specify either a single column or a comma
delimited list of column numbers for this attribute. The content in
the specied columns word-wraps to reduce their width.
If the value is 0 then the rst column's width shrinks or reduces by
word wrapping its content.
If the value is 0,1 then both rst and second columns are shrinks or
reduced by word wrapping its content.
If the value is `*' then the content of all columns is word wrapped
to shrink their widths.
Attributes of TableLayout

collapseColumns
collapse columns attribute is used to collapse or make invisible the
UI elements of a table layout. These columns are the part of the
table information but are invisible.
If the values is 0 then the rst column appears collapsed, i.e it is
the part of table but it is invisible.
android.widget.FrameLayout
Frame Layout

used to block an area on the screen


If multiple views are put, then overlaps each other
FrameLayout example 1

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


<FrameLayout 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">

<ImageView android:id="@+id/imv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/photo"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
</FrameLayout>
FrameLayout example 2

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


<FrameLayout xmlns:android="http://schemas.android.
com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<TextView android:text="LeftTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="RightTop"
android:layout_gravity="top|right" />
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="CentreTop"
android:layout_gravity="top|center_horizontal
" />
<TextView android:text="Left"
android:layout_gravity="left|center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Right"
android:layout_gravity="right|center_vertical
" />
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Centre"
android:layout_gravity="center" />
<TextView android:text="LeftBottom"
android:layout_gravity="left|bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="RightBottom"
android:layout_gravity="right|bottom" />
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="CenterBottom"
android:layout_gravity="center|bottom" />
</FrameLayout>
Units of Measurement
Units of Measurement
Units of Measurement

dp - Density-independent pixel. 1 dp is equivalent to one pixel


on a 160 dpi screen. This is the recommended unit of
measurement when specifying the dimension of views in your
layout. The 160 dpi screen is the baseline density assumed by
Android. You can specify either "dp" or "dip" when referring
to a density-independent pixel.
Units of Measurement

dp - Density-independent pixel. 1 dp is equivalent to one pixel


on a 160 dpi screen. This is the recommended unit of
measurement when specifying the dimension of views in your
layout. The 160 dpi screen is the baseline density assumed by
Android. You can specify either "dp" or "dip" when referring
to a density-independent pixel.
sp - Scale-independent pixel. This is similar to dp and is
recommended for specifying font sizes.
Units of Measurement

dp - Density-independent pixel. 1 dp is equivalent to one pixel


on a 160 dpi screen. This is the recommended unit of
measurement when specifying the dimension of views in your
layout. The 160 dpi screen is the baseline density assumed by
Android. You can specify either "dp" or "dip" when referring
to a density-independent pixel.
sp - Scale-independent pixel. This is similar to dp and is
recommended for specifying font sizes.
pt - Point. A point is de ned to be 1/72 of an inch, based on
the physical screen size.
Units of Measurement

dp - Density-independent pixel. 1 dp is equivalent to one pixel


on a 160 dpi screen. This is the recommended unit of
measurement when specifying the dimension of views in your
layout. The 160 dpi screen is the baseline density assumed by
Android. You can specify either "dp" or "dip" when referring
to a density-independent pixel.
sp - Scale-independent pixel. This is similar to dp and is
recommended for specifying font sizes.
pt - Point. A point is de ned to be 1/72 of an inch, based on
the physical screen size.
px - Pixel. Corresponds to actual pixels on the screen. Using
this unit is not recommended, as your UI may not render
correctly on devices with a dierent screen resolution.
Screen densities

Android denes and recognizes four screen densities:


Low density (ldpi) - 120 dpi

Medium density (mdpi) - 160 dpi

High density (hdpi) - 240 dpi

Extra High density (xhdpi) - 320 dpi


Some examples
Some examples

Nexus S is regarded as a hdpi device, as its pixel density is


closest to 240 dpi.
Some examples

Nexus S is regarded as a hdpi device, as its pixel density is


closest to 240 dpi.

The HTC Hero, however, has a 3.2-inch (diagonal) screen size


and a resolution of 320× 480. Its pixel density works out to be
about 180 dpi. Therefore, it would be considered an mdpi
device, as its pixel density is closest to 160 dpi.
How to convert dp to px

The formula for converting dp to px (pixels) is as follows:

Actual pixels = dp ∗ 160


dpi
, where dpi is either 120, 160, 240, or 320.
ConstraintLayout
ConstraintLayout

exible layout
allows at views with no hierarchy
hence improves performance(layout load time)
released in Google I/O 2016
similar to RelativeLayout
Design and BluePrint view in layout Design
Using Constraint Layout in Android Studio

It is not bundled as part of Android SDK


available as a support library
repositories {
maven {
url ’https://maven.google.com’
}
}
dependencies {
compile ’com.android.support.constraint:
constraint-layout:1.1.0-beta3’
}
ConstraintLayout

To dene a view's position in ConstraintLayout, you must add


at least one horizontal and one vertical constraint for the view
Each constraint denes the view's position along either the
vertical or horizontal axis
If a view has no constraints when you run your layout on a
device, it is drawn at position [0,0] (the top-left corner)
missing constraint won't cause a compilation error
ConstraintLayout

Figure: The editor shows view C below A, but it has no vertical constraint
ConstraintLayout

Figure: View C is now vertically constrained below view A


To use ConstraintLayout in Project
To use ConstraintLayout in Project

1 Ensure maven.google.com repository declared in build.gradle


le
repositories {
google()
}
To use ConstraintLayout in Project

1 Ensure maven.google.com repository declared in build.gradle


le
repositories {
google()
}

2 Add the library as a dependency in the same build.gradle le.


dependencies {
implementation ’com.android.support.
constraint:constraint-layout:1.1.2’
}
To use ConstraintLayout in Project

1 Ensure maven.google.com repository declared in build.gradle


le
repositories {
google()
}

2 Add the library as a dependency in the same build.gradle le.


dependencies {
implementation ’com.android.support.
constraint:constraint-layout:1.1.2’
}

3 In the toolbar or sync notication, click Sync Project with


Gradle Files
Adding a Constraint

Moview
Creating a Constraint

Figure: The Layout section of the Attributes window lets you create
connections
Delete a Constraint

To delete a constraint press Ctrl+click on a constraint


Figure: A horizontal constraint to the parent
Figure: A horizontal and vertical constraint
Figure: A horizontal alignment constraint
Figure: An oset horizontal alignment constraint
Baseline alignment

Figure: A baseline alignment constraint


Constrain to a guideline

You can add a vertical or horizontal guideline to which you can


constrain views, and the guideline will be invisible to app users. To
create a guideline, click Guidelines and then click either Add
Vertical Guideline or Add Horizontal Guideline.
Constrain to a guideline

You can add a vertical or horizontal guideline to which you can


constrain views, and the guideline will be invisible to app users. To
create a guideline, click Guidelines and then click either Add
Vertical Guideline or Add Horizontal Guideline.
Constrain to a barrier

A barrier is an invisible line that can constrain views to it.


A barrier does not dene its own position; instead the barrier
position moves based on the views contained within it.
This is useful when you want to constrain to a set of views
rather than one specic view
Click Guidelines in the toolbar, and then click Add Vertical
Barrier or Add Horizontal Barrier
Figure: View C is constrained to a barrier, which moves based on the
position/size of both view A and view B
Adjusting the Constraint bias

Adjust constraint bias


Adjust the View Size

Figure: Attributes window includes controls for 1. size ratio, 2. deleting


constraints, 3. height/width mode, 4. margins and 5. constraint bias
Control linear groups with a Chain

A chain is a group of views that are linked to each other with


bi-directional position constraints.
The views within a chain can be distributed either horizontally
or vertically
Figure: A horizontal chain with two views
Figure: Examples of chain style 1. Spread 2.Spread_inside 3. Weighted
4. Packed
Chain styles

1 Spread: The views are evenly distributed(after margins are


accounted for). This is the default.
2 Spread inside: The rst and last view are axed to the
constraints on each end of the chain and the rest are evenly
distributed
3 Weighted: by setting layout_constraintHorizontal_weight and
layout_constraintVertical_weight
4 Packed: The views are packed together(after margins are
accounted for). You can adjust the whole chain's
bias(left/right or up/down) by changing the chai's head view
bias.
Intents and Intent Filters
Intents

Intent is a messaging object to request action from another


app component
startActivity() or startActivityForResult()
the result is obtained as a separate Intent object in activity's
onActivityResult() callback
used also in startService() or sendBroadcast()
Intents

starting an activity
starting a service(performs operations in the background)
delivering a broadcast
Intent types

Explicit intents
You'll typically use an explicit intent to start a component in
your own app, because you know the class name of the activity
or service you want to start
Implicit intents
do not name a specic component, but instead declare a
general action to perform, which allows a component from
another app to handle it. For e.g. user location in a map
Intent lter

Intent lter is an expression in an app's manifest le that species


the type of intents that the component would like to receive.
if you do not declare any intent lters for an activity, then it can be
started only with an explicit intent.
Implicit Intents

Intents might require data in the form of URI, or some other form
or no data at all
Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL,
number);
Implicit Intents

Uri location =
Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+
Mountain+View,+California");
// Or map point based on latitude/longitude
// Uri location = Uri.parse("geo
:37.422219,-122.08364?z=14"); //
z param is zoom level
Intent mapIntent = new Intent(Intent.ACTION_VIEW,
location);
Implicit Intents

Uri webpage = Uri.parse("http://www.facebook.com");


Intent webIntent = new Intent(Intent.ACTION_VIEW,
webpage);
Spinner, ListView
resources/strings.xml

<resources>
<string name="app_name">AppWithSpinnerDemo</
string>
<string-array name="states">
<item>Assam</item>
<item>Bihar</item>
<item>Chattisgadh</item>
<item>Delhi</item>
<item>Goa</item>
</string-array>
</resources>
activity_main.xml

Include Spinner UI component in the XML le.


<Spinner

android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
MainActivity.java I

package com.xyz.appwithspinnerdemo;

import android.widget.ArrayAdapter;
import android.widget.Spinner;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState
) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sp=(Spinner)findViewById(R.id.spinner);
states=getResources().getStringArray(R.array.
states);

aa=new ArrayAdapter<String>(this,android.R.
layout.simple_spinner_item,states);
aa.setDropDownViewResource(android.R.layout.
simple_spinner_dropdown_item);
sp.setAdapter(aa);
MainActivity.java II

}
public void onClick(View v)
{
Toast.makeText(this,"Your state is "+sp.
getSelectedItem(), Toast.LENGTH_LONG).show
();
}
ListView
activity_main.xml

Include Spinner UI component in the XML le.


<ListView
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:divider="@color/green"
android:listSelector="@color/green"
android:dividerHeight="2dp"/>

<Button
android:onClick="onClick"
android:text="Register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
MainActivity.java I

package com.xyz.spinnerdemo;

import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity


implements AdapterView.OnItemClickListener {

private String countries[]={"India","Russia","


Nepal","Sri Lanka"};
private ListView sp;
private ArrayAdapter<String> aa;
@Override
protected void onCreate(Bundle savedInstanceState
) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.java II
sp=(ListView)findViewById(R.id.spinner);
aa=new ArrayAdapter<String>(this,android.R.
layout.simple_spinner_item,getResources().
getStringArray(R.array.countries));
//aa.setDropDownViewResource(android.R.layout
.simple_spinner_dropdown_item);
sp.setAdapter(aa);
sp.setOnItemClickListener(this);
}
protected void onClick(View v) {
Toast.makeText(this,"Selected item is "+sp.
getSelectedItem(),Toast.LENGTH_LONG).show
();
}
public void onItemClick(AdapterView<>v,View v2,
int i,long l){

}
}
Threads
Threads
Threads

Application creates a thread of execution called main thread


Threads

Application creates a thread of execution called main thread

it is also called UI thread because through this thread system


interacts with UI components
Threads

Application creates a thread of execution called main thread

it is also called UI thread because through this thread system


interacts with UI components

system does not create separate threads for components


Time Consuming tasks

When performing intensive work single thread model can yield poor
performance
Time Consuming tasks

When performing intensive work single thread model can yield poor
performance

Performing long operations such as network access or database


queries will block the whole UI.
Time Consuming tasks

When performing intensive work single thread model can yield poor
performance

Performing long operations such as network access or database


queries will block the whole UI.

When the thread is blocked, no events can be dispatched


Time Consuming tasks

When performing intensive work single thread model can yield poor
performance

Performing long operations such as network access or database


queries will block the whole UI.

When the thread is blocked, no events can be dispatched

From the user's perspective application appears to hang


Time Consuming tasks

When performing intensive work single thread model can yield poor
performance

Performing long operations such as network access or database


queries will block the whole UI.

When the thread is blocked, no events can be dispatched

From the user's perspective application appears to hang

The user might quit and uninstall


An example

public void buttonClick(View view)


{
long endTime = System.currentTimeMillis() +
20*1000;

while (System.currentTimeMillis() < endTime) {


synchronized (this) {
try {
wait(endTime - System.currentTimeMillis())
;
} catch (Exception e) {
}
}
}
TextView myTextView = (TextView)findViewById(R.id
.myTextView);
myTextView.setText("Button Pressed");
}
Two simple rules

Android UI toolkit is not thread safe.


Two simple rules

Android UI toolkit is not thread safe.

Should not manipulate UI from a worker thread.


Two simple rules

Android UI toolkit is not thread safe.

Should not manipulate UI from a worker thread.

Two simple rules


Two simple rules

Android UI toolkit is not thread safe.

Should not manipulate UI from a worker thread.

Two simple rules


1 Do not block the UI thread
Two simple rules

Android UI toolkit is not thread safe.

Should not manipulate UI from a worker thread.

Two simple rules


1 Do not block the UI thread
2 Do not access the Android UI toolkit from outside the UI
thread
Worker Threads

public void onClick(View v) {


new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://
example.com/image.png");
mImageView.setImageBitmap(b);
}
}).start();
}

It violates the second rule.


Solution

To x this problem, Android oers several ways to access the UI


thread from other threads. Here is a list of methods that can help:
Solution

To x this problem, Android oers several ways to access the UI


thread from other threads. Here is a list of methods that can help:

Activity.runOnUiThread(Runnable)
Solution

To x this problem, Android oers several ways to access the UI


thread from other threads. Here is a list of methods that can help:

Activity.runOnUiThread(Runnable)
View.post(Runnable)
Solution

To x this problem, Android oers several ways to access the UI


thread from other threads. Here is a list of methods that can help:

Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
Fix

For example, you can x the above code by using the


View.post(Runnable) method:
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap =
loadImageFromNetwork("http://
example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap)
;
}
});
}
}).start();
}
Handler
Handler Object

import android.os.Handler;
import android.os.Message;

public class ThreadExample extends Activity {

Handler handler = new Handler() {


@Override
public void handleMessage(Message msg) {
TextView myTextView =
(TextView)findViewById(R.id.
myTextView);
myTextView.setText("Button Pressed");
}
};
public void buttonClick(View view)
{

Runnable runnable = new Runnable() {


public void run() {

long endTime = System.currentTimeMillis()


+ 20*1000;

while (System.currentTimeMillis() <


endTime) {
synchronized (this) {
try {
wait(endTime - System.
currentTimeMillis());
} catch (Exception e) {}
}

}
handler.sendEmptyMessage(0);
}
};

Thread mythread = new Thread(runnable);


AyncTask
AyncTask
AyncTask

AsyncTask enables proper and easy use of the UI thread.


AyncTask

AsyncTask enables proper and easy use of the UI thread.

allows to perform background operations and publish results


on the UI thread
AyncTask

AsyncTask enables proper and easy use of the UI thread.

allows to perform background operations and publish results


on the UI thread

No manipulation of Threads / handlers


AsyncTask
AsyncTask

computation runs in worker thread


AsyncTask

computation runs in worker thread

result is published on the UI thread


AsyncTask

computation runs in worker thread

result is published on the UI thread

dened by three generic types called Params, Progress and


Result
AsyncTask

computation runs in worker thread

result is published on the UI thread

dened by three generic types called Params, Progress and


Result
four steps called onPreExecute,
doInBackground,onProgressUpdate and onPostExecute
An Example
public void onClick(View v) {
new DownloadImageTask().execute("http://example.
com/image.png");
}

private class DownloadImageTask extends AsyncTask<


String, Void, Bitmap> {
/** The system calls this to perform work in a
worker thread and
* delivers it the parameters given to AsyncTask
.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}

/** The system calls this to perform work in the


UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
Another Example
private class DownloadFilesTask extends AsyncTask<URL
, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(
urls[i]);
publishProgress((int) ((i / (float)
count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}

protected void onProgressUpdate(Integer...


progress) {
setProgressPercent(progress[0]);
}

protected void onPostExecute(Long result) {


Menus
Menus

menus are common user interface components


Beginning with Android 3.0 (API level 11), Android-powered
devices are no longer required to provide a dedicated Menu
button.
Types of menus

Option menu and app bar


The options menu is the primary collection of menu items for
an activity. It's where you should place actions that have a
global impact on the app, such as "Search," "Compose
email," and "Settings."
Context menu and contextual action mode
A context menu is a oating menu that appears when the user
performs a long-click on an element. It provides actions that
aect the selected content or context frame. The contextual
action mode displays action items that aect the selected
content in a bar at the top of the screen and allows the user to
select multiple items.
Types of menus

Popup menu
A popup menu displays a list of items in a vertical list that's
anchored to the view that invoked the menu. It's good for
providing an overow of actions that relate to specic content
or to provide options for a second part of a command. Actions
in a popup menu should not directly aect the corresponding
content-that's what contextual actions are for. Rather, the
popup menu is for extended actions that relate to regions of
content in your activity.
Dening a menu in XML

For all menu types, Android provides a standard XML format to


dene menu items. Instead of building a menu in your activity's
code, you should dene a menu and all its items in an XML menu
resource. You can then inate the menu resource (load it as a
Menu object) in your activity
Menus in XML

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


<menu xmlns:android="http://schemas.android.com/apk/
res/android">
<item android:id="@+id/new_game"
android:icon="@drawable/ic_new_game"
android:title="@string/new_game"
android:showAsAction="ifRoom"/>
<item android:id="@+id/help"
android:icon="@drawable/ic_help"
android:title="@string/help" />
</menu>
Adding Submenus

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


<menu xmlns:android="http://schemas.android.com/apk/
res/android">
<item android:id="@+id/file"
android:title="@string/file" >
<!-- "file" submenu -->
<menu>
<item android:id="@+id/create_new"
android:title="@string/create_new"
/>
<item android:id="@+id/open"
android:title="@string/open" />
</menu>
</item>
</menu>
Adding menu to Activity

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true;
}
handling Option menu

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Context Menu
Creating a Context Menu
1 Register the View to which the context menu should be
associated by calling registerForContextMenu() and pass it the
View.
If your activity uses a ListView or GridView and you want each
item to provide the same context menu, register all items for a
context menu by passing the ListView or GridView to
registerForContextMenu().
2 @Override
public void onCreateContextMenu(ContextMenu menu,
View v,
ContextMenuInfo
menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
3 @Override
public boolean onContextItemSelected(MenuItem
item) {
AdapterContextMenuInfo info = (
AdapterContextMenuInfo) item.getMenuInfo
();
switch (item.getItemId()) {
case R.id.edit:
editNote(info.id);
return true;
case R.id.delete:
deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(
item);
}
}
Notications
Notications

A notication is a message one can display to the user outside of


application's normal UI.
Notications

A notication is a message one can display to the user outside of


application's normal UI.

When you tell the system to issues a notication, it rst appears as


an icon in the notication area.
Notications

A notication is a message one can display to the user outside of


application's normal UI.

When you tell the system to issues a notication, it rst appears as


an icon in the notication area.

To see the details of the notication, the user opens the


notication drawer.
Notications

Both the notication area and the notication drawer are


system-controlled areas that the user can view at any time.
Notication Area
Notication Drawer
Creating a Notication

We use NoticationCompat.Builder class introduced in version 4.


The class Notication.Builder was added in Android 3.0
The UI information and actions for a notication in a
NoticationCompat.Builder object.
To create the notication call
NoticationCompat.Builder.build() which returns a
Notication object.
To issue the notication, pass the Notication object to the
system by calling NoticationManager.notify().
Required Notication Contents

A Notication object must contain the following


A small icon, set by setSmallIcon()
A title, set by setContentTitle()
Detailed text, set by setContentText()
Notication Actions

You should add atelast one action to your notication.


Notication Actions

You should add atelast one action to your notication.

An action allows users to go directly from the notication to an


Activity in your application, where they can look at one or more
events or do further work.
Notication Actions

You should add atelast one action to your notication.

An action allows users to go directly from the notication to an


Activity in your application, where they can look at one or more
events or do further work.

You can also add buttons to the notication that perform


additional actions such as snoozing an alarm or responding
immediately to a text message
Notication actions

Inside a Notication, the action is dened by a PendingIntent


containing an Intent that starts an Activity in your application.
Notication actions

Inside a Notication, the action is dened by a PendingIntent


containing an Intent that starts an Activity in your application.

If you want to start Activity when the user clicks the notication
text in the notication drawer, you add the PendingIntent by calling
setContentIntent().
An example

NotificationCompat.Builder mBuilder = new


NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle(textTitle)
.setContentText(textContent)
.setPriority(NotificationCompat.
PRIORITY_DEFAULT);
Notication Channel
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES
.O) {
CharSequence name = getString(R.string.
channel_name);
String description = getString(R.string.
channel_description);
int importance = NotificationManager.
IMPORTANCE_DEFAULT;
NotificationChannel channel = new
NotificationChannel(CHANNEL_ID, name,
importance);
channel.setDescription(description);
NotificationManager notificationManager =
getSystemService(NotificationManager.class
);
notificationManager.createNotificationChannel
(channel);
}
}
// Create an explicit intent for an Activity in your
app
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.
getActivity(this, 0, intent, 0);

NotificationCompat.Builder mBuilder = new


NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.............
.setContentIntent(pendingIntent)
.setAutoCancel(true);
Broadcast Receivers
Broadcast Receivers

Respond to broadcast messages from other applications or


from the sytem
Applications can also initiate broadcasts to other application
Broadcast receiver will interept this communication and will
initiate appropriate action
Creating a Broadcast Receiver

A broadcast receiver is implemented as a subclass of


BroadcastReceiver class, where each message is received as a Intent
object parameter.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent
intent) {
Toast.makeText(context, "Intent Detected.",
Toast.LENGTH\_LONG).show();
}
}
Broadcast Receiver
Registering Broadcast Receiver

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">

<intent-filter>
<action android:name="android.intent.action.
BOOT_COMPLETED">
</action>
</intent-filter>

</receiver>

</application>
Standard Broadcast Actions I
Action Description
ACTION_TIME_TICK The current time has changed.
Sent every minute. You cannot
receive this through components
declared in manifests, only by ex-
plicitly registering for it with Con-
text#registerReceiver(BroadcastRec
IntentFilter).
ACTION_TIME_CHANGED The time was set
ACTION_TIMEZONE_CHANG The timezone has changed
ED
ACTION_BOOT_COMPLETED This is broadcast once, after
the user has nished boot-
ing. You must hold the Mani-
fest.permission.RECEIVE_BOOT_C
permission in order to receive this
broadcast.
Standard Broadcast Actions II
Action Description
ACTION_PACKAGE_ADDED A new application package has
been installed on the device.
ACTION_PACKAGE_CHANGE An existing application package
D has been changed (for example,
a component has been enabled or
disabled).
ACTION_PACKAGE_REMOVE An existing application package
D has been removed from the device.
ACTION_PACKAGE_RESTAR The user has restarted a package,
TED and all of its processes have been
killed.
ACTION_PACKAGE_DATA_C The user has cleared the data of a
LEARED package
ACTION_PACKAGES_SUSPEN Packages have been suspended
DED
Standard Broadcast Actions III

Action Description
ACTION_PACKAGES_UNSUS Packages have been unsuspended
PENDED
ACTION_UID_REMOVED A user ID has been removed from
the system
ACTION_BATTERY_CHANGE This is a sticky broadcast contain-
D ing the charging state, level, and
other information about the bat-
tery
ACTION_POWER_CONNECTE External power has been con-
D nected to the device
ACTION_POWER_DISCONNE External power has been removed
CTED from the device
ACTION_SHUTDOWN Device is shutting down
Broadcasting Custom Intents

If the application has to generate and send custom intents then you
will have to create and send intents by using sendBroadcast()
method.
public void broadcastIntent(View view)
{
Intent intent = new Intent();
intent.setAction("com.mahe.example.CUSTOM_INTENT")
;
sendBroadcast(intent);
}
Registering Custom BroadcastReceiver

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">

<intent-filter>
<action android:name="com.mahe.example.
CUSTOM_INTENT">
</action>
</intent-filter>

</receiver>
</application>
Telephony and SMS APIs
How to make a Phone call

Intent intent = new Intent(Intent.ACTION_DIAL);


intent.setData(Uri.parse("tel:" + number));
startActivity(intent);
How to make a Phone call

Intent intent = new Intent(Intent.ACTION_DIAL);


intent.setData(Uri.parse("tel:" + number));
startActivity(intent);

No need of permission
How to place a Call directly

Add the following permission


<uses-permission android:name=
"android.permission.CALL_PHONE"></uses-permission>
How to place a Call directly

Add the following code


public void dialPhone(View view){
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:0123456789"));
startActivity(intent);
}
SMS Messages
Sending SMS Messages

<uses-permission android:name=
"android.permission.SEND_SMS"/>
Sending SMS Messages

SmsManager smsManager = SmsManager.getDefault();


smsManager.sendTextMessage(phoneNumber, null, msg,
null, null);
Services
Services

long running tasks in background


does not provide a user interface
is an application component
continues to run in background even if the user switches to
another application
a component can bind to a service to interact with it and even
perform interprocess communication(IPC)
a service can be designed for handling network transactions,
play music, perform le I/O or interact with a content provider
all from the background
Types of Services

There are three types of services.


Foreground service
operation is visible to the user e.g. audio app

Bacground service
operation is not noticed by the user e.g. compression app

Bound service
application component binds by calling bindService()
oers a client-server interface
Service

onStartCommand() and onBind()


manifest.xml <service android:name=".ExampleService" />
android:exported="true" or "false"
A bound service allows components to interact with the service
send requests
receive results
even do so across processes with interprocess communication
a bound service runs only as long as another application is
bound to it
Scenario

perform work outside of your main thread, but only while the user
is interacting with your application
onCreate()
onStart(),onStop()
To Create a Service

create a subclass of android.app.Service


override few callback methods
onStartCommand() - will run indenitely, stopSelf(),
stopService()
onBind() - bindService(), return IBinder, otherwise return null
onCreate() - setup
onDestroy() - clean up
Create Service

extend android.app.Service - create a new thread in onCreate()


android.app.IntentService - uses a worker thread to handle all
of the start requests, one at a time
implement onHandleIntent() which receives the intent for each
start request
android.app.IntentService

The IntentService class does the following:


It creates a default worker thread that executes all of the
intents that are delivered to onStartCommand(), separate from
your application's main thread.
Creates a work queue that passes one intent at a time to your
onHandleIntent() implementation, so you never have to worry
about multi-threading.
Stops the service after all of the start requests are handled, so
you never have to call stopSelf().
Provides a default implementation of onBind() that returns
null.
Provides a default implementation of onStartCommand() that
sends the intent to the work queue and then to your
onHandleIntent() implementation.
public class HelloIntentService extends IntentService
{

/**
* A constructor is required, and must call the
super IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
}

/**
* The IntentService calls this method from the
default worker thread with
* the intent that started the service. When this
method returns, IntentService
* stops the service, as appropriate.
*/
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like
download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
}
}
call super

@Override
public int onStartCommand(Intent intent, int flags,
int startId) {
Toast.makeText(this, "service starting", Toast.
LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId)
;
}
Extending the android.app.Service class
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;

// Handler that receives messages from the thread


private final class ServiceHandler extends Handler
{
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// Normally we would do some work here,
like download a file.
// For our sample, we just sleep for 5
seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so
that we don’t stop
// the service in the middle of handling
another job
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note
that we create a
// separate thread because the service normally
runs in the process’s
// main thread, which we don’t want to block. We
also make it
// background priority so CPU-intensive work
doesn’t disrupt our UI.
HandlerThread thread = new HandlerThread("
ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();

// Get the HandlerThread’s Looper and use it for


our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(
mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags,
int startId) {
Toast.makeText(this, "service starting", Toast.
LENGTH_SHORT).show();

// For each start request, send a message to


start a job and deliver the
// start ID so we know which request we’re
stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);

// If we get killed, after returning from here,


restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don’t provide binding, so return null
return null;
}

@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.
LENGTH_SHORT).show();
}
}
Service Lifecycle
Declaring a Service in manifest

<manifest ... >


...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>
Service classes

Service
This is the base class for all services
it's important to create a new thread in this
otherwise uses your application's main thread by default
it can slow the performance of any activity
Service classes

IntentService
this is a subclass of Service that uses a worker thread
it handles all of the start requests, one at a time
this is the best option if you don't require that your service
handle multiple requests simultaneously
implement onHandleIntent(), which receives the intent for each
start request so that you can complete the background work
Service Example

public class CounterService extends Service {


private boolean keepCounting=false;
int count=0;

@Override
public void onCreate() {
super.onCreate();
Log.i("Service Lifecycle","onCreate called");
}
@Override
public int onStartCommand(Intent in, int flags, int
startId) {
Log.i("Service Lifecycle","onStartCommand called"
);
keepCounting=true;
count=0;
new Thread(new Runnable() {
@Override
public void run() {
while(keepCounting) {
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
count++;
Log.i("CounterStatus","Time elapsed since
service started "+count+" seconds");
}
}
}).start();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("Service Lifecycle","onDestroy called");
count=0;
keepCounting=false;
}
Return value of onStartCommand()

START_STICKY
If the system kills the service after onStartCommand() returns,
recreate the service and call onStartCommand(), but do not
redeliver the last intent.
START_NOT_STICKY
If the system kills the service after onStartCommand() returns,
do not recreate the service unless there are pending intents to
deliver.
START_REDELIVER_INTENT
If the system kills the service after onStartCommand() returns,
recreate the service and call onStartCommand() with the last
intent that was delivered to the service.
Starting and Stopping the Service

Intent in=new Intent(this, CounterServicce.class)


;\\[0.5cm]

startService(in); or startForegroundService()\\[0.5cm
]

stopService(in);
IntentService
IntentService example

public class CounterService extends IntentService {


private boolean keepCounting=false;
int count=0;

public CounterService() {
super("CounterService");
}

@Override
protected void onHandleIntent(Intent arg0) {
keepCounting=true;
count=0;
while(keepCounting) {
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
count++;
Log.i("CounterStatus","Time elapsed since
service started "+count+" seconds");
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("Service Lifecycle","onDestroy called");
count=0;
keepCounting=false;
}
}
Bound Services
Service Lifecycle
CounterService with Local binding

public class CounterService extends Service {


boolean keepCounting=false;
int count=0;
@Override
public IBinder onBind(Intent in) {
startCount();
return new CounterServiceBinder();
}
public class CounterServiceBinder extends Binder {
public CounterService getService(){
return CounterService.this;
}
}
private void startCount() {
keepCounting=true;
count=0;
new Thread(new Runnable() {
@Override
public void run() {
while(keepCounting) {
count++;
try {
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}).start();
}
private void stopCount() {
keepCounting=false;
count=0;
}
public int getCount(){
return count;
}
@Override
public boolean onUnbind(Intent in){
stopCount();
return super.onUnbind(in);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("Service Lifecycle","onDestroy called");
}
}
MainActivity.java

boolean bound=false;
CounterService cs = null;
Intent in;
ServiceConnection sc=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName arg0,
IBinder arg1) {
CounterService.CounterServiceBinder csb=(
CounterService.CounterServiceBinder)arg1;
cs=csb.getService();
bound=true;
}
@Override
public void onServiceDisconnected() {
bound=false;
}
@Override
protected void onCreate(Bundle b) {
in = new Intent(this,CounterService.class);
}
public void onClickStart(View v){
bindService(in,sc,BIND_AUTO_CREATE);
}
public void onClickStop(View v){
unbindService(sc);
}
Data Persistence
So far

So far
User Interface
Long-running tasks
In both cases data captured through user inputs and exchanged
using Intents
Data is volatile and wiped o once the app is terminated.
Storage of Data

We may come across scenarios where app data need to be


stored on the device or remotely on the enterprise system.
For local storage, apps use internal memory of the device or
Secure Digital(SD) card
For remote storage, apps have to connect to external
enterprise systems over the network
Flat Files
Flat Files

Flat les are used to persist unstructured data-primitive and


complex
Android uses Java Input-Output API to read and write at les
Opening, Writing and Closing a le

private void writeToFile(String text) {


try {
OutputStreamWriter outputStreamWriter = new
OutputStremWriter(openFileOutput("
userinput.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(text);
outputStreamWriter.close();
}catch(IOException e) {
e.printStackTrace();
}
}
File Location

The userinput.txt le gets created inside


/data/data/<package>/les folder.
Opening, Reading and Closing a le
private String getFileContent() {
String fileContent = "";
try {
InputStream is = openFileInput("userinput.txt");
if(inputStream != null) {
InputStreamReader isr = new InputStreamReader(
is);
BufferedReader br = new BufferedReader(isr);
String line="";
StringBuilder sb=new StringBuilder();
while((line = br.readLine()) != null) {
sb.append(line);
}
is.close();
fileContent = sb.toString();
}
} catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
return fileContent;
File Storage in External(SDCard)
Opening, Writing and Closing a le
private void writeToFile(String text) {
try {
File sdCard=Environment.
getExternalStorageDirectory();
if(sdCard.exists() && sdCard.canWrite()) {
File newFolder = new File(sdCard.
getAbsolutePath()+"/FolderName");
newFolder.mkdir();
if(newFolder.exists() && newFolder.canWrite())
{
File textFile = new File(newFolder.
getAbsolutePath()+"/userinput.txt");
textFile.createNewFile();
if(textFile.exists() && textFile.canWrite())
{
FileWriter fw = new FileWriter(textFile);
fw.write(text);
fw.flush();
fw.close();
}
}
}
Reading a File from External Storage

private String getFileContent() {


String fileContent = "";
File sdCard = Environment.
getExternalStorageDirectory();
if(sdCard.exists() && sdCard.canRead()) {
File appFolder = new File(sdCard.getAbsolutePath
()+"/FolderName");
if(appFolder.exists() && appFolder.canRead()) {
File textFile=new File(appFolder.
getAbsolutePath()+"/userinput.txt");
....
}
Shared Preferences
Shared Preferences

Shared preferences is a solution to store primitive data in


key-value pairs
Key-value pairs are used to save user preferences such as
ringtone, user-preferred app settings etc.
provide support for persisting boolean, oat, int, long and
String data types
Shared preferences stores data in an XML le in the internal
memory of the device
An Example

SharedPreferences preferences = getSharedPreferences(


"SMSPreferences", Context.MODE_PRIVATE);
Editor ed = preferences.edit();
ed.putBoolean("SendSMS", chkEnable.isChecked());
ed.putString("Message", et.getText().toString());
ed.putString("Signature", etSign.getText().toString()
);
ed.commit();
Shared Preferences le

File gets stored in /data/data/<package>/shared_prefs as an


XML le
<?xml version="1.0" encoding="utf-8" standalone="yes"
?>
<map>
<string name="Message">Will call you back later</
string>
<string name="Signature">Auto SMS</string>
<boolean name="SendSMS" value="true"/>
</map>
Methods oered by Editor

putBoolean(String key, boolean value) Saves a boolean value


against a key
putFloat(String key, oat value) Saves a oat value
against a key
putInt(String key, int value) Saves an integer value
against a key
putLong(String key, long value) Saves a long value
against a key
putString(String key, String value) Saves a string value
against a key
putStringSet(String key, Set values) Saves a set of String val-
ues against a key
Reading Shared Preferences

SharedPreferences preferences = getSharedPreferences(


"SMSPreferences", Context.MODE_PRIVATE);
boolean sendSms= preferences.getBoolean("SendSMS",
false);
String message=ed.getString("Message", "");
String sign=ed.getString("Signature", "");
//Send SMS to the caller
Implementing a Settings Screen
Preferences Screen
res/xml/preferences.xml I

<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/
android">
<PreferenceCategory
android:title="General options">
<CheckBoxPreference
android:key = "silent_mode"
android:defaultValue="false"
android:title="Silent Mode
android:summary="Mute all sounds from this app" />
<SwitchPreference
android:key="awesome_mode"
android:defaultValue="false"
android:switchTextOn="Yes"
android:switchTextOff="No"
android:title="Awesome mode"
android:summary="Enable the Awesome Mode feature"/>
<EditTextPreference
android:key="custom_storage"
res/xml/preferences.xml II

android:defaultValue="/sdcard/data/"
android:title="Custom storage location"
android:summary="Enter the directory path where you
want data to be saved. If it does
not exist, it will be created."
android:dialogTitle="Enter directory path (eg. /
sdcard/data/ )"/>
</PreferenceCategory>
</PreferenceScreen>
Activity I

package com.example.preferences;
import android.preference.PreferenceActivity;
import android.os.Bundle;
public class PreferencesActivity extends
PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
Relational Data
Relational Data

So far we learnt to store unstructured, primitive data on the


device using le,shared preferences
reduced data redundancy, atomicity, consistency, isolation,
durability and querying ability
these databases have to be light weight, utilize limited
processing power
Android provides SQLite database
SQLite is light weight(around 500KB)
SQLite runs as part of the process
An Example

public class StringDBAdapter {


private static final String DB_NAME="
String_Database.db";
private static final String TABLE_NAME="
String_Table";
private static final int DB_VERSION=1;
private static final String KEY_ID="id";
private static final String COLUMN_STRING="String";
private static final String TABLE_CREATE="create
table "+TABLE_NAME+"("+KEY_ID+" integer primary
key autoincrement ,"+COLUMN_STRING+" text not
null);";
private SQLiteDatabase stringDatabase;
private final Context context;
private MyDBHelper helper;
public StringDBAdapter(Context context)
{
this.context=context;
helper=new MyDBHelper(context,DB_NAME,null,
DB_VERSION);
}
private static class MyDBHelper extends
SQLiteOpenHelper
{
public MyDBHelper(Context context, String name,
CursorFactory cursorFactory, int version){
super(context,name,cursorFactory,version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int
oldVersion, int newVersion){
Log.w("Updation","Database version is being updated
");
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public StringDBAdapter open() {
stringDatabase=helper.getWritableDatabase();
return this;
}
public void close() {
stringDatabase.close();
}
Query

public Cursor getAllRecords() {


return db.query(TABLE_NAME,null,null,null,null,null
,null);
}

public Cursor getRecordsWithinRange(int gid) {


return db.query(TABLE_NAME,null,KEY_ID+"<="+gid,
null,null,null,null);
}
Displaying values from Table

recs=db.getAllRecords();

stringlist=new ArrayList<Integer>();
while(recs.moveToNext()) {
stringlist.add(recs.getString(0));
}
stringAdapter = new ArrayAdapter<String>(
getApplicationContext(),android.R.layout.
simple_list_item_1,
expAmount);
lv.setAdapter(stringAdapter);
Sum of a column

public int getTotalRecords() {


Cursor strCursor = db.rawQuery("SELECT COUNT(id)
FROM "+TABLE_NAME,null);
if(strCursor != null) {
strCursor.moveToNext();
return strCursor.getInt(0);
}
else
return 0;
Adding a tuple

public long addString(String str) {


ContentValues cv=new ContentValues();
cv.put(COLUMN_STRING, str);
return db.insert(TABLE_NAME,null,cv);
}
Deleting a tuple

public boolean deleteRecord(long id) {


return db.delete(TABLE_NAME,KEY_ID+"="+id,null)>0;
}
Updating a tuple

public int updateString(long id, String str) {


ContentValues cv = new ContentValues();
cv.put(COLUMN_STRING, str);
return db.update(TABLE_NAME, cv,KEY_ID+"="+id,null)
;
}
Graphics
Supporting multiple Screen Densities

Android devices come with varying screen densities. To


support multiple screen densities multiple resources need to be
prepared and kept in separate folder.
Android system recognizes four screen densities namely ldpi,
mdpi, hdpi and xhdpi
Images need to be prepared and kept in respective folders
namely drawable-ldpi, drawable-mdpi, drawable-hdpi and
drawable-xhdpi
Layout resource les need to be prepared and kept in
layout-ldpi, layout-mdpi, layout-hdpi and layout-xhdpi
Android Graphics

android.graphics.Canvas can be used to draw graphics in


android. It provides methods to draw oval, rectangle, picture,
text, line etc.
android.graphics.Paint is used to draw objects. It holds the
information of color and style.
MainActivity.java

package com.example.simplegraphics;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;

public class MainActivity extends Activity {


DemoView demoview;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
demoview = new DemoView(this);
setContentView(demoview);
}
private class DemoView extends View{
public DemoView(Context context){
super(context);
}
@Override protected void onDraw(Canvas canvas
) {
super.onDraw(canvas);

// custom drawing code here


Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);

// make the entire canvas white


paint.setColor(Color.WHITE);
canvas.drawPaint(paint);

// draw blue circle with anti aliasing


turned off
paint.setAntiAlias(false);
paint.setColor(Color.BLUE);
canvas.drawCircle(20, 20, 15, paint);
// draw green circle with anti aliasing
turned on
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
canvas.drawCircle(60, 20, 15, paint);

// draw red rectangle with anti aliasing


turned off
paint.setAntiAlias(false);
paint.setColor(Color.RED);
canvas.drawRect(100, 5, 200, 30, paint);
// draw the rotated text
canvas.rotate(-45);

paint.setStyle(Paint.Style.FILL);
canvas.drawText("Graphics Rotation", 40,
180, paint);

//undo the rotate


//canvas.restore();
Output
Two ways to drawing Graphics

Draw the graphics or animations into a View object. Useful


when simple graphics.
Draw your graphics directly to a Canvas. e.g. Video game
Drawing Directly to a Canvas

1 In the same thread as the UI activity, you create a custome


View component, call invalidate() and then handle the
onDraw() callback
2 In a separate thread, wherein you manage a SurfaceView and
perform draws to the Canvas
Creating a Canvas from a Bitmap

Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.


Config.ARGB_8888);
Canvas c = new Canvas(b);

After drawing upon with Canvas, you can then carry your Bitmap
to another Canvas with one of the Canvas.drawBitmap(Bitmap,..)
methods. Draw the nal graphics through a Canvas oered by
View.onDraw() or SurfaceHolder.lockCanvas()
On a SurfaceView

is a subclass of View
oer the drawing surface to secondary thread
You need to create a new class that extends SurfaceView
The class should implement SurfaceHolder.Callback
Animations
Animations in Android

Tweened View Animations - applied to Views, letting to dene


series of changes in position, size, rotation and opacity
Frame Animations - tradition cell based animation in which
dierent drawables are displayed in each frame
Interpolated property Animations - lets you animate almost
anything
Drawable Animation

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


<animation-list
xmlns:android="http://schemas.android.com/apk/res/
android">
<item android:drawable="@drawable/img1"
android:duration="250"/>
<item android:drawable="@drawable/img2"
android:duration="250"/>
<item android:drawable="@drawable/img3"
android:duration="250"/>
<item android:drawable="@drawable/img4"
android:duration="250"/>
</animation-list>
Drawable Animation Java code

//in onCreate()
ImageView im=(ImageView)findViewById(R.id.image);
im.setBackgroundResource(R.drawable.drawable_anim);

public void onClick(View v){


AnimationDrawable frameAnimation=(AnimationDrwable)
im.getBackground();
frameAnimation.start();
}
res/anim/myanimation.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/
res/android">
<scale xmlns:android="http://schemas.android.com/
apk/res/android"
android:fromXScale="0.5"
android:toXScale="3.0"
android:fromYScale="0.5"
android:toYScale="3.0"
android:duration="5000"
android:pivotX="50%"
android:pivotY="50%" >
</scale>
<scale xmlns:android="http://schemas.android.com/
apk/res/android"
android:startOffset="5000" android:fromXScale="
3.0"
android:toXScale="0.5" android:fromYScale="3.0"
android:toYScale="0.5" android:duration="5000"
android:pivotX="50%" android:pivotY="50%" >
</scale>
res/anim/clockwise.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/
res/android">
<rotate xmlns:android="http://schemas.android.com/
apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000" >
</rotate>
<rotate xmlns:android="http://schemas.android.com/
apk/res/android"
android:startOffset="5000"
android:fromDegrees="360"
android:toDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000" >
</rotate>
</set>
res/anim/fade.xml

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


<set xmlns:android="http://schemas.android.com/apk/
res/android"
android:interpolator="@android:anim/
accelerate_interpolator" >
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000" >
</alpha>
<alpha
android:startOffset="2000"
android:fromAlpha="1"
android:toAlpha="0"
android:duration="2000" >
</alpha>
</set>
res/anim/blink.xml

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


<set xmlns:android="http://schemas.android.com/apk/
res/android">
<alpha android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="@android:anim/
accelerate_interpolator"
android:duration="600"
android:repeatMode="reverse"
android:repeatCount="infinite"/>
</set>
res/anim/move.xml

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


<set
xmlns:android="http://schemas.android.com/apk/res/
android"
android:interpolator="@android:anim/
linear_interpolator"
android:fillAfter="true">

<translate
android:fromXDelta="0%p"
android:toXDelta="75%p"
android:duration="800" />
</set>
res/anim/slide.xml

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


<set xmlns:android="http://schemas.android.com/apk/
res/android"
android:fillAfter="true" >

<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/
linear_interpolator"
android:toXScale="1.0"
android:toYScale="0.0" />
</set>
MainActivity.java
package com.example.mahe;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void clockwise(View view){
ImageView image = (ImageView)findViewById(R.id.
imageView);
Animation animation = AnimationUtils.
loadAnimation(getApplicationContext(), R.
anim.myanimation);
image.startAnimation(animation);
}
public void zoom(View view){
ImageView image = (ImageView)findViewById(R.id.
imageView);
Animation animation1 = AnimationUtils.
loadAnimation(getApplicationContext(), R.
anim.clockwise);
image.startAnimation(animation1);
}
public void fade(View view){
ImageView image = (ImageView)findViewById(R.id.
imageView);
Animation animation1 = AnimationUtils.
loadAnimation(getApplicationContext(), R.
anim.fade);
image.startAnimation(animation1);
}
public void blink(View view){
ImageView image = (ImageView)findViewById(R.id.
imageView);
Animation animation1 = AnimationUtils.
loadAnimation(getApplicationContext(), R.
anim.blink);
image.startAnimation(animation1);
}
public void move(View view){
ImageView image = (ImageView)findViewById(R.id.
imageView);
Animation animation1 = AnimationUtils.
loadAnimation(getApplicationContext(), R.
anim.move);
image.startAnimation(animation1);
}
public void slide(View view){
ImageView image = (ImageView)findViewById(R.id.
imageView);
Animation animation1 = AnimationUtils.
loadAnimation(getApplicationContext(), R.
anim.slide);
image.startAnimation(animation1);
}
Property Animation
Property Animation

private RelativeLayout parent;


private ObjectAnimator colorAnim;

protected void onCreate(Bundle b){


parent=(RelativeLayout)findViewById(R.id.parent);
colorAnim=ObjectAnimator.ofInt(parent,"
backgroundColor",Color.RED,Color.BLUE);
colorAnim.setDuration(1000);
}
public void onClick(View v) {
colorAnim.start();
}
Sensors
Sensors Overview

Sensors are designed for diverse needs


motion, orientation and environmental conditions
Android-powered devices have built-in senosrs
e.g. three dimensional device movement, positioning or
changes in ambient environment
e.g. game might track readings from a device's gravity sensor
to infer complex user gestures such as tilt, shake, rotation or
swing
a weather application might use a device's temperature and
humidity sensor
Types of sensors

Motion sensors - measures acceleration forces and rotational


forces along three axes e.g. accelerometer, gravity sensor,
gyroscope and rotational vector sensor
Environmental sensors - measure various environmental
parameters, such as temperature, pressure, illumination and
humidity. e.g. barometers, photometers and thermometers
Position sensors - measure the physical position of a device.
This category includes orientation sensors and magnetometers.
Sensor Framework

Using Sensor framework,


determine which sensors are available on a device
determine individual sensor's capabilities
acquire raw sensor data
register and unregister sensor event listeners
Identifying Sensors

private SensorManager sm;

public void onClick(View v) {


String LOG_TAG="Sensor";
sm=(SensorManager)getSystemService(Context.
SENSOR_SERVICE);
List<Sensor> ls = sm.getSensorList(Sensor.TYPE_ALL)
;
for(Sensor s : ls) {
Log.i(LOG_TAG, "Sensor Name :"+s.getName()+" Type
:"+s.getType());
}
other options for getSensorList()

1 TYPE_ACCELEROMETER, TYPE_PROXIMITY,
TYPE_LIGHT

2 there may be multiple sensors for a single task

3 Information about Sensors can be obtained


Reading sensor data

public class MainActivity extends Activity implements


SensorEventListener, OnClickListener {
private SensorManager sm;
private Sensor s;
private TextView xtv,ytv,ztv;
private boolean monitoring=false;
private Button b;

@Override
protected void onCreate(Bundle b) {
super.onCrete(b);
setContentView(R.layout.activity_main);
Reading sensor data

sm=(SensorManager)getSystemService(Context.
SENSOR_SERVICE);
s=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
xtv=(Textview)findViewById(R.id.xtv);
ytv=(Textview)findViewById(R.id.ytv);
ztv=(Textview)findViewById(R.id.ztv);
b = (Button)findViewById(R.id.button);
b.setOnClickListener(this);
}
@Override
public final void onAccuracyChanged(Sensor s, int
accuracy) {
//Do something on sensor accuracy change
}
Reading sensor data
@Override
public final void onSensorChanged(SensorEvent se) {
if(monitoring) {
float []values = se.values;
//Movement
float accx = values[0];
float accy = values[1];
float accz = values[2];

xtv.setText(String.valueOf(accx));
ytv.setText(String.valueOf(accy));
ztv.setText(String.valueOf(accz));
}
}

@Override
protected void onResume() {
super.onResume();
sm.registerListener(this,s,SensorManager.
SENSOR_DELAY_NORMAL);
}
Reading sensor data

@Override
protected void onPause() {
super.onPause();
sm.unregisterListener(this);
}

@Override
public void onClick(View v) {
Toast.makeText(this,"Displaying Accelerometer
data ",Toast.LENGTH_SHORT).show();
monitoring = true;
}
}
Ring Silencer
Ring Silencer

public class Silencer extends BroadcastReceiver


implements SesorEventListener {
private SensorManager sm;
private static final String Mode_number="
RingSilencerPrefs";
private AudioManager am;
private static float prevZValue;
private static boolean phoneFlipped=false;

@Override
public void onReceive(Context c, Intent i) {
am=(AudioManager)c.getSystemService(c.
AUDIO_SERVICE);
sm=(SensorManager)c.getSystemService(c.
SENSOR_SERVICE);
Ring Silencer

if(i.getAction().equals("android.intent.action.
PHONE_STATE")) {
if(i.getStringExtra(TelephonyManager.
EXTRA_STATE).toString().equals(
TelephonyManager.EXTRA_STATE_RINGING)) {
int prevMode;
SharedPreferences sp=c.getSharedPreferences(
Mode_Number,c.MODE_PRIVATE);
Editor ed=sp.edit();
prevMode = am.getRingerMode();
ed.putInt("silentMode",prevMode);
ed.commit();
startListening();
}
Ring Silencer

else if(i.getStringExtra(TelephonyManager.
EXTRA_STATE).toString().equals(
TelephonyManager.EXTRA_STATE_OFFHOOK)) {
sm.unregisterListener(this);
}
else if(i.getStringExtra(TelephonyManager.
EXTRA_STATE).toString().equals(
TelephonyManager.EXTERA_STATE_IDLE)) {
SharedPreferences sp=c.getSharedPreferences(
Mode_number,c.MODE_PRIVATE);
int prevMode=sp.getInt("silentMode",
AudioManager.RINGER_MODE_VIBRATE);
am.setRingerMode(prevMode);
sm.unregisterListener(this);
Editor ed = sp.edit();
ed.clear();
ed.commit();
phoneFlipped=false;
}
}
Ring Silencer
} public void startListening() {
Sensor s=sm.getDefaultSensor(Sensor.
TYPE_ACCELEROMETER);
sm.registerListener(this, s,SensorManager.
SENSOR_DELAY_FASTEST);
}
public void onAccuracyChanged(Sensor s, int
accuracy) {}
public void onSensorChanged(SensorEvent e) {
Sensor s = e.sensor;
if(s.getType() == Sensor.TYPE_ACCELEROMETER) {
if(e.values[2] < 0 && prevZValue > 0 ) {
phoneFlipped = true;}
}prevZValue = e.values[2];
if(phoneFlipped == true) {
am.setRingerMode(AudioManager.
RINGER_MODE_SILENT);
sm.unregisterListener(this);
}}}
Brightness Manager
Brightness Manager

public class BrightnessManagerActivity extends


Activity implements OnCheckedChangeListener,
SensorEventListener
{ private CheckBox enableCB;
private SensorManager sm;
private Sensor proximitySensor;
public enum BRIGHTNESS_LEVEL {
LOW, MEDIUM, HIGH;
}
public BRIGHTNESS_LEVEL cb = BRIGHTNESS_LEVEL.LOW;
@Override
protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_main);
enableCB = (CheckBox) findViewById(R.id.checkBox1
);
enableCB.setOnCheckedChangeListener(this);
}
Brightness Manager

@Override
protected void onResume() {
super.onResume();
if(enableCB.isChecked())
initiateBrightnessManager();
}
@Override
public void onCheckedChanged(CompoundButton b,
boolean isChecked) {
if(isCehcked)
initiateBrightnessManager();
else
terminateBrightnessManager();
}
private void terminateBrightnessManager() {
if(sm != null)
sm.unregisterListener(this);
}
Brightness Manager

private void initiateBrightnessManager() {


sm = (SensorManager)getSystemService(Context.
SENSOR_SERVICE);
proximitySensor = sm.getDefaultSensor(Sensor.
TYPE_PROXIMITY);
if(proximitySensor != null) {
sm.registerListener(this,proximitySensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
@Override
public void onAccuracyChanged(Senosr s, int
accuracy) {
}
Brightness Manager

@Override
public void onSensorChanged(SensorEvent se) {
float distance = se.values[0];
if(distance==0) {
int nextBrightnessLevelNumber = (cb.ordinal()
+1)%3;
WindowManager.LayoutParams p = getWindow().
getAttributes();
p.screenBrightness = nextBrightnessLevelNumber
;
getWindow().setAttributes(p);
}
}
Testing in Android
Testing Android Applications

Android applications run on a variety of devices


To ensure application works well, it is important to write
Software Tests
Unit Test, Integration Tests, UI Tests are types of tests
Testing in Android
Unit test

Unit testing is a testing a component or code for its function


usually developer will carry out unit test on the code developed
Unit test is classied into two types - Local unit tests and
Instrumented unit tests
Local unit tests run on the JVM
Instrumented unit tests require the Android system
Testing Frameworks

Following are some of the testing frameworks used in Android:


JUnit
Mockito
Powermock
Robolectric
Espresso
Hamcrest
build.gradle

Whenever you start a new Android Studion Project, JUnit


dependency is already present in the build.gradle
build.gradle

Whenever you start a new Android Studion Project, JUnit


dependency is already present in the build.gradle
Folders in Android

In Android Studio Project, the following are the three important


packages inside the src folder:
app/src/main/java/ - Main java source code folder
app/src/test/java/ - Local unit test folder
app/src/androidTest/java/ - Instrumentation test folder
Creating Test Cases

To create tests, we need to either extend the class with


TestCase or add the annotation Test above the methods.
TestCase was used mainly till JUnit3
A Test Case

package edu.manipal.util.temperature;

public class ConverterUtil {


// converts to celsius
public static float convertFahrenheitToCelsius(
float fahrenheit) {
return ((fahrenheit - 32 * 5 / 9));
}

// converts to fahrenheit
public static float convertCelsiusToFahrenheit(
float celsius) {
return ((celsius * 9) / 5) + 32;
}
}
A Test Case I

package edu.manipal.test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import edu.manipal.util.temperature.ConverterUtil;

public class ConverterUtilTest {

@Test
public void testConvertFahrenheitToCelsius() {
float actual = ConverterUtil.
convertCelsiusToFahrenheit(100);
// expected value is 212
float expected = 212;
A Test Case II
// use this method because float is not
precise
assertEquals("Conversion from celsius to
fahrenheit failed", expected, actual,
0.001);
}

@Test
public void testConvertCelsiusToFahrenheit() {
float actual = ConverterUtil.
convertFahrenheitToCelsius(212);
// expected value is 100
float expected = 100;
// use this method because float is not
precise
assertEquals("Conversion from celsius to
fahrenheit failed", expected, actual,
0.001);
}
A Test Case III

}
Publishing and Distributing Apps
Distributing Apps

Distributing the app through email, site, or App Store such as


Google Play and Amazon
Distributing through email is preferred when limited number of
users
Through website is convenient
There is not much control over the app from the perspective
of upgradation, maintenance
Distributing Apps through Online App Store

Online App stores charge a nominal fee


Provide various services such as monitoring the number and
frequency of app downloads
monitoring app usage patterns, establishing connect with
service providers for localization and internationalization
tracking app performance in the market, accessing end-user's
feedback or viewing crash reports
Distributing Apps through Online App Store

cater to distributing apps for a specic set of regions, carrier


networks and device congurations
Provide on-the-air update service for installed apps
In case of paid pricing model, the online app stores may also
charge percentage cut of the app selling price
advanced app features are sold typically as in-app purchases
content is sold as subscription(for content based apps)
Indirect monetization is implemented via hosting
advertisements in an app
Publishing Apps
Ground work

Steps
1 Sanitizing the app - removes unused resource les, Java source

les used for testing and debugging purpose, log statements


and unused libraries
2 app resources such as image les, locale specic strings should

be cross checked for placement in appropriate folders


3 App manifst has to be checked for unique app package name

4 remote servers need to be ensured that they are ready and

functional and prepared for anticipated load


5 pricing model has to be nalized

6 legal agreements such as End User License Agreement(EULA)

7 promotional artifacts such as app description, screen shots and

promotional videos need to be designed.


Conguring App

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/
apk/res/android"
package="com.mahe.Multimedia"
android:versionCode="1"
android:versionName="v1.0">

Next version of App


<manifest xmlns:android="http://schemas.android.com/
apk/res/android"
package="com.mahe.Multimedia"
android:versionCode="2"
android:versionName="v1.1">
API requirements of an App

<uses-sdk android:minSdkVersion="18"
android:targetSdkVersion="23"/>
Packaging

Android app need to be packaged as a signed .apk le


apk le contains a .dex le, app manifest le and resource les
such as images, icons, assets, layouts and menu
During development and testing IDE creates an apk le and
signs it using a default debug key
References

1 Pradhan, Anubhav, and Anil V. Deshpande. "Composing


Mobile Apps" using Android." (2014).
2 Android App Development e-book, Abhishek, abhiandroid.com
3 http://developer.android.com
4

https://www.vogella.com/tutorials/AndroidTesting/article.html
5 https://www.journaldev.com/22674/android-unit-testing-
junit4

You might also like