0% found this document useful (0 votes)
8 views210 pages

Android Notes - 5 Modules 12 Size

Android is a mobile operating system developed by Google, primarily for touchscreen devices, and is based on the Linux kernel. It supports a wide range of applications written in Java, offers a secure environment through a multi-user system, and has evolved through various versions since its inception in 2008. Key features include a beautiful user interface, multi-tasking capabilities, and extensive connectivity options, with ongoing updates enhancing functionality and performance.

Uploaded by

mallygop
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)
8 views210 pages

Android Notes - 5 Modules 12 Size

Android is a mobile operating system developed by Google, primarily for touchscreen devices, and is based on the Linux kernel. It supports a wide range of applications written in Java, offers a secure environment through a multi-user system, and has evolved through various versions since its inception in 2008. Key features include a beautiful user interface, multi-tasking capabilities, and extensive connectivity options, with ongoing updates enhancing functionality and performance.

Uploaded by

mallygop
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

1

Introducing the Android Computing Platform

Introduction

Android is a mobile operating system developed by Google, designed primarily for


touchscreen mobile devices such as smartphones and tablets. Google acquired the startup company
Android Inc. in 2005 to start the development of the Android platform. The key players at Android
Inc. included Andy Rubin, Rich Miner, Nick Sears, and Chris White. Most of the code is available
under Apache License.

According to Google‘s Andy Rubin, Android is –

“The first truly open and comprehensive platform for mobile devices. It includes an Operating System,
user interface and applications - all of the software to run a mobile phone but without the proprietary
obstacles that have hindered mobile innovation.”

Android operating system is based on Linux kernel that manages devices, memory, and processes.

Its user interface is mainly based on direct manipulation, using touch gestures such as swiping, tapping
and pinching, to manipulate on-screen objects, along with a virtual keyboard for text input.

Android apps are written in the Java programming language. Android‘s Java libraries cover telephony,
video, speech, graphics, connectivity, UI programming, and a number of other aspects of the device.

In addition to touchscreen devices, Google has further developed Android TV for televisions, Android
Auto for cars and Android Wear for wrist watches, each with a specialized user interface. Variants of
Android are also used on notebooks, game consoles, digital cameras, and other electronics.

The Android operating system is a multi-user Linux system in which each app is a different [Link]
default, the system assigns each app a unique Linux user ID (the ID is used only by the system and is
unknown to the app). The system sets permissions for all the files in an app so that only the user ID
assigned to that app can access [Link] process has its own virtual machine (VM), so an app's code
runs in isolation from other apps.

By default, every app runs in its own Linux process. Android starts the process when any of the app's
components need to be executed, then shuts down the process when it's no longer needed or when the
system must recover memory for other apps.

Android apps are written in the Java programming language. The Android SDK supports most of the
Java Platform, Standard Edition (Java SE), except for the Abstract Window Toolkit (AWT) and
Swing. In place of AWT and Swing, Android SDK has its own extensive modern UI framework.
Android offers its own optimized JVM to run the compiled Java class files in order to counter the
handheld device limitations such as memory, processor speed, and power. This virtual machine is
called the Dalvik VM.

The Android SDK tools compile your code—along with any data and resource files—into an APK:
an Android package, which is an archive file with an .apk suffix. One APK file contains all the
contents of an Android app and is the file that Android-powered devices use to install the [Link]
installed on a device, each Android app lives in its own security sandbox:
2

The Android system implements the principle of least privilege. That is, each app, by default, has
access only to the components that it requires to do its work and no more. This creates a very secure
environment in which an app cannot access parts of the system for which it is not given permission.

An app can share data with other apps. It's possible to arrange for two apps to share the same Linux
user ID, in which case they are able to access each other's files. To conserve system resources, apps
with the same user ID can also arrange to run in the same Linux process and share the same VM (the
apps must also be signed with the same certificate).

An app can request permission to access device data such as the user's contacts, SMS messages, the
mountable storage (SD card), camera, Bluetooth, and more. The user has to explicitly grant these
permissions.

One of Androids key architectural goals is to allow applications to interact with one another and reuse
components from one another. This reuse applies not only to services, but also to data and the user
interface (UI).

Early History of Android

Mobile phones use a variety of operating systems, such as Symbian OS, Microsoft‘s Windows Phone
OS, Mobile Linux, iPhone OS (based on Mac OS X), Moblin (from Intel), and many other proprietary
OSs.

Android early timeline

Open Handset Alliance was formed in November 2007. OHA is a business alliance that consists of 47
companies for developing open standard platform for mobile devices. The members of OHA include
handset manufactures, chip makers, commercialization companies, software companies and mobile
operators.

The Android SDK was first issued as an ―early look‖ release in November 2007. In September 2008,
T-Mobile announced the availability of T-Mobile G1, the first smartphone based on the Android
[Link] then the SDKs 2.0, 3.0, 4.0, etc. are released roughly one every year.

Features of Android

Android is a powerful operating system competing with Apple 4GS and support great features. Few of
them are listed below:

Beautiful UI - Android OS basic screen provides a beautiful and intuitive user interface.
3

Connectivity - GSM/EDGE, IDEN, CDMA, EV-DO, UMTS, Bluetooth, Wi-Fi, LTE, NFC and
WiMAX.

Storage - SQLite, a lightweight relational database, is used for data storage purposes.

Media support - H.263, H.264, MPEG-4 SP, AMR, AMR-WB, AAC, HE-AAC, AAC 5.1, MP3,
MIDI, Ogg Vorbis, WAV, JPEG, PNG, GIF, and BMP

Messaging - SMS and MMS Web browser Based on the open-source WebKit layout engine, coupled
with Chrome's V8 JavaScript engine supporting HTML5 and CSS3.

Multi-touch -Android has native support for multi-touch which was initially made available in
handsets such as the HTC Hero.

Multi-tasking - User can jump from one task to another and same time various application can run
simultaneously.

Resizable widgets - Widgets are resizable, so users can expand them to show more content or shrink
them to save space

Multi-Language Support - single direction and bi-directional text

GCM - Google Cloud Messaging (GCM) is a service that let developers send short message data to
their users on Android devices, without needing a proprietary sync solution.

Wi-Fi Direct - A technology that let apps discover and pair directly, over a high band width peer-to-
peer connection.

Android Beam - A popular NFC-based technology that let users instantly share, just by touching two
NFC-enabled phones together

Android Versions

Android 1.0 - September 2008

 Includes camera support, Google apps, including Gmail and YouTube.

 Widgets are present at this early stage, but they're limited to Google's own and are not truly
interactive.

Android 1.5 (Cupcake) - April 2009

 On-screen keyboard allows Android to move away from physical keyboards.

 Camcorder app brings video recording to Android for the first time.

 Videos can be uploaded to YouTube, and photos can be uploaded to Picasa.

 Third-party widgets are now possible as a companion to an app.

 Google adds Calendar and Music widgets;

 Google Talk gets its own app.


4

 Auto-rotation allows for an easier landscape-to-portrait transition.

Android 1.6 (Donut) - September 2009

 CDMA support opens Android up to all carriers.

 Multiple screen resolutions are available for the first time.

 A battery-usage indicator is introduced to show the user what apps and services are using up
the most battery.

 The Power Control widget brings easy toggle for Wi-Fi, Bluetooth, GPS, Sync and Brightness
to the home screen.

Android 2.0 (Éclair) - October 2009

 Google Maps Navigation is introduced, bringing free turn-by-turn directions to the phone.

 Support for multiple accounts is added, with distinct Contact, Email and Calendar sync settings
for each account.

 Browser is updated with ability to search from the address bar, save bookmarks with
thumbnails f the Web page, double-tap to zoom and HTML5 support.

 On-screen buttons are now available to answer and end a call, allowing Android devices to
drop those hardware buttons.

Android 2.2 (Froyo) - May 2010

 Dalvik VM: Just-in-time (JIT) Compiler brings massive speed enhancements to Android.

 Apps can now be installed or moved to an SD card from internal storage

 A native hotspot feature now allows your smartphone to serve as a wireless hotspot for your
other devices.

 Browser adds V8 engine from Chrome, making the browser two to five times faster.

Android 2.3 (Gingerbread) - December 2010

 The on-screen keyboard is redesigned to improve typing speed and accuracy, and suggestions
are now available as you type.

 Support for near-field communication (NFC) is included for the first time.

Android 3.0 (Honeycomb) - February 2011

 Designed for tablets only.


5

 The Fragments API was introduced to deal with this break between tablets and phones, which
allowed developers to create multiple screens for a phone interface that could then be displayed
together on the tablet.

 There are no devices still running Honeycomb; this version of Android was never open-
sourced, and all devices running Honeycomb were updated to at least Ice Cream Sandwich.

Android 4.0 (Ice Cream Sandwich) - October 2011

 Spell checker.
 Enhancements to the calendar application.
 Better camera app: continuous focus, zero shutter lag, face detection,tap to focus, and a photo
editor.
 A quick way to take and share screen shots.

 All navigation is brought on-screen, meaning that it is now possible to release a device with
only a power and volume buttons.

 The swipe gesture to dismiss notifications, recent apps or browser tabs is added for the first
time.

 Adds the ability to monitor your own data usage and set warnings and hard limits for mobile or
Wi-Fi to avoid costly overages.
Android Market was renamed as the Google Play store.

Android 4.1 (Jelly Bean) - June 2012

 Notifications are greatly expanded in Jelly Bean, can display eight lines of text and could
feature buttons at the bottom of the notification to take action.

 Google Play services become a way for Google to update Android devices without having to
go through the carriers with a full OS update.

Android 4.4 (KitKat) - September 2013

 Make Android better on low-end hardware, with the possibility of running it with as little as
512MB of RAM.

 The black backgrounds are banished from most screens in KitKat in favor of transparencies,
which display your wallpaper behind them.

 Offers support for Host Card Emulation (HCE), making NFC-based payments or other
transactions more secure.

 Truly full-screen apps are possible for the first time, and hide even the status [Link] Drive
becomes a default app as a gateway to Google's office suite.

Android 5.0 (Lollipop) - November 2014

 Android Runtime with ahead-of-time compilation replaces the Dalvik VM with just-in-time
compilation introduced in Android 2.2.
6

 Android TV launches, bringing Android to the big screen.

 OpenGL ES 3.1 allows for even more immersive and visually captivating Android gaming.

 Smart Lock lets you unlock your device automatically when a trusted Bluetooth device (like a
smart watch) is present.

Android 6.0 (Marshmallow) October 2015

 USB Type-C support


 Fingerprint Authentication support
 Better battery life with "deep sleep"
 MIDI support
 Android Pay
 Home Screen Rotation
 Chrome Custom Tab
 Auto backup and Store
 Status bar icon removal

Version Version Key developer features Releas API


Key user features added
No name added e date Level
 Better privacy support:

Require permissions to access


location or files in background

Limit access to unique device


identifiers MIDI API

Notification Bubbles 2019


Android Android Q Access system settings directly 29
Sep 3
10 from apps using floating panel
In apps Biometric
 New audio/video codec
authentication
support: AV1, HDR10+, Opus
 WPA3 Wi-Fi support
 Foldable phones support
 Dark theme
 Gesture navigation

 User interface updates:

Rounded corners across the UI


2018
Android 9 Pie 28
Aug 9
Quick settings menu change.

Notification bar, the clock has


7

moved to the left.

The "dock" now has a semi-


transparent background.

New transitions when switching


between apps, or within apps

Volume slider updated

 Richer messaging notifications:


with full conversation, large
images, smart replies
 The power options now has a
"screenshot" button
 Biometric authentication can
now be disabled only once

Neural networks API for


 Show battery level in "Quick
artificial intelligence
Settings" for devices connected
via Bluetooth Shared memory API
 Navigation buttons dim when
not in use Wallpaper Colors API
 UI updates to 'Power Off' and
'Restart' Programmatic Safe
Android 2017
Oreo  Toast messages are now white Browsing actions 27
8.1 Dec 5
in color with same existing
Autofill framework
transparency
updates
 Automatic light and dark
themes Go Edition: lightweight
 Emoji updates (ie: Hamburger Android distribution for
move the cheese slice position)
devices with less than 1
GB of RAM
 PIP: Picture-in-Picture with
resizable windows
 Android Instant apps
Android 2017
Oreo  Improved notifications system 26
8.0 Aug 21
 Improved system settings
 Lock screen redesign
8

 Battery usage alerts


Android 2017
Nougat  Nexus and Pixel specific 25
7.1.2 Apr 4
improvements

 Long press on the app icon


enable new launch actions
2016
Nougat 
Android The default keyboard allows 25
7.1.1 Dec 5
now to send GIFs directly
 New set of emojis

Shortcut manager APIs

Support Circular app


icons

Keyboard image
 Daydream Virtual Reality mode insertion
 Night Light
 Storage manager improvements VR thread scheduling
 Performance improvements for improvements
Android Touch and Display 2016
Nougat 25
7.1 Enhanced wallpaper Oct 4
managements
 Option to enable fingerprint metadata
swipe down gesture
Multi-endpoint call
 Seamless system updates
support

Source type support for


Visual Voicemail

Carrier config options to


manage video telephony
 Unicode 9.0 emoji
 Better multitasking Sustained Performance
 Multi-window mode (PIP, Mode (SPM) API
Freeform window)
Android Vulkan 3D rendering 2016
Nougat  Seamless system updates (with 24
7.0 API Aug 22
dual system partition)
 Better performance and code
Daydream virtual reality
size thanks to new JIT
Compiler platform
9

Android Marshmall 2015


New emojis 23
6.0.1 ow Dec 7

USB Type-C support
 Fingerprint Authentication
support Custom Chrome Tabs for
 Better battery life with "deep better in app browser
Marshmall sleep" support 2015
Android 6 23
ow Oct 5
 Permissions dashboard
 Android Pay App Permissions
 MIDI support management update
 Google Now improvements

 Speed improvement
Android 2015
Lollipop Bug fixes 22
5.1.1 Apr 21

 Multiple SIM cards support


 Quick settings shortcuts to join
Wi-Fi networks or control
Bluetooth devices
Android 2015
Lollipop Lock protection if lost or stolen 22
5.1 Mar 9
 High Definition voice call
 Stability and performance
enhancements

 Performance improvements and


Android 2014
Lollipop bug fixes 21
5.0.2 Dec 19

 bug fixes, fix issues with video


Android 2014
Lollipop playback and password failures 21
5.0.1 Dec 2

 New design (Material design)


Several new API
 Speed improvement
Android 2014
Lollipop Battery consumption 21
5.0 Tracking battery Oct 17
improvement consumption app

 Fix Heartbleed / OpenSSL


Android 2014
KitKat vulnerability 19
4.4.4 Jun 23

Android  Bug fixes 2014


KitKat 19
4.4.3  Enable Sprint Spark band 26 Apr 14
10

and band 41

 Bug fixes
Android 2013
KitKat  Security enhancements 19
4.4.2 Dec 9

 Bug fixes
2013
KitKat 
Android Enhance the camera on the 19
4.4.1 Dec 5
Nexus 5

Public API for SMS


management.

Improved memory usage

Security enhancements
(SELinux enforcing
mode, new cryptographic
algorithms, VPN per
user...)

NFC Host Card


Emulation (for wireless
 Screen recording
payment, loyalty
 New Translucent system UI
programs...)
 Enhanced notification access
Android 2013
KitKat  System-wide settings for closed Printing Framework 19
4.4 Oct 31
captioning
 Performance improvements Storage Access
Framework

Hardware Sensor
Batching

Full-screen immersive
mode

GLES2.0 SurfaceFlinger

Chromium WebView

Audio tunneling to DSP


11

Audio monitoring

Wi-Fi certified Miracast

New Bluetooth profile

IR Blasters API

Wi-Fi Tunneled Direct


Link Setup (TDLS)
support

Tools for analyzing


memory use (procstats,
on-device memory status
and profiling)
 Dial pad auto-complete
 Photo Sphere enhancements
 Camera app UI updated OpenGL for Embedded
 4K resolution support Systems 3.0 graphics
 Ability to create restricted support
profiles for tablets
Logging and analyzing
 Hebrew and Arabic right-to-left
Android enhancements 2013
Jelly Bean (RTL) support 18
4.3 Jul 24
 Bluetooth Low Energy (BLE)
Wi-Fi scanning API
support
 Bluetooth Audio/Video Remote Improved DRM (digital
Control Profile (AVRCP) 1.3 rights management) API
support
 Security and performance VP8 encoding
enhancements

 Allow toggling Wi-Fi and


Bluetooth state in Quick
Settings using long-press
Secure USB debugging
 Shows the percentage and
Android (allow debugging to 2013
Jelly Bean estimated time remaining in the 17
4.2.2 authenticated computers Feb 11
active download notifications
only)
 Wireless charging and low
battery sounds changed
 Gallery app updated for faster
12

loading with new image


transition
 Performance enhancements and
bug fixes (Bluetooth A2DP
audio streaming fix...)

 Fix missing december bug in


the People app
Android  Add support for Bluetooth 2012
Jelly Bean 17
4.2.1 Nov 27
gamepads and joysticks HID
devices

vsync timing

Triple buffering

reduced touch latency

CPU input boost

Native RTL support -


 Lockscreen widgets mirrors the display from
 360 degree images with Photo manifest prop
Sphere
 Gesture Typing, for faster External display support
typing - Display Manager
Android 2012
Jelly Bean
 Wireless display with Miracast 17
4.2 Nov 13
Nested fragments
 Daydream to display
information when idle or Renderscript Compute -
docked run tasks on the GPU
 Multi-user for tablets
(supported devices)

Renderscript
ScriptGroups, built-in
intrinsics like blur,

FilterScript is a subset of
Renderscript made for
high performance image
processing
Android Jelly Bean
 Enable Home screen rotation 2012 16
13

4.1.2  Fix bugs and enhance Oct 9


performances

Android  Fix a bug on screen orientation 2012


Jelly Bean 16
4.1.1 Jul 23
app stack navigation to
define a parent activity in
manifest for deep
navigation

MediaActionSound class
 Google Now to make sounds like
( [Link] ) when a camera takes a
 Voice Search photo
 Speed enhancements
Android NFC supports large 2012
Jelly Bean
 Camera app improvements 16
4.1 Jul 9
payloads over bluetooth
 Accessibility: gesture mode,
enable braille external WIFI/WIFI-Direct
keyboards... service discovery

Large, detailed, multi-


action notifications

Input manager allows


you to query input
devices
 stability improvements
Android Ice Cream
 better camera performance 2012
15
4.0.4 Sandwich Mar 28
 smoother screen rotation

 Social stream API in Contacts


provider to show updates
associated to your contacts
 Video stabilization and QVGA
Android Ice Cream 2011
15
4.0.3 Sandwich video resolution API access Dec 16
 Accessibility API refinements
for screen readers
 Calendar provider updates

Android Ice Cream 2011


Minor fixes 14
4.0.2 Sandwich Nov 28
14

 Facial recognition (Face


Unlock)
 UI use Hardware acceleration
 Better voice recognition
(dictating/Voice typing)
Android Ice Cream
 Web browser, allows up to 16 2011
14
4.0.1 Sandwich Oct 19
tabs
 Updated launcher
(customizable)
 Android Beam app to exchange
data through NFC

Low-level streaming
multimedia (Khronos
OpenMAX AL

Grid Layout

Spell checking service


 New lock screen actions
 Improved text input and spell- Address Space Layout
checking Randomization
 Control over network data
Android Ice Cream 2011
 Email app supports EAS v14 VPN client API 14
4.0 Sandwich Oct 18
 WI-FI direct
Remote Device camera
 BlueTooth Health Device
enable/disable
Profile

ZSL exposure,
continuous focus, and
image zoom

Flags to help control


system ui elements like
system bar from apps
Android Honeycom 2012
Minor fixes 13
3.2.6 b Feb 15
Android Honeycom Added "Pay as you go" for 2011
13
3.2.4 b tablets Dec 15
Android Honeycom 2011
Minor fixes 13
3.2.2 b Sep 30
Android Honeycom 2011
 Android Market updates 13
3.2.1 b Sep 20
15

including easier automatic


updates
 Google Books updates
 Wi-Fi improvements
 Chinese handwriting prediction
improved

Extended API for


managing screens
support

 Optimizations for a wider range New resource qualifiers


of tablets for screens support
Android Honeycom
 Compatibility display mode 2011
13
3.2 b New manifest attributes Jul 15
(zoom for fixed-sized apps)
 Media sync from SD card
for screen-size
compatibility

Screen compatibility
mode which allows for
phone apps to appear as
if they were still on a
phone
 UI improvements
 Open Accessory API
 USB host API
 Mice, joysticks, gamepads...
Android 3. Honeycom 2011
support 12
1 b May 10
 Resizable Home screen widgets
 MTP notifications
 RTP API for audio

 Multi core support contextual action bar


 Better tablet support
 Updated 3D UI Fragments first
Android Honeycom 2011
introduced(support 11
3.0 b Feb 22
customizable home screens library now supports it as
well)
o recent applications viewing
16

o redone keyboard layout Hardware-accelerated 2D


 Media/Picture transport graphics
protocol
 Google Talk video chat Renderscript 3D graphics
 Google eBooks engine
 "Private browsing"
Pluggable DRM
 System-wide Clipboard
framework
 HTTP Live streaming

device administration

High performance
Animation Framework

RTP streaming API

Forced rendering of
layers

High performance WIFI


lock

View network traffic


stats

ADTS AAC and FLAC


audio

LRU cache
 Google Wallet support for the
Android Gingerbrea 2011
Nexus S 4G 10
2.3.7 d Sep 21

Android Gingerbrea
 Voice search issue fixed 2011
10
2.3.6 d Sep 2
 Improved network performance
for the Nexus S 4G
Android Gingerbrea
 Fixed Bluetooth issues on the 2011
10
2.3.5 d Jul 25
Samsung Galaxy S
 Gmail app. improvements

Android 2. Gingerbrea 2011


 Voice or video chat using Open Accessory API 10
3.4 d May 10
17

Google Talk

NFC API improvements


(peer to peer
Android Gingerbrea communication...) 2011
10
2.3.3 d Feb 9
added unsecure bluetooth
sockets
performance - concurrent
garbage collection, faster
event distribution,
updated video drivers

NDK - Native Asset


 Updated UI Manager, Native
 Improved keyboard ease of use
Activities + event
 Improved copy/paste
handling, khronos api
 Improved power management
Android Gingerbrea
 Social networking features audio effects api 2010
9
2.3 d Dec 6
 Near Field Communication
support VP8, WebM, AAC,
 Native VoIP/SIP support AMR wideband
 Video call support
Multiple camera sensor
support

strictmode debugging

media framework
replaces OpenCore
 Speed improvements
 JIT implementation
 USB Tethering
 Applications installation to the
Android 2010
Froyo expandable memory 8
2.2 May 20
 Upload file support in the
browser
 Animated GIFs

2010
Eclair 
Android Updated UI 7
2.1 Jan 12
Android Eclair 2009 6
18

2.0.1 Dec 3
 HTML
 Digital zoom
 Microsoft Exchange support
Android 2009
Eclair  Bluetooth 2.1 5
2.0 Oct 26
 Live Wallpapers
 Updated UI

 Gesture framework
Android 2009
Donut  Turn-by-turn navigation 4
1.6 Sep 15

 Bluetooth A2DP, AVRCP


support
2009
Cupcake
Android Soft-keyboard with text- 3
1.5 Apr 30
prediction
 Record/watch videos

 "Show" & "Hide" numeric


keyboard, in caller application
Android 1. Banana bre 2009
 Ability to save MMS 2
1 ad Feb 9
attachments

 Download and updates via


Android Market,
 Web Browser,
 Camera support,
Android 1. 2008
Apple pie
 Gmail, Contacts and Google 1
0 Sep 23
Agenda synchronization
 Google Maps
 YouTube application

Android 0. 2008
9 Aug 22
19

Android Software Stack

Linux Kernel

At the core of the Android platform is a Linux kernel responsible for device drivers, resource access,
power management, and other OS duties. The supplied device driversinclude Display, Camera,
Keypad, Wi-Fi, Flash Memory, Audio, and inter-processcommunication (IPC).

Native Libraries

On top of the kernel, are a number of C/C++ libraries such as,

 The C runtime library (libc)


 A media library for playback of audio and video media
 A surface manager to provide display management
 Graphics libraries that include SGL and OpenGL for 2D and 3D graphics
 SQLite for native database support
 SSL and WebKit for integrated web browser and Internet security
 The FreeType library is responsible for font support.
20

Android Runtime

Android run time is the engine that powers your applications and, along with the libraries, forms the
basis for the application framework. It includes

 Core libraries: The core Android libraries providemost of the functionality available in the core
Java libraries, as well as the Android-specific libraries.
 DalvikVM: Dalvik VM is a register-based Virtual Machine that‘s been optimized to ensure that
a device can run multiple instances efficiently. It relies on the Linux kernel for threading and
low-level memory management.

Application framework

The application framework provides the classes used to createAndroid applications. It also provides a
generic abstraction for hardware access and managesthe user interface and application resources.

 Activity Manager - Control the lifecycle of Activities.


 Views — Used to construct the user interfaces for Activities
 Notification Manager — Provides a consistent and nonintrusive mechanism for signaling Users
 Content Providers — Lets your applications share data
 Resource Manager — Enables non-code resources, such as strings and graphics, to be
externalized.
 Intents — Provides a mechanism for transferring data between applications and their
components.
 Package managers (installation, security).
 Telephony - Provides a Global System for Mobile Communication (GSM).
 Bluetooth / NFC / Wi-Fi Direct - supports Bluetooth, Wi-Fi, NFC etc.

Programmers develop end-user applications on top of this Java API.

Application Layer

It is a Collection of built-in and 3rd party apps.

 Built-in apps - Phone and Web Browser


 Google and 3rd party apps uses same APIsand goes through same approval process
 Built-in applications can be stopped touse 3rd party apps
21

Dalvik Virtual Machine (DVM)

One of the key elements of Android is the Dalvik VM. Rather than using a traditional Java VM,
Android uses its own custom VM designed to ensure that multiple instances run efficiently on a single
device. The Dalvik VM uses the device‘s underlying Linux kernel to handle low-level functionality,
including security, threading, and process and memory management. By using a VM to host
application execution, developers should never have to worry about a particular hardware
implementation.

The Dalvik VM executes Dalvik executable files, a format optimized to ensure minimal memory
footprint. You create .dex executables by transforming Java language compiled classes using the tools
supplied within the SDK.

Fundamental Components of an Android Application

Application components are the essential building blocks of an Android application. These
components are loosely coupled by the application manifest file [Link] that describes
each component of the application and how they interact.

There are following four main components that can be used within an Android application:
Activity, Service, Broadcast Receivers and Content providers. There are additional components
which will be used in creating android apps. They are Fragments, Views, Layouts, and Intents,
Resources etc.
22

Activity

An Activity is an application component that provides a screen with which users can interact in order
to do something, such as dial the phone, take a photo, send an email, or view a map. Each activity is
given a window in which to draw its user interface. The window typically fills the screen, but may be
smaller than the screen and float on top of other windows.

An application usually consists of multiple activities that are loosely bound to each other. Typically,
one activity in an application is specified as the "main" activity, which is presented to the user when
launching the application for the first time. Each activity can then start another activity in order to
perform different actions. Each time a new activity starts, the previous activity is stopped, but the
system preserves the activity in a stack (the "back stack"). When a new activity starts, it is pushed onto
the back stack and takes user focus. The back stack abides to the basic "last in, first out" stack
mechanism, so, when the user is done with the current activity and presses the Back button, it is
popped from the stack (and destroyed) and the previous activity resumes.

When an activity is stopped because a new activity starts, it is notified of this change in state through
the activity's lifecycle callback methods. There are several callback methods that an activity might
receive, due to a change in its state—whether the system is creating it, stopping it, resuming it, or
destroying it—and each callback provides you the opportunity to perform specific work that's
appropriate to that state change.

For instance, when stopped, your activity should release any large objects, such as network or database
connections. When the activity resumes, you can reacquire the necessary resources and resume actions
that were interrupted. These state transitions are all part of the activity [Link] an activity
transitions into and out of the different states described above, it is notified through various callback
methods. All of the callback methods are hooks that you can override to do appropriate work when the
state of your activity changes.
23

Activity lifecycle

Life cycle methods

Method Description

onCreate() Called when the activity is first created. This is where you should do all of
your normal static set up — create views, bind data to lists, and so on. This
method is passed a Bundle object containing the activity's previous state, if
that state was captured.
24

onRestart() Called after the activity has been stopped, just prior to it being started again.

onStart() Called just before the activity becomes visible to the user.

onResume() Called just before the activity starts interacting with the user. At this point the
activity is at the top of the activity stack, with user input going to it.

onPause() Called when the system is about to start resuming another activity. This
method is typically used to commit unsaved changes to persistent data, stop
animations and other things that may be consuming CPU, and so on. It should
do whatever it does very quickly, because the next activity will not be
resumed until it returns.

onStop() Called when the activity is no longer visible to the user. This may happen
because it is being destroyed, or because another activity (either an existing
one or a new one) has been resumed and is covering it.

onDestroy() Called before the activity is destroyed. This is the final call that the activity
will receive. It could be called either because the activity is finishing, or
because the system is temporarily destroying this instance of the activity to
save space.

The following skeleton activity includes each of the fundamental lifecycle methods:

public class ExampleActivity extends Activity

{
public void onCreate(Bundle savedInstanceState)

{
[Link](savedInstanceState); // The activity is being created.
}
protected void onStart()

{
[Link](); // The activity is about to become visible.
}
protected void onResume()

{
[Link](); // The activity has become visible (it is now "resumed").
}
protected void onPause()

{
[Link](); // Another activity is taking focus (this activity is about to be "paused").
25

}
protected void onStop()

{
[Link](); // The activity is no longer visible (it is now "stopped")
}

protected void onDestroy()

{
[Link](); // The activity is about to be destroyed.
}
}

The entire lifetime of an activity happens between the call to onCreate() and the call to onDestroy().
Setup of "global" state (such as defining layout) should be in onCreate(), and release of all remaining
resources is in onDestroy(). For example, a thread running in the background to download data from
the network, might be defined in onCreate() and then stop the thread in onDestroy().

The visible lifetime of an activity happens between the call to onStart() and the call to onStop().
During this time, the user can see the activity on-screen and interact with it. Between these two
methods, you can maintain resources that are needed to show the activity to the user. The system
might callonStart() and onStop() multiple times during the entire lifetime of the activity, as the activity
alternates between being visible and hidden to the user.

The foreground lifetime of an activity happens between the call to onResume() and the call
to onPause(). During this time, the activity is in front of all other activities on screen and has user
inputfocus. An activity can frequently transition in and out of the foreground—for
example, onPause() is called when the device goes to sleep or when a dialog appears. Because this
state can transition often, the code in these two methods should be fairly lightweight in order to avoid
slow transitions that make the user wait.

Service

A Service is an application component that can perform long-running operations in the background
and does not provide a user interface. Another application component can start a service and it will
continue to run in the background even if the user switches to another application. Additionally, a
component can bind to a service to interact with it and even perform inter-process communication
(IPC). For example, a service might handle network transactions, play music, perform file I/O, or
interact with a content provider, all from the background.

Android defines twotypes of services: local services and remote services. Local services are
components that are only accessible by the application that is hosting the service. Conversely, remote
services are services that are meant to be accessed remotely by otherapplications running on the
device. Each service extends the Service base class.

A service can essentially take two states –


26

Started : A service is started when an application component, such as an activity, starts it by


calling startService(). Once started, a service can run in the background indefinitely, even if the
component that started it is destroyed.
Bound : A service is bound when an application component binds to it by calling bindService(). A
bound service offers a client-server interface that allows components to interact with the service, send
requests, get results etc.
Broadcast Receivers
Broadcast Receivers simply respond to broadcast messages from other applications or from the
system. Examples: Battery low, External powerconnected/disconnected, Screen on/off areexample of
system generated broadcasts. SMS or Email App can broadcast that SMS orEmail is received.
Applications can also initiate broadcasts to let other applications know that some data has been
downloaded to the device and is available for them to use, so this is broadcast receiver who will
intercept this communication and will initiate appropriate action.

Broadcast receivers are dormant listeners that can register for various system or application events
(intents).
Static Registration - done in the manifest file using intentfilters
Dynamic Registration – done at runtime
Local broadcast - within app components
Global broadcast – system wide communication

A broadcast receiver is implemented as a subclass of BroadcastReceiver class and each message is


broadcaster as an Intent object.

Normal broadcasts are completely asynchronous. All receivers of the broadcast are run in an
undefinedorder, often at the same time. Ordered broadcasts are delivered to one receiver at a time. As
each receiver executes in turn, it can propagate aresult to the next receiver, or it can completely abort
thebroadcast so that it won't be passed to other receivers.

Content Provider

Data sharing among mobile applications on a device is common. Therefore, Android defines a
standard mechanism for applications to share data (such as a list of contacts) without exposing the
underlying storage, structure, and implementation. Through content providers, you can expose your
data and have your applications use data from other applications.

View and View Groups

Views are user interface (UI) elements that form the basic building blocks of a user interface. A view
can be a button, a label, a text field, or many other UI elements. Views are also used as containers for
views, which means there‘s usually a hierarchy of views in the UI.

All user interface elements in an Android app are built using View and ViewGroup objects. A View is
an object that draws something on the screen that the user can interact with. ViewGroup is an object
27

that holds other View (and ViewGroup) objects in order to define the layout of the interface. Views
are organized as tree to build up GUIs. Views are described in XML in layout resources.

Fragment

When a screen is large, it becomes difficult to manage all of its functionality in a single activity.
Fragments are like sub-activities, and an activity can display one or more fragments on the screen at
the same time. When a screen is small, an activity is more likely to contain just one fragment, and that
fragment can be the same one used within larger screens.

Intent

An intent generically defines an ―intention‖ to do some work. Intents can be used to perform the
following tasks:

 Broadcast a message.
 Start a service.
 Launch an activity.
 Display a web page or a list of contacts.
 Dial a phone number or answer a phone call.

Intents are not always initiated by your application—they‘re also used by the system to notify your
application of specific events (such as the arrival of a text message). Intents can be explicit or implicit.
If you simply say that you want to display a URL, the system decides what component will fulfill the
intention. You can also provide specific information about what should handle the intention. Intents
loosely couple the action and action handler.

Notifications

A notification is a message displayed to the user outside of application's normal UI. Notifications are
issued by system through Notification Manager. Notification first appears as an icon in the notification
area. To see details of notification, user shall opens the notification drawer. Both the notification area
and the notification drawer are system-controlled areas that the user can view at any time. A
Notification is an object of Notification class. It notifies the user about events through
NotificationManager.

Resources

Resources are the additional files and static content that your code uses, such as bitmaps, layout
definitions, user interface strings, animation instructions, and more. Always externalize resources such
as images and strings from your application code, so that you can maintain them independently.
Externalizing your resources also allows you to provide alternative resources that support specific
device configurations such as different languages or screen sizes. Organized in /res project directory.

Default resources are those that should be used regardless of the device configuration or when there
are no alternative resources that match the current configuration. Alternative resources are those that
you've designed for use with a specific configuration. Example, while your default UI layout is saved
in the res/layout/ directory, you might specify a different layout to be used when the screen is in
landscape orientation.
28

String resources are defined in xml files and stored in /res/values folder. Layout resources are defined
in xml file and stored in /res/layout folder. An example is given below.

[Link] file

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


<LinearLayout xmlns:android="[Link]
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Welcome this is my first program" />
</LinearLayout>
When this file is created or updated, android automatically creates or updates a Java class in your
application‘s root package called [Link] with unique IDs for different resources specified. Regardless
of the number of resource files, there is only one [Link] file.

[Link]

[Link], defines the contents and behavior of your application. For example, it lists your
application‘s activities and services, along with the permissions and features the application needs to
run. Every application must have an [Link] file in its root directory.

 It describes the components of the application.


 It determines which processes will host application components.
 It declares which permissions the application must have in order to access protected parts of
the API and interact with other applications.
 It also declares the permissions that others are required to have in order to interact with the
application's components.
 It declares the minimum level of the Android API that the application requires.
 It lists the libraries that the application must be linked.

The manifest is made up of a root manifest tag

<manifest> tag
<manifest xmlns:android=‖[Link]
package=―[Link]―
android:versionCode=―1―
android:versionName=―0.9 Beta―
android:installLocation=―preferExternal―>
29

[ ... manifest nodes ... ]

</manifest>

Attributes
package describes project‘s package.
xmlns:android supplies several system attributes used within the file.
versionCode defines the current application version as an integer
versionName specify a public version that will be displayed to users.
installLocation specify whether to allow your application be installed on external storage
(usually an SD card) rather than internal storage. The value can be
preferExternal or auto, where the former installs to external storage whenever
possible, and the latter asks the system to decide.

The manifest tag can include nodes that define the application components, security settings, test
classes, and requirements that make up your application.

The following list gives a summary of the available manifest sub-node tags.
<uses-sdk>
This node enables you to define a minimum and maximum SDK version that must be available on a
device for your application to function properly, and target SDK for which it has been designed using
a combination of minSDKVersion, maxSDKVersion, and targetSDKVersionattributes, respectively.
<uses-sdk
android:minSdkVersion=‖6‖
android:targetSdkVersion=‖15‖/>

<application>
A manifest can contain only one application node. It uses attributes tospecify the metadata for your
application (including its title, icon, and theme). During developmentyou should include a debuggable
attribute set to true to enable debugging. The application node also acts as a container for the Activity,
Service, Content Provider, and Broadcast Receiver nodes that specify the application components.
You specify the name of your custom application class using the android:name attribute.

<application
android:icon=‖@drawable/icon‖
android:logo=‖@drawable/logo‖
android:theme=‖@android:style/[Link]‖
android:name=‖.MyApplicationClass‖
android:debuggable=‖true‖>

[ ... application nodes ... ]

</application>

<activity>— An activity tag is required for every Activity within your application. Use the
android:name attribute to specify the Activity class name. You must include the main launch Activity
30

and any other Activity that may be [Link] to start an Activity that‘s not defined in the
manifest will throw a runtime error.

<activity
android:name=‖.MyActivity‖
android:label=‖My New App‖>
<intent-filter>
<action android:name=‖[Link]‖ />
<category android:name=‖[Link]‖ />
</intent-filter>
</activity>
The android:label attributes specifies a string to use as the label for the activity. You can specify
multiple activities using <activity> tags.

The action for the intent filter is named [Link] to indicate that this activity
serves as the entry point for the application. The category for the intent-filter is
named [Link] to indicate that the application can be launched from the
device's launcher icon.

<service>
As with the activity tag, add a service tag for each Service classused in your application. Service tags
also support intent-filter child tags toallow late runtime binding.
<service android:name=‖.MyService‖>
</service>

<provider>
Provider tags specify each of your application‘s Content Providers. Content Providers are used to
manage database access and sharing.

<provider android:name=‖.MyContentProvider‖
android:authorities=‖[Link]‖/>

<receiver>
By adding a receiver tag, you can register a Broadcast Receiver withouthaving to launch your
application first. BroadcastReceivers are like global event listeners that, when registered, will execute
whenevera matching Intent is broadcast by the system or an application. By registering aBroadcast
Receiver in the manifest you can make this process entirely autonomous. Ifa matching Intent is
broadcast, your application will be started automatically andthe registered Broadcast Receiver will be
executed. Each receiver node supportsintent-filter child tags that define the Intents that can be used to
trigger thereceiver:

<receiver android:name=‖.MyIntentReceiver‖>
<intent-filter>
<action android:name=‖[Link]‖ />
</intent-filter>
</receiver>
31

<uses-library>
It is used to specify a shared library that this application requires. Forexample, Maps, Geocoding, and
Location-Based Services, are packaged as a separate library that is not automatically linked.
You can specify that a particular package is required — which prevents the applicationfrom being
installed on devices without the specified library — or optional,in which case your application must
use reflection to check for the library beforeattempting to make use of it.
<uses-library
android:name=‖[Link]‖
android:required=‖false‖/>

Create a Project with Android Studio

A project in Android Studio contains everything that defines your workspace for an app, from source
code and assets, to test code and build configurations. When you start a new project, Android Studio
creates the necessary structure for all your files and makes them visible in the Project window on the
left side of the IDE (click View > Tool Windows > Project). This page provides an overview of the
key components inside your project.

1. In Android Studio, create a new project:

 If you don't have a project opened, in the Welcome screen, click New Project.
 If you have a project opened, from the File menu, select New Project. The Create New
Project screen appears.

2. Fill out the fields on the screen, and click Next.

It is easier to follow these lessons if you use the same values as shown.
 Application Name is the app name that appears to users. For this project, use "My First App."
 Company domain provides a qualifier that will be appended to the package name; Android
Studio will remember this qualifier for each new project you create.
 Package name is the fully qualified name for the project (following the same rules as those for
naming packages in the Java programming language). Your package name must be unique
across all packages installed on the Android system. You can Edit this value independently
from the application name or the company domain.
 Project location is the directory on your system that holds the project files.

3. Under Select the form factors your app will run on, check the box for Phone and Tablet.

4. For Minimum SDK, select API 8: Android 2.2 (Froyo).

The Minimum Required SDK is the earliest version of Android that your app supports, indicated
using the API level. To support as many devices as possible, you should set this to the lowest
version available that allows your app to provide its core feature set. If any feature of your app is
32

possible only on newer versions of Android and it's not critical to the app's core feature set, you can
enable the feature only when running on the versions that support it
Leave all of the other options (TV, Wear, and Glass) unchecked and click Next.
5. Under Add an activity to <template>, select Basic Activity and click Next.

6. Under Customize the Activity, change the Activity Name to MainActivity. The Layout
Name changes to activity_main, and the Title to MainActivity. The Menu Resource
Name is menu_main.

7. Click the Finish button to create the project.


33

Structure of the Android Application


34

When you select Project view, you can see a lot more files and directories. The most important of
which are the following:
module-name/ (app is the module in the above fig.)
build/ Contains build outputs.
libs/ Contains private libraries.
src/ Contains all code and resource files for the module in the following
subdirectories:
androidTest/ Contains code for instrumentation tests that run on an Android device.
main/ Contains the "main" source set files: the Android code and resources shared by
all build variants. It has the following sub directories. java, ini, gen, res, assets
and test.
java/ Contains Java code sources. Eg. [Link]
jni/ Contains native code using the Java Native Interface (JNI).
gen/ Contains the Java files generated from xml files, such as [Link]
res/ Contains application resources, such as drawable files, layout files, and UI string.

drawable-<density>/ Directories for drawable resources, other than launcher icons, designed for
various densities.

layout/ Directory for files that define your app's user interface like activity_my.xml,
discussed above, which describes a basic layout for the MyActivityclass.

menu/ Directory for files that define your app's menu items.

mipmap/ Launcher icons reside in the mipmap/ folder rather than the drawable/ folders.
This folder contains the ic_launcher.png image that appears when you run the
default app.

values/ Directory for other XML files that contain a collection of resources, such as
string and color definitions.

assets/ Contains file that should be compiled into an .apk file as-is. You can navigate
this directory in the same way as a typical file system using URIs and read files
as a stream of bytes using the AssetManager . For example, this is a good
location for textures and game data.
test/ Contains code for local tests that run on your host JVM.
35

[Link] Describes the nature of the application and each of its components
[Link] (module) This defines the module-specific build configurations.
[Link] (project) This defines your build configuration that apply to all modules. This
file is integral to the project, so you should maintain them with all other
source code.

activity_main.xml

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


<LinearLayout xmlns:android="[Link]
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Welcome to my first app">
</LinearLayout>

[Link]
import [Link];
import [Link];

public class MainActivity extends Activity {


public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
}
}

[Link]

<manifest xmlns:android="[Link]
36

package="[Link]" android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="22"/>
<application android:label=‖My First App "
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="[Link]"/>
<category android:name="[Link]"/>
</intent-filter>
</activity>
</application>
</manifest>

The R File

The [Link] file is the glue between the activity Java files like [Link] and the resources
like [Link]. It is an automatically generated file and you should not modify the content of the
[Link] file. Following is a sample of [Link] file −

/* AUTO-GENERATED FILE. DO NOT MODIFY.

* This class was automatically generated by the

* aapt tool from the resource data it found. It

* should not be modified by hand.

*/

[Link];

public final class R {

public static final class attr{}

public static final class dimen

public static final int padding_large=0x7f040002;

public static final int padding_medium=0x7f040001;

public static final int padding_small=0x7f040000;

}
37

public static final class drawable

public static final int ic_action_search=0x7f020000;

public static final int ic_launcher=0x7f020001;

public static final class layout

public static final int main=0x7f030000;

public static final class string

public static final int app_name=0x7f050000;

public static final int hello_world=0x7f050001;

public static final int title_activity_main=0x7f050003;

Run on a Real Device


If you have a device running Android, here's how to install and run your app.

Set up your device

1. Plug in your device to your development machine with a USB cable. If you're developing on
Windows, you might need to install the appropriate USB driver for your device.

2. Enable USB debugging on your device. On Android 4.0 and newer, go to Settings >
Developer options.
38

Note: On Android 4.2 and newer, Developer options is hidden by default. To make it available, go
to Settings > About phone and tap Build number seven times. Return to the previous screen to
find Developer options.

Run the app from Android Studio

1. Select one of your project's files and click Run from the toolbar.

2. In the Choose Device window that appears, select the Choose a running device radio button,
select your device, and click OK .

Android Studio installs the app on your connected device and starts it.

Run on the Emulator

Whether you're using Android Studio or the command line, to run your app on the emulator you need
to first create an Android Virtual Device (AVD). An AVD is a device configuration for the Android
emulator that allows you to model a specific device.

Create an AVD

1. Launch the Android Virtual Device Manager:


2. In Android Studio, select Tools > Android > AVD Manager, or click the AVD Manager

icon in the toolbar. The AVD Manager screen appears.


3. On the AVD Manager main screen, click Create Virtual Device.
4. In the Select Hardware window, select a device configuration, such as Nexus 6, then
click Next.
5. Select the desired system version for the AVD and click Next.
6. Verify the configuration settings, then click Finish.

Run the app from Android Studio

1. In Android Studio, select your project and click Run from the toolbar.

2. In the Choose Device window, click the Launch emulator radio button.

3. From the Android virtual device pull-down menu, select the emulator you created, and
click OK.
39

It can take a few minutes for the emulator to load itself. You may have to unlock the screen. When you
do, My First App appears on the emulator screen.
THE ANDROID APPLICATION LIFECYCLE
The life cycle of an Android application is strictly managed by the system, based on the user‘s needs,
available resources, and so on. A user may want to launch a web browser, for example, but the system
ultimately decides whether to start the application. Although the system is the ultimate manager, it
adheres to some defined and logical guidelines to determine whether an application can be loaded,
paused, or stopped. If the user is currently working with an activity, the system gives high priority to
that application. Conversely, if an activity is not visible and the system determines that an application
must be shut down to free up resources, it shuts down the lower-priority application.

Android runs each application in a separate process, each of which hosts its own virtual machine. This
provides a protected-memory environment. By isolating applications to an individual process, the
system can control which application deserves higher priority. For example, a background process
that‘s doing a CPU-intensive task can‘t block an incoming phone call.

Let‘s consider a typical scenario. A user is talking to someone on the phone and needs to open an e-
mail message to answer a question. The user goes to the home screen, opens the mail application,
opens the e-mail message, clicks a link in the e-mail, and answers the friend‘s question by reading a
stock quote from a web page. This scenario requires four applications: the home application, a talk
application, an e-mail application, and a browser application. As the user navigates from one
application to the next, the experience is seamless. In the background, however, the system is saving
and restoring application state. For instance, when the user clicks the link in the e-mail message, the
system saves metadata on the running e-mail message activity before starting the browser-application
activity to launch a URL. In fact, the system saves metadata on any activity before starting another so
that it can come back to the activity (when the user backtracks, for example). If memory becomes an
issue, the system has to shut down a process running an activity and resume it as necessary.

UNDERSTANDING AN APPLICATION‘S PRIORITY AND ITS PROCESS‘ STATES

All Android applications continue running and in memory until the system needs resources for other
applications.

Figure 3-4 shows the priority tree used to determine the order of application termination.

It‘s important to structure your application to ensure that its priority is appropriate for the work it‘s
doing. If you don‘t, your application could be killed while it‘s in the middle of something important,
or it could remain running when it is no longer needed.
40

The following list details each of the application states shown in Figure 3-4, explaining how the state
is determined by the application components of which it comprises:

Active processes — Active (foreground) processes have application components the user is interacting
with. These are the processes Android tries to keep responsive by reclaiming resources from other
applications. Active processes include the following:

Visible processes — Visible but inactive processes, they aren‘t in the foreground or responding to user
events.

Started Service processes — Processes hosting Services that have been started. Because these Services
don‘t interact directly with the user, they receive a slightly lower priority than visible.

Background processes — Processes hosting Activities that aren‘t visible and that don‘t have any
running Services. There will generally be a large number of background processes that Android will
kill using a last-seen-first-killed pattern in order to obtain resources for foreground processes.

Empty processes — To improve overall system performance, Android will often retain an application
in memory after it has reached the end of its lifetime. Android maintains this cache to improve the
start-up time of applications when they‘re relaunched. These processes are routinely killed, as
required.

INTRODUCING THE ANDROID APPLICATION CLASS

An application‘s Application object remains instantiated whenever an application runs. Unlike


Activities, the Application is not restarted as a result of configuration changes. Extending the
Application class with your own implementation enables you to do three things:

 Respond to application level events broadcast by the Android run time such as low memory
conditions.
 Transfer objects between application components.
 Manage and maintain resources used by several application components.

Overriding the Application Lifecycle Events

The Application class provides event handlers for application creation and termination, low memory
conditions, and configuration changes. By overriding these methods, you can implement your own
application-specific behavior for each of these circumstances:

onCreate — Called when the application is created. Override this method to initialize your application
singleton and create and initialize any application state variables or shared resources.

onLowMemory — Provides an opportunity for well-behaved applications to free additional memory


when the system is running low on resources. This will generally only be called when background
processes have already been terminated and the current foreground applications are still low on
memory. Override this handler to clear caches or release unnecessary resources.

onTrimMemory — An application specific alternative to the onLowMemory handler introduced in


Android 4.0 (API level 13). It is called when the run time determines that the current application
should attempt to trim its memory overhead – typically when it moves to the background.
41

onConfigurationChanged — Unlike Activities Application objects are not restarted due to


configuration changes. If your application uses values dependent on specific configurations, override
this handler to reload those values and otherwise handle configuration changes at an application level.

The superclass event handlers must be called when overriding these methods.

LISTING 3-8: Overriding the Application Lifecycle Handlers

public class MyApplication extends Application

private static MyApplication singleton; // Returns the application instance

public static MyApplicationgetInstance()

return singleton;

@Override

public final void onCreate()

[Link]();

singleton = this;

@Override

public final void onLowMemory()

[Link]();

@Override

public final void onTrimMemory(int level)

[Link](level);

@Override

public final void onConfigurationChanged(Configuration newConfig)


42

[Link](newConfig);

Android Java Packages

Here‘s a brief description of the important packages that are included in the Android SDK:

[Link]: Implements the Application model for Android. Primaryclasses include Application,
activity-related classes, fragments, controls, dialogs, alerts, and notifications.

[Link]: Provides classes to manage accounts such asGoogle, Facebook, and so on. The
primary classes are AccountManager and Account.

[Link]: Hosts all the new property animation classes.

[Link]: Provides functionality for home screen widgets.

[Link]: Provides a number of classes to work withBluetooth functionality. The main


classes include BluetoothAdapter, BluetoothDevice, BluetoothSocket, BluetoothServerSocket,
andBluetoothClass.

[Link]: Implements the concepts of content [Link] providers abstract out data
access from data stores. Thispackage also implements the central ideas around intents and
AndroidUniform Resource Identifiers (URIs).

[Link]: Implements package manager–related classes. Apackage manager knows about


permissions, installed packages, installed providers, installed services, installed components such
asactivities, and installed applications.

[Link]: Implements the idea of an abstract database. Theprimary interface is the Cursor
interface.

[Link]: Implements the concepts from the [Link] package using SQLite
as the physical database. Primary classes are SQLiteCursor, SQLiteDatabase, SQLiteQuery,
SQLiteQueryBuilder, and SQLiteStatement. However, most of yourinteraction is going to be with
classes from the abstract [Link] package.

[Link]: Houses all the classes and interfaces necessary towork with user-defined gestures.
Primary classes are Gesture, GestureLibrary, GestureOverlayView, GestureStore, GestureStroke and
43

GesturePoint. A Gesture is a collection of GestureStrokes and GesturePoints. Gestures are collected in


a GestureLibrary. Gesturelibraries are stored in a GestureStore. Gestures are named so that theycan be
identified as actions.

[Link]: Contains the classes Bitmap, Canvas, Camera, Color, Matrix, Movie, Paint.

[Link]: Implements drawing protocols andbackground images, and allows


animation of drawable objects.

[Link]: Implements shapes includingArcShape, OvalShape, PathShape,


RectShape, and RoundRectShape.

[Link]: Implements the physical Camera-related classes. The Camera represents the
hardware camera, whereas [Link] represents a graphical concept that‘s notrelated to
a physical camera at all.

[Link]: Lets you talk to USB devices from Android.

[Link]: Contains the classes Address, GeoCoder, Location, LocationManager, and


LocationProvider. The Address class representsthe simplified Extensible Address Language (XAL).
GeoCoder allowsyou to get a latitude/longitude coordinate given an address, and viceversa. Location
represents the latitude/longitude.

[Link]: Contains the classes MediaPlayer, MediaRecorder, Ringtone, AudioManager, and


FaceDetector. MediaPlayer supports streaming, is used to play audio and video. MediaRecorder is
used to record audio and video. The Ringtone class is used to play short sound snippets that could
serve as ringtones and notifications. AudioManager is responsible for volume controls. You can use
FaceDetector to detect people‘s faces in a bitmap.

[Link]: Manages Wi-Fi connectivity. Primary classes include WifiManager and


WifiConfiguration. WifiManager is responsible for listing the configured networks and the currently
active Wi-Fi network.

[Link] adhering to the [Link] interface. The content providers


include Contacts, MediaStore, Browser, and Settings. This set of interfaces and classes stores the
metadata forthe underlying data structures.

[Link]: PhoneNumberUtils, and TelephonyManager. TelephonyManager lets you


determine cell location, phone number, network operator name,network type, phone type, and
Subscriber Identity Module (SIM) serialnumber
44

[Link] cell towers and also hosts classes responsible for SMS [Link]
package is called GSM because Global System for MobileCommunication is the technology that
originally defined the SMS data-messaging standard.

[Link]: Contains the classes Menu, View, and ViewGroup, and aseries of listeners and
callbacks.

[Link]: Provides support for tweening animation. The main classes include
Animation, a series of interpolators foranimation, and a set of specific animator classes that include
AlphaAnimation, ScaleAnimation, TranslationAnimation, and RotationAnimation.

[Link]: Contains all of the UI controls usually derived fromthe View class. Primary widgets
include Button, Checkbox, Chronometer, AnalogClock, DatePicker, DigitalClock, EditText, ListView,
FrameLayout, GridView, ImageButton, MediaController, ProgressBar, RadioButton, RadioGroup,
RatingButton, Scroller,ScrollView, Spinner, TabWidget, TextView, TimePicker, VideoView, and
ZoomButton.

[Link]: Contains the classes MapView, MapController, and MapActivity,


essentially classes required to workwith Google maps.

Android Development Tools

The Android SDK includes several tools and utilities to create, test and debug android apps. Some of
them are Android Emulator, Android Virtual device manager, Android SDK manager,

The Android Virtual Device Manager

The Android Virtual Device Manager is used to create and manage the virtual devices that will
hostinstances of the [Link] are used to simulate the software builds and hardware
configurations available on differentphysical devices. This lets you test your application on a variety
of hardware platforms withoutneeding to buy a variety of [Link] virtual device is configured
with a name, atarget build of Android (based on the SDK version itsupports), an SD card capacity, and
screen resolution. You can also choose to enable snapshots to savethe Emulator state when it‘s closed.
Starting a newEmulator from a snapshot is significantly faster.

Each virtual device also supports a number of specific hardware settings and restrictions that can
beadded in the form of name-value pairs (NVPs) in thehardware table. The additional settings include
Maximum VM heap size, Screen pixel density, SD card support, Existence of D-pad, touchscreen,
keyboard, and trackball hardware, Accelerometer, GPS, and proximity sensor support, Available
device memory, Camera hardware (and resolution), Support for audio recording, Existence of
hardware back and home keys etc.

Android Emulator

Android emulator is used to run, debug, and test android applications. The real device is not needed
for 90% of the applicationdevelopment. The full-featured Android emulator mimics most of the device
45

[Link] emulator limitations include USB connections, camera and video capture,headphones,
battery simulation, Bluetooth, Wi-Fi, NFC, and OpenGL ES 2.0.

The Android emulator accomplishes its work through an open source ―processor emulator‖ technology
called QEMU, developed by Fabrice Bellard. QEMU allowsemulation at the CPU [Link] the
Android emulator, the processor is based on Advanced RISC Machine (ARM).ARM is a 32-bit
microprocessor architecture based on Reduced Instruction SetComputing (RISC), in which design
simplicity and speed is achieved through a reducednumber of instructions in an instruction set. The
emulator runs the Android version ofLinux on this simulated processor. ARM is widely used in
handhelds and other embedded electronics where lower power consumption is important. Much of the
mobile market uses processors based on thisarchitecture.

Android SDK Manager

The Android SDK Manager can be used to see which version of the SDK you have installed and
toinstall new SDKs when they are released. Each platform release is displayed, along with the
platform tools and a number of additional supportpackages. Each platform release includes the SDK
platform, documentation, tools, and examplescorresponding to that release.

The Dalvik Debug Monitor Service

The Emulator enables you to see how your application will look, behave, and interact, but to actually
see what‘s happening under the surface, you need the Dalvik Debug Monitoring Service. TheDDMS is
a powerful debugging tool that lets you interrogate active processes, view the stack andheap, watch
and pause active threads, and explore the filesystem of any connected Android device.

The Android Debug Bridge

The Android Debug Bridge (ADB) is a client-service application that lets you connect with anAndroid
device (virtual or actual). It‘s made up of three components:

 A daemon running on the device or Emulator


 A service that runs on your development computer
 Client applications (such as the DDMS) that communicate with the daemon through theservice

As a communications conduit between your development hardware and the Android device/Emulator,
the ADB lets you install applications, push and pull files, and run shell commands on thetarget device.
Using the device shell, you can change logging settings and query or modify SQLitedatabases
available on the device.

The ADT tool automates and simplifies a lot of the usual interaction with the ADB, including
application installation and updating, file logging, and file transfer (through the DDMSperspective).

The Hierarchy Viewer and Lint Tool

To build applications that are fast and responsive, you need to optimize your UI. The HierarchyViewer
and Lint tools help you analyze, debug, and optimize the XML layout definitions usedwithin your
[Link] Hierarchy Viewer displays a visual representation of the structure of your UI layout.
Starting atthe root node, the children of each nested View (including layouts) is displayed in a
hierarchy. EachView node includes its name, appearance, and identifier.
46

To optimize performance, the performance of the layout, measure, and draw steps of creating theUI of
each View at runtime is displayed. Using these values, you can learn the actual time taken tocreate
each View within your hierarchy, with colored ―trafficlight‖ indicators showing the
relativeperformance for each step. You can then search within your layout for Views that appear to be
taking longer to render than they should.

The Lint tool helps you to optimize your layouts by checking them for a series of
commoninefficiencies that can have a negative impact on your application‘s performance.
Commonissues include a surplus of nested layouts, a surplus of Views within a layout, and
unnecessaryparent Views.

Monkey and Monkey Runner

Monkey and Monkey Runner can be used to test your applications stability from a UI perspective.
Monkey works from within the ADB shell, sending a stream of pseudo-random system and UIevents
to your application. It‘s particularly useful to stress test your applications to investigate edge cases you
might not have anticipated through unconventional use of the UI.

Alternatively, Monkey Runner is a Python scripting API that lets you send specific UI commands
tocontrol an Emulator or device from outside the application. It‘s extremely useful for performing UI,
functional, and unit tests in a predictable, repeatable fashion.

Setting Up Your Development Environment


Android applications can be developed on either of the following operating systems:

 Microsoft Windows XP or later version.

 Mac OS X 10.5.8 or later version with Intel chip.

 Linux including GNU C Library 2.7 or later.

The required tools to develop Android applications are freely available and can be downloaded from
the Web. The software‘s required for Android application programming are as follows:

 Java JDK5 or later version

 Android SDK

 The IDE can be Android Studio or the Eclipse IDE for Java Developers

 Android Development Tools (ADT) Eclipse Plug-in (if Eclipse IDE is used).

The Android studio is the official IDE for Android. Android Studio is built on IntelliJ and is capable
of advanced code completion, refactoring, and code analysis. SDK Tools is a downloadable
component for the Android SDK. It includes the complete set of development and debugging tools
for the Android SDK. It is included with Android Studio. If you are already using the SDK and you
want to update to the latest version of the SDK Tools, use the SDK Manager to get the update
47

System Requirements
Windows
 Microsoft® Windows® 7/8/10 (32- or 64-bit)

 2 GB RAM minimum, 8 GB RAM recommended

 2 GB of available disk space minimum, 4 GB Recommended (500 MB for IDE + 1.5 GB for
Android SDK and emulator system image)

 1280 x 800 minimum screen resolution

 Java Development Kit (JDK) 8

Mac
 Mac® OS X® 10.8.5 or higher, up to 10.11.4 (El Capitan)

 2 GB RAM minimum, 8 GB RAM recommended

 2 GB of available disk space minimum,


4 GB Recommended (500 MB for IDE + 1.5 GB for Android SDK and emulator system
image)

 1280 x 800 minimum screen resolution

 Java Development Kit (JDK) 6

Linux
 GNOME or KDE desktop

 64-bit distribution capable of running 32-bit applications

 GNU C Library (glibc) 2.11 or later

 2 GB RAM minimum, 8 GB RAM recommended

 2 GB of available disk space minimum,


4 GB Recommended (500 MB for IDE + 1.5 GB for Android SDK and emulator system
image)

 1280 x 800 minimum screen resolution

 Java Development Kit (JDK) 8

Set-up Java Development Kit (JDK)


 You can download the latest version of Java JDK from Oracle's Java site:

Java SE Downloads. [Link]

 Follow the given instructions to install and configure the setup.


48

 Select Start menu > Computer > System Properties > Advanced System Properties. Then
open Advanced tab > Environment Variables and add a new system
variable JAVA_HOME that points to your JDK folder, for example
C:\Program Files\Java\jdk1.8.0_77

 For Mac OS X, you set JAVA_HOME in the .bashrc file in your home directory. Edit or
create the .bashrc file, and add a line that looks like this
export JAVA_HOME=pat h_to_JDK_directory where path_to_JDK_directory is probably
/Library/Java/Home.

 For Linux, edit your .bashrc file and add a line like the one for Mac OS X, except that your
path to Java is probably something like /usr/lib/jvm/java-6-sun or /usr/lib/jvm/java-6-
openjdk

To install Android Studio on Windows, proceed as follows:


 Launch the .exe file you downloaded.

 Follow the setup wizard to install Android Studio and SDK tools.

You are almost ready for your first Android application using Android Studio.

Setting up Android in Eclipse


Download the Eclipse IDE for Java Developers. The Eclipse distribution is a .zip file that can be
extracted just about anywhere. For Mac OS X, you can extract to Applications. For Linux, you can
extract to your home directory or have your administrator put Eclipse into a common place where you
can get to it. The Eclipse executable is in the eclipse folder for all platforms.

When you first start up Eclipse, it asks you for a location for the workspace. To make things easy, you
can choose a simple location such as C:\android or a directory under your home directory. If you share
the computer with others, you should put your workspace folder somewhere underneath your home
directory.

Downloading the Android SDK


To build applications for Android, you need the Android SDK. As stated before, the SDK comes with
the base tools; then you download the package parts that you need. The tools part of the SDK includes
an emulator so you don‘t need a mobile device with the Android OS to develop Android applications.
It also has a setup utility to allow you to install the packages that you want to download.

You can download the Android SDK from [Link] It ships as a .zip file,
similar to the way Eclipse is distributed, so you need to unzip it to an appropriate location. For
Windows, unzip the file to a convenient location (we used the C: drive), after which you should have a
folder called something like C:\android-sdkwindows that contains the files as shown in Figure 2–1.
For Mac OS X and Linux, you can unzip the file to your home directory. Notice that Mac OS X and
Linux do not have an SDK Manager executable; the equivalent of the SDK Manager in Mac OS X and
Linux is to run the tools/android program.
49

An alternate approach (for Windows only) is to download an installer EXE instead of the zip file and
then run the installer executable. This executable checks for the Java JDK, unpacks the embedded files
for you, and runs the SDK Manager program to help you set up the rest of the downloads.

When you first install the Android SDK, it does not come with any platform versions (that is, versions
of Android). After you‘ve launched the SDK Manager, you see what is installed and what‘s available
to install. You must add Android SDK Tools and Platform-tools in order for your environment to
work. Because you use it shortly, add at least the Android 1.6 SDK Platform.

Click the Install button. You need to click Accept for each item you‘re installing (or Accept All) and
then click Install. Android then downloads your packages and platforms to make them available to
you. The Google APIs are add-ons for developing applications using Google Maps. You can always
come back to add more packages later.

Updating PATH Environment Variable


The Android SDK comes with a tools directory that you want to have in your PATH. You also need in
your PATH the platform-tools directory you just installed. You can also add a JDK bin directory.

Installing Android Development Tools (ADT)

Now you need to install ADT, an Eclipse plug-in that helps you build Android applications.
Specifically, ADT integrates with Eclipse to provide facilities for you to create, test, and debug
Android applications.
You need to use the Install New Software facility in Eclipse to perform the installation.
To get started, launch the Eclipse IDE and follow these steps:
1. Select Help .. Install New Software.
2. Select the Work With field, type in [Link] and press Enter.
Eclipse contacts the site and populates a list.
3. You should see an entry named Developer Tools with four child nodes: Android DDMS, Android
Development Tools, Android Hierarchy Viewer, and Android Traceview
Select the parent node Developer Tools, make sure the child nodes are also selected, and click the
Next button. The versions you see may be newer than these, and that‘s okay. You may also see
additional tools.
4. Eclipse asks you to verify the tools to install. Click Next.
5. You‘re asked to review the licenses for ADT as well as for the tools required to install ADT.
Review the licenses, click ―I accept,‖ and then click the Finish button.

Eclipse downloads the Developer Tools and installs them. You need to restart Eclipse for the new
plug-in to show up in the IDE.
The final step to make ADT functional in Eclipse is to point it to the Android SDK. In Eclipse, select
Window ➤ Preferences.
In the Preferences dialog box, select the Android node and set the SDK Location field to the path of
the Android SDK and then click the Apply button.
Note that you may see a dialog box asking if you want to send usage statistics to Google concerning
the Android SDK; that decision is up to you.
50

You may want to make one more Preferences change on the Android ➤ Build page. The Skip
Packaging option should be checked if you‘d like to make your file saves faster. By default, the ADT
readies your application for launch every time it builds it. By checking this option packaging and
indexing occur only when truly needed.
From Eclipse, you can launch the SDK Manager. To do so, choose Window ➤ Android SDK
Manager. You are almost ready for your first Android application.

****************
51

UNIT II
UNDERSTANDING ANDROID RESOURCES

A resource in Android is a file or a value that is bound to an executable application. These files and
values are bound to the executable in such a way that you can change them or provide alternatives
without recompiling the application. Examples of resources include strings, colors, bitmaps, and
layouts. Instead of hard-coding strings in an application, resources allow you to use their IDs instead.
This indirection lets you change the text of the string resource without changing the source code.

Resource Reference Syntax


Regardless of the type of resource all Android resources are identified by their IDs in Java source
code. The syntax you use to allocate an ID to a resource in the XML file is called resource reference
syntax. This syntax is not limited to allocating just ids: it is a way to identify any resource such as a
string, a layout file, or an image. This resource reference has the following formal structure:
@[package:]type/name
For example
@android:string/hello
@string/hello
The name part in the resource reference @[package:]type/name is the name given to the Resource. It
also gets represented as an int constant in [Link]. If you don‘t specify any package in the syntax
@[package:]type/name, the pair type/name is resolved based on local resources and the application‘s
local [Link] package. If you specify android:type/name, the reference is resolved using the package
android and specifically through the [Link] file. You can use any Java package name in place
of the package placeholder to locate the correct [Link] file to resolve the reference.

1. String Resources
Android allows you to define strings in one or more XML resource files. These XML files containing
string-resource definitions reside in the /res/values subdirectory. The names of the XML files are
arbitrary, although you commonly see the file name as [Link].

Example [Link]
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns="[Link]

<string name="hello">hello</string>
52

<string name="app_name">hello appname</string>


</resources>

The root node is <resources> followed by one or more <string> child elements. Each <string> element
or node has an attribute name that defines the name of the string. When this file is created or updated,
ADT automatically creates or updates a Java class in your application‘s root package called [Link]
with unique IDs. Regardless of the number of resource files, there is only one [Link] file.

Example of [Link]
package [Link]-root-package;
public final class R
{
...
public static final class string
{
public static final int hello=0x7f040000;
public static final int app_name=0x7f040001;
}

...
}

Within that outer class of R, Android defines an inner class, static final class string.
[Link] creates this inner static class as a namespace to hold string resource IDs. The two static final int
defined with variable names hello and app_name are the resource IDs that represent the corresponding
string resources. You can use these resource IDs anywhere in the source code through the following
code structure: [Link]
The generated IDs point to int rather than strings. Any number of string resource files can be defined
in the /res/values subdirectory. There is only one inner class string for all IDs defined in different
XML files. The ADT plug-in validates the uniqueness of the IDs at compile time and places them in
[Link]. In XML a string resource can be referred using the following syntax :
@string/resourcename.
For example: @string/hello
2. Layout Resources
In Android, the view for a screen is often loaded from an XML file as a resource. These XML files are
called layout resources. They are saved in res/layout/ and accessed from the [Link] class. A layout
resource is a key resource used in Android UI programming.

SYNTAX:
53

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


<ViewGroup
xmlns:android="[Link]
android:layout_height=["dimension" | "match_parent" | wrap_content"]
android:layout_width=["dimension" | "match_parent" | "wrap_content"] >
<View
android:id="@[+][package:]id/resource_name"
android:layout_height=["dimension" | "match_parent" | "wrap_content"]
android:layout_width=["dimension" | "match_parent" | "wrap_content"]
[View-specific attributes] >
</View>
</ViewGroup>

<ViewGroup>

It is a container for other View elements. ViewGroup can be LinearLayout, RelativeLayout,


FrameLayout etc.

Attributes:

xmlns:android : defines the namespace for the attributes. The value can be
[Link]

android:orientation : the value can be vertical or horizontal. Organizes controls in


horizontal or vertical pattern. It is used in Linearlayout

android:layout_height : sets the height of the layout. The value can be a dimension value
(or dimension resource) or a keyword
("match_parent" or "wrap_content").

android:layout_width : sets the width of the layout. The value can be a dimension value
(or dimension resource) or a keyword
("match_parent" or "wrap_content").

The height and width value can be expressed using any of the dimension units supported by Android
(px, dp, sp, pt, in, mm) or with the following keywords:
54

Value Description

match_parent Sets the dimension to match that of the parent element. Added in API
Level 8 to deprecate fill_parent.

wrap_content Sets the dimension only to the size required to fit the content of this
element.

fill_parent Occupies the full space

Example [Link] Layout File


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button android:id="@+id/b1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
The layout file defines a root node called LinearLayout, which contains a TextView followed by a
Button. A LinearLayout lays out its children vertically or horizontally. This layout can be accessed in
java code using [Link]

You need to define a separate layout file for each screen (or activity). More accurately, each layout
needs a dedicated file. If you are painting two screens, you probably need two layout files. Each file in
the /res/layout/ subdirectory generates a unique constant based on the name of the file (extension
excluded).
55

For example, if you have two files under /res/layout/ called [Link] and [Link], then in [Link] you
have the entries as follows.
Multiple Constants for Multiple Layout Files
public static final class layout
{
public static final int file1=0x7f030000;
public static final int file2=0x7f030001;
//.... any other files
}

Using a Layout File


public class HelloWorldActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
[Link](savedInstanceState);
setContentView([Link]);
}
...
}
The line setContentView([Link]) points out that there is a static class called [Link], and
within that class, there is a constant called main pointing to a View defined by an XML layout
resource file. The name of the XML file is [Link], which needs to be placed in the resources‘ layout
subdirectory.

3. ID Resources
The general pattern for allocating an ID is either to create a new one or to use the one created by the
Android package. It is used to identify the views and view groups.
56

The ID value has the following syntax "@+id/name". The plus symbol, +, indicates that this is a new
resource ID and the aapt tool will create a new resource integer in the [Link] class, if it doesn't already
exist.
The line <TextView android:id="@+id/text"> indicates that an ID named text is used if it already
exists. If the ID doesn‘t exist, a new one is created. It creates an integer constant text in [Link]. It gets
regenerated every time something is changed, added, or deleted in the /res/* subdirectory.

To define an ID without attaching to any particular resource (+)


<resources>
<item type="id" name="t1"/>
</resources>

Reusing a Predefined ID
<TextView android:id="@id/t1">
..
</TextView>

4. String Arrays
You can specify an array of strings as a resource in any file under the /res/values subdirectory. To do
so, you use an XML node called string-array. This node is a child node of resources just like the string
resource node

Specifying String Arrays


<resources ....>
......Other resources
<string-array name="test_array">
<item>one</item>
<item>two</item>
<item>three</item>
</string-array>
......Other resources
</resources>
Once you have this string-array resource definition, you can retrieve this array in the
Java code as follows.
Resources res = [Link]();
57

String strings[] = [Link]([Link].test_array);


for (String s: strings)
{
Log.d("example", s); //Print strings
}
5. Plurals
The resource plurals are a set of strings. These strings are various ways of expressing a numerical
quantity, such as how many eggs are in a nest. Consider an example:
There is 1 egg.
There are 2 eggs.
There are 0 eggs.
There are 100 eggs.
Notice how the sentences are identical for the numbers 2, 0, and 100. However, the sentence for 1 egg
is different. Android allows you to represent this variation as a plurals resource. Listing 3–12 shows
how you would represent these two variations based on quantity in a resource file.

Specifying String Arrays


<resources...>
<plurals name="eggs ">
<item quantity="one">There is 1 egg</item>
<item quantity="other">There are %d eggs</item>
</plurals>
</resources>
The two variations are represented as two different strings under one plural. Specifying String Arrays
Resources res = [Link]();
String s1 = [Link]([Link], 0,0);
String s2 = [Link]([Link], 1,1);
String s3 = [Link]([Link], 2,2);
String s4 = [Link]([Link], 10,10);
The first parameter to the getQuantityString() method is the plurals resource ID. The second parameter
selects the string to be used. When the value of the quantity is 1, you use the string as ―There is 1 egg‖.
When the value is not 1, you must supply a third parameter whose value is to be placed where %d is.
58

6. Color Resources
You can use reference identifiers to indirectly reference colors. Doing this enables Android to localize
colors and apply themes. Once you‘ve defined and identified colors in resource files, you can access
them in Java code through their IDs. The color IDs are available under the [Link] namespace.

XML Syntax for Defining Color Resources


<resources>
<color name="red">#f00</color>
<color name="blue">#0000ff</color>
<color name="green">#f0f0</color>
<color name="bgcolor">#ffffff00</color>
</resources>
The file residing in the /res/values subdirectory. The name of the file is arbitrary, meaning the file
name can be anything you choose.
Color Resources in Java code

int backclr = [Link]([Link]);

Using Colors in View

<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:text="Sample Text to Show Red Color"/>

7. Dimension Resources
Pixels, inches, and points are all examples of dimensions that can play a part in XML layouts or Java
code. You can use these dimension resources to style and localize Android UIs without changing the
source code.
XML Syntax for Defining Dimension Resources
<resources>
<dimen name="mysize1">1px</dimen>
<dimen name="mysize2">5dp</dimen>
<dimen name="medium_size">100sp</dimen>
</resources>
You can specify the dimensions in any of the following units:
px: Pixels in: Inches
59

mm: Millimeters pt: Points


dp: Density-independent pixels based on a 160dpi (pixel density per inch) screen (dimensions adjust to
screen density)
sp: Scale-independent pixels (dimensions that allow for user sizing; helpful for use in fonts)
In Java, you need to access your Resources object instance to retrieve a dimension.

Using Dimension Resources in Java Code


float dimen = [Link]().getDimension([Link].mysize1);

Using Dimension Resources in XML


<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/medium_size"/>

8. Image Resources
Android generates resource IDs for image files placed in the /res/drawable subdirectory. The
supported image types include .gif, .jpg, and .png. Each image file in this directory generates a unique
ID from its base file name. If the image file name is sample_image.jpg, for example, then the resource
ID generated is [Link].sample_image.

Using Image Resources in XML


<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Dial"
android:background="@drawable/sample_image"
/>
Using Image Resources in Java
// you can set the background directly from the Resource Id
[Link]([Link].sample_image);
60

INTENT
An Intent is a messaging object you can use to request an action from another app component.
Although intents facilitate communication between components in several ways, there are three
fundamental use cases:
1. Starting an activity

An Activity represents a single screen in an app. You can start a new instance of an Activity by
passing an Intent to startActivity(). The Intent describes the activity to start and carries any necessary
data.
If you want to receive a result from the activity when it finishes, call startActivityForResult(). Your
activity receives the result as a separate Intent object in your activity's onActivityResult() callback.
2. Starting a service

A Service is a component that performs operations in the background without a user interface. With
Android 5.0 (API level 21) and later, you can start a service with JobScheduler.
For versions earlier than Android 5.0 (API level 21), you can start a service by using methods of
the Service class. You can start a service to perform a one-time operation (such as downloading a file)
by passing an Intent to startService(). The Intent describes the service to start and carries any
necessary data.
If the service is designed with a client-server interface, you can bind to the service from another
component by passing an Intent to bindService().
3. Delivering a broadcast

A broadcast is a message that any app can receive. The system delivers various broadcasts for system
events, such as when the system boots up or the device starts charging. You can deliver a broadcast to
other apps by passing an Intent to sendBroadcast() or sendOrderedBroadcast().

There are two types of intents:

 Explicit intents specify which application will satisfy the intent, by supplying either the target
app's package name or a fully-qualified component class name. 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.
Eg:
Intent downloadIntent = new Intent(this, [Link]);
[Link]([Link]("[Link]
startService(downloadIntent);

Implicit intents do not name a specific component, but instead declare a general action to
perform, which allows a component from another app to handle it.

Intent in = new Intent(Intent.ACTION_VIEW);


[Link]([Link]("[Link]
startActivity(in);
61

Figure shows how an implicit intent is delivered through the system to start another
activity: [1] Activity A creates an Intent with an action description and passes it
to startActivity(). [2] The Android System searches all apps for an intent filter that matches the intent.
When a match is found, [3] the system starts the matching activity (Activity B) by invoking
its onCreate() method and passing it the Intent.

When you use an implicit intent, the Android system finds the appropriate component to start by
comparing the contents of the intent to the intent filters declared in the manifest file of other apps on
the device. If the intent matches an intent filter, the system starts that component and delivers it
the Intent object. If multiple intent filters are compatible, the system displays a dialog so the user can
pick which app to use.

Intent filter

An intent filter is an expression in an app's manifest file that specifies the type of intents that the
component would like to receive. For instance, by declaring an intent filter for an activity, you make it
possible for other apps to directly start your activity with a certain kind of intent. Likewise, if you
do not declare any intent filters for an activity, then it can be started only with an explicit intent.

<activity android:name="MainActivity">
<intent-filter>
<action android:name="[Link]" />
<category android:name="[Link]" />
</intent-filter>
</activity>

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="[Link]"/>
<category android:name="[Link]"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>

Each intent filter specifies the type of intents it accepts based on the intent's action, data, and category.
The system delivers an implicit intent to your app component only if the intent can pass through one of
your intent filters.
62

Each intent filter is defined by an <intent-filter> element in the app's manifest file, nested in the
corresponding app component (an <activity> element). Inside the <intent-filter>, you can specify the
type of intents to accept using one or more of these three elements:
<action>
Declares the intent action accepted, in the name attribute. The value must be the literal string value of
an action, not the class constant.
<data>
Declares the type of data accepted, using one or more attributes that specify various aspects of the data
URI (scheme, host, port, path) and MIME type.
<category>
Declares the intent category accepted, in the name attribute. The value must be the literal string value
of an action, not the class constant.
Intent resolution
When the system receives an implicit intent to start an activity, it searches for the best activity for the
intent by comparing it to intent filters based on three aspects:
 Action.
 Data (both URI and data type).
 Category.
Action test
To specify accepted intent actions, an intent filter can declare zero or more <action> elements, as
shown in the following example:
<intent-filter>
<action android:name="[Link]" />
<action android:name="[Link]" />
...
</intent-filter>
To pass this filter, the action specified in the Intent must match one of the actions listed in the filter.
If the filter does not list any actions, there is nothing for an intent to match, so all intents fail the test.
However, if an Intent does not specify an action, it passes the test as long as the filter contains at least
one action.
Category test
To specify accepted intent categories, an intent filter can declare zero or more <category> elements, as
shown in the following example:
<intent-filter>
<category android:name="[Link]" />
<category android:name="[Link]" />
...
</intent-filter>
63

For an intent to pass the category test, every category in the Intent must match a category in the filter.
The intent filter may declare more categories than are specified in the Intent and the Intent still passes.
Therefore, an intent with no categories always passes this test, regardless of what categories are
declared in the filter.
Different types of categories
CATEGORY_DEFAULT
An activity can declare itself as a DEFAULT activity if it wants to be invoked by implicit intents. If
you don‘t define this category for your activity, that activity will need to be invoked explicitly every
time through its class name. This is why you see activities that get invoked through generic actions or
other action names that use default category specification.
CATEGORY_BROWSABLE
An activity can declare itself as BROWSABLE by promising the browser that it will not violate
browser security considerations when started.
CATEGORY_TAB
An activity of this type is embeddable in a tabbed parent activity.
CATEGORY_ALTERNATIVE
An activity can declare itself as an ALTERNATIVE activity for a certain type of data that you are
viewing. These items normally show up as part of the options menu when you are looking at that
document. For example, print view is considered an alternative to regular view.
CATEGORY_SELECTED_ALTERNATIVE
An activity can declare itself as an ALTERNATIVE activity for a certain type of data. This is similar
to listing a series of possible editors for a text document or an HTML document.
CATEGORY_LAUNCHER
Assigning this category to an activity will allow it to be listed on the launcher screen.
CATEGORY_HOME
An activity of this type will be the home screen. Typically, there should be only one activity of this
type. If there are more, the system will provide a prompt to pick one.
CATEGORY_PREFERENCE
This activity identifies an activity as a preference activity, so it will be shown as part of the
preferences screen.
CATEGORY_GADGET
An activity of this type is embeddable in a parent activity.
CATEGORY_TEST
This is a test activity.
CATEGORY_EMBED
This category has been superseded by the GADGET category.
64

Data test
To specify accepted intent data, an intent filter can declare zero or more <data> elements, as shown in
the following example:
<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http" ... />
<data android:mimeType="audio/mpeg" android:scheme="http" ... />
...
</intent-filter>

Each <data> element can specify a URI structure and a data type (MIME media type). Each part of the
URI is a separate attribute: scheme, host, port, and path:
<scheme>://<host>:<port>/<path>
The following example shows possible values for these attributes:
content://[Link]/folder/subfolder/etc
In this URI, the scheme is content, the host is [Link], the port is 200, and the path
is folder/subfolder/etc.
Each of these attributes is optional in a <data> element, but there are linear dependencies:
 If a scheme is not specified, the host is ignored.
 If a host is not specified, the port is ignored.
 If both the scheme and host are not specified, the path is ignored.

Intent matching
Intents are matched against intent filters not only to discover a target component to activate, but also to
discover something about the set of components on the device.
Available Intent actions in Android
The set of available applications could include the following:
 A browser application to open a browser window

Intent intent = new Intent (Intent.ACTION_VIEW);


[Link]([Link]("[Link]
[Link](intent);
 An application to call a telephone number

Intent intent = new Intent (Intent.ACTION_DIAL);


[Link](intent);
 An application to present a phone dialer so the user can enter the numbers and make a call
through the UI

Intent intent = new Intent (Intent.ACTION_CALL);


65

[Link]([Link]("[Link]
[Link](intent);
 A mapping application to show the map of the world at a given latitude and longitude
coordinate

Intent intent = new Intent (Intent.ACTION_VIEW);


[Link]([Link]("geo:0,0?z=4&q=business+near+city"));
[Link](intent);
The ACTION_PICK Action
The predefined intent action Intent.ACTION_PICK helps you to pick an item from a data source. All
we need is to know the URI of the provider. Almost all core android applications provide this facility.
All you need is the URI of the data you need and required permissions to access that data.
ACTION_PICK is one generic action. The idea of ACTION_PICK is to start an activity that displays a
list of items. The activity should allow a user to pick one item from that list. Once the user picks the
item, the activity should return the URI of the picked item to the caller. This allows reuse of the UI‘s
functionality to select items of a certain type.
startActivity() is an asynchronous call with no callbacks to indicate what happened in the invoked
activity. If you want to return data, you can use a variation of startActivity() called
startActivityForResult(), which comes with a callback.
public void startActivityForResult(Intent intent, int requestCode)

This method launches an activity from which you would like a result. When this activity exits, the
source activity‘s onActivityResult() method will be called with the given requestCode. The signature
of this callback method is

protected void onActivityResult(int requestCode, int resultCode, Intent data)

requestCode is what you passed in to the startActivityForResult() method. The resultCode can be
RESULT_OK, RESULT_CANCELED, or a custom code. The custom codes should start at
RESULT_FIRST_USER. The Intent parameter contains any additional data that the invoked activity
wants to return. In the case of ACTION_PICK, the returned data in the intent points to the data URI of
a single item. The constants RESULT_OK, RESULT_CANCELED, and RESULT_FIRST_USER are
all defined in the Activity class. The numerical values of these constants are
RESULT_OK = -1;
RESULT_CANCELED = 0;
RESULT_FIRST_USER = 1;

For eg:
66

public static void invokePick(Activity activity)


{
Intent pickIntent = new Intent(Intent.ACTION_PICK);
int requestCode = 1;
[Link]([Link]("content://[Link]/notes"));
[Link](pickIntent, requestCode);
}

The GET_CONTENT Action

ACTION_GET_CONTENT is similar to ACTION_PICK. In the case of ACTION_PICK, you are


specifying a URI that points to a collection of items, such as a collection of notes. You will expect the
action to pick one of the notes and return it to the caller. In the case of ACTION_GET_CONTENT,
you indicate to Android that you need an item of a particular MIME type. Android searches for either
activities that can create one of those items or activities that can choose from an existing set of items
that satisfy that MIME type. Using ACTION_GET_CONTENT, you can pick a note from a collection
of notes supported by the NotePad application using the following code:

public static void invokeGetContent(Activity activity)


{
Intent pickIntent = new Intent(Intent.ACTION_GET_CONTENT);
int requestCode = 2;
[Link]("[Link]/[Link]");
[Link](pickIntent, requestCode);
}
Notice how the intent type is set to the MIME type of a single note.
The rest of the code for responding to onActivityResult() is identical to the previous ACTION_PICK
example. If there are multiple activities that can return the same MIME type, Android will show you
the chooser dialog to let you pick an activity.
Pending Intent
A PendingIntent object is a wrapper around an Intent object. The primary purpose of
a PendingIntent is to grant permission to a foreign application to use the contained Intent as if it were
executed from your app's own process.
Major use cases for a pending intent include the following:
Declaring an intent to be executed when the user performs an action with your Notification (the
Android system's NotificationManager executes the Intent).
67

Declaring an intent to be executed when the user performs an action with your App Widget (the Home
screen app executes the Intent).
Declaring an intent to be executed at a specified future time (the Android
system's AlarmManager executes the Intent).
Just as each Intent object is designed to be handled by a specific type of app component (either
an Activity, a Service, or a BroadcastReceiver), so too must a PendingIntent be created with the same
consideration. When using a pending intent, your app doesn't execute the intent with a call such
as startActivity(). Instead, you must declare the intended component type when you create
the PendingIntent by calling the respective creator method:
[Link]() for an Intent that starts an Activity.
[Link]() for an Intent that starts a Service.
[Link]() for an Intent that starts a BroadcastReceiver.
Unless your app is receiving pending intents from other apps, the above methods to create
a PendingIntent are probably the only PendingIntent methods you'll ever need.
Each method takes the current app Context, the Intent you want to wrap, and one or more flags that
specify how the intent should be used (such as whether the intent can be used more than once).

UNDERSTANDING CONTENT PROVIDERS

Android uses a concept called content providers for abstracting data into services. A content provider
is a wrapper around data. A SQLite database on an Android device is an example of a data source that
you can encapsulate into a content provider.

It is like REST enabled data sources like webpages. REST stands for REpresentational State Transfer.
When you type a URL in a web browser and the web server responds with HTML, you have
essentially performed a REST-based ―query‖ operation on the web server.

Content providers play a significant role in sharing data between applications. Strictly speaking, a
content provider‘s responsibilities consist more of an encapsulation mechanism than a data-access
mechanism.
Content-provider abstraction is required only if you want to share data externally or between
applications. For internal data access, an application can use any data storage/access mechanism that it
deems suitable, such as the following:
Preferences: A set of key/value pairs that you can persist to store application preferences
Files: Files internal to applications, which you can store on a removable storage medium
SQLite: SQLite databases, each of which is private to the package that creates that database
68

Network: A mechanism that lets you retrieve or store data externally through the Internet via HTTP
services.

Exploring Android’s Built-in Providers

Android comes with a number of built-in content providers, which are documented in the SDK‘s
[Link] Java package.

The providers include, for example, Contacts and MediaStore. These SQLite databases typically have
an extension of .db and are accessible only from the implementation package. Any access outside that
package must go through the content-provider interface.

Architecture of Content Providers


69

Structure of Android Content URIs

Content URIs have the syntax

content://authority/path/id

Here‘s an example URI that identifies a note numbered 23 in a database of notes:

content://[Link]/notes/23

content:

The scheme portion of the URI. This is always set


to ContentResolver.SCHEME_CONTENT (value content://).

authority

A unique identifier for the authority, which is used to locate the provider in the provider registry. It
identifies the entire content provider. All the content URIs for the provider start with this string. To
guarantee a unique authority, providers should

The [Link] package includes the ContentProvider and ContentResolver classes to


handle content providers.

An object of ContentProvider provides data to external applications as one or more tables. A row
represents an instance of some type of data the provider collects. A column in a row represents an
individual piece of data collected for an instance.

An application accesses the data from a content provider with a ContentResolver client object.
The ContentResolver methods provide the basic functions (create, retrieve, update, and delete)
functions of persistent storage.

Content Uri

A content URI is a URI that identifies data in a provider. Content URIs include the symbolic name of
the entire provider (its authority) and a name that points to a table (a path). When you call a client
method to access a table in a provider, the content URI for the table is one of the arguments.

Structure of Content Uri

Content URIs have the syntax


70

content://authority/path/id

content

The scheme portion of the URI. This is always set to the value content

authority

A string that identifies the entire content provider. All the content URIs for the provider start with this
string. To guarantee a unique authority, providers should consider using an authority that is the same
as the provider class' package identifier.

path

Zero or more segments, separated by a forward slash (/), that identify some subset of the provider's
data. Most providers use the path part to identify individual tables. Individual segments in the path are
often called "directories" although they do not refer to file directories. The right-most segment in a
path is often called a "twig"

id

A unique numeric identifier for a single row in the subset of data identified by the preceding path part.
Most providers recognize content URIs that contain an id part and give them special handling. A table
that contains a column named _ID often expects the id part to be a particular value for that column.

Reading Data Using URIs

To retrieve data from a provider, follow these basic steps:

1. Request the read access permission for the provider.

2. Define the code that sends a query to the provider.

Requesting read access permission


To retrieve data from a provider, your application needs "read access permission" for the provider.
You can't request this permission at run-time; instead, you have to specify that you need this
permission in your manifest, using the <uses-permission> element and the exact permission name
defined by the provider. When you specify this element in your manifest, you are in effect
71

"requesting" this permission for your application. When users install your application, they implicitly
grant this request.

The Contacts Provider defines the permission [Link].READ_CONTACTS in its


manifest file, so an application that wants to read from the provider must request this permission.

<uses-permission

android:name=‖[Link].READ_CONTACTS‖ />

Constructing the query


The next step in retrieving data from a provider is to construct a query. Follow the steps.

 Retrieve a ContentResolver object from the activity.

 Invoke query() method in ContentResolver object.

Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String
sortOrder)

 Invoke the methods in Cursor object to retrieve data

Parameters

uri Uri: The URI, using the content:// scheme, for the content to retrieve.

projection String: A list of which columns to return. Passing null will return all columns,
which is inefficient.

selection String: A filter declaring which rows to return, formatted as an SQL WHERE
clause (excluding the WHERE itself). Passing null will return all rows for the
given URI.

selectionArgs String: You may include ?s in selection, which will be replaced by the values from
selectionArgs, in the order that they appear in the selection. The values will be
bound as Strings.
72

sortOrder String: How to order the rows, formatted as an SQL ORDER BY clause
(excluding the ORDER BY itself). Passing null will use the default sort order,
which may be unordered.

query() compared to SQL query.

query() SELECT Notes


argument keyword/parameter

Uri FROM table_name Uri maps to the table in the provider named table_name.

projection col,col,col,... projection is an array of columns that should be included


for each row retrieved.

selection WHERE col = value selection specifies the criteria for selecting rows.

selectionArgs (No exact equivalent. Selection arguments


replace ? placeholders in the selection clause.)

sortOrder ORDER BY col,col,... sortOrder specifies the order in which rows appear in the
returned Cursor

Now you know that to retrieve data from a content provider, you need to use URIs supplied by that
content provider. Because the URIs defined by a content provider are unique to that provider, it is
important that these URIs are documented and available to programmers to see and then call. The
providers that come with Android do this by defining constants representing these URI strings.
Consider these three URIs defined by helper classes in the Android SDK:
[Link].INTERNAL_CONTENT_URI
[Link].EXTERNAL_CONTENT_URI
[Link].CONTENT_URI
The equivalent textual URI strings would be as follows:
content://media/internal/images
73

content://media/external/images
content://[Link]/contacts/
Given these URIs, the code to retrieve a single row of people from the Contacts provider looks like
this:
Uri peopleBaseUri = [Link].CONTENT_URI;
Uri myPersonUri = [Link](peopleBaseUri, "23");
//Query for this record.
//managedQuery is a method on Activity class
Cursor cur = managedQuery(myPersonUri, null, null, null);
Notice how the [Link].CONTENT_URI is predefined as a constant in
the Contacts class. We have named the variable peopleBaseUri to indicate that if your intention is to
discover people, you go after the Contacts content URI. Of course, you can call this variable
contactsBaseUri if you conceptually think of people as contacts. In this example, the code takes the
root URI, adds a specific person ID to it, and makes a call to the managedQuery method. As part of the
query against this URI, it is possible to specify a sort order, the columns to select, and a where clause.
These additional parameters are set to null in this example.

NOTE: A content provider should list which columns it supports by implementing a set of interfaces
or by listing the column names as constants. However, the class or interface that defines constants for
columns should also make the column types clear through a column-naming convention, or comments
or documentation, because there is no formal way to indicate the type of a column through constants.

Retrieving a Cursor from a Content Provider


//Use this interface to see the constants
import [Link];
...
// An array specifying which columns to return.
string[] projection ={ Contacts._ID, Contacts.DISPLAY_NAME_PRIMARY};
Uri mContactsUri = [Link].CONTENT_URI;
// Best way to retrieve a query; returns a managed query.
Cursor managedCursor = managedQuery (mContactsUri, projection, null ,
Contacts.DISPLAY_NAME_PRIMARY + " ASC");
//Which columns to return, WHERE clause, Order-by clause.
Notice how a projection is merely an array of strings representing column names. So unless you know
what these columns are, you‘ll find it difficult to create a projection. You should look for these column
74

names in the same class that provides the URI, in this case the Contacts class. The cursor that is
returned contains zero or more records. Column names, order, and type are provider specific.
However, every row returned has a default column called _id representing a unique ID for that row.

Using the Android Cursor


Here are a few facts about an Android cursor:
A cursor is a collection of rows.
You need to use moveToFirst() before reading any data because the cursor starts off positioned before
the first row.
You need to know the column names.
You need to know the column types.
All field-access methods are based on column number, so you must convert the column name to a
column number first.
The cursor is random (you can move forward and backward, and you can jump).
Because the cursor is random, you can ask it for a row count.
An Android cursor has a number of methods that allow you to navigate through it.
Listing 4–2 shows how to check if a cursor is empty and how to walk through the cursor
row by row when it is not empty.
Listing 4–2. Navigating Through a Cursor Using a while Loop
if ([Link]() == false)
{
//no rows empty cursor
return;
}
//The cursor is already pointing to the first row
//let's access a few columns
int nameColumnIndex = [Link](Contacts.DISPLAY_NAME_PRIMARY);
String name = [Link](nameColumnIndex);
//let's now see how we can loop through a cursor
while([Link]())
{
//cursor moved successfully
//access fields
}
75

The assumption at the beginning of Listing 4–2 is that the cursor has been positioned before the first
row. To position the cursor on the first row, we use the moveToFirst() method on the cursor object.
This method returns false if the cursor is empty. We then use the moveToNext() method repetitively to
walk through the cursor.

To help you learn where the cursor is, Android provides the following methods:
isBeforeFirst()
isAfterLast()
isClosed()
Using these methods, you can also use a for loop as in Listing 4–3 to navigate through
the cursor instead of the while loop used in Listing 4–2.

Listing 4–3. Navigating Through a Cursor Using a for Loop


//Get your indexes first outside the for loop
int nameColumn = [Link](Contacts.DISPLAY_NAME_PRIMARY);
//Walk the cursor now based on column indexes
for([Link]();![Link]();[Link]())
{
String name = [Link](nameColumn);
}
The index order of columns seems to be a bit arbitrary. As a result, we advise you to explicitly get the
indexes first from the cursor to avoid surprises. To find the number of rows in a cursor, Android
provides a method on the cursor object called getCount().

Working with the where Clause


Content providers offer two ways of passing a where clause:
 Through the URI
 Through the combination of a string clause and a set of replaceable string-array arguments
Passing a where Clause Through a URI
Imagine you want to retrieve a note whose ID is 23 from the Google notes database.
You‘d use the code in Listing 4–4 to retrieve a cursor containing one row corresponding
to row 23 in the notes table.
Listing 4–4. Passing SQL where Clauses Through the URI
Activity someActivity;
//..initialize someActivity
76

String noteUri = "content://[Link]/notes/23";


Cursor managedCursor = [Link]( noteUri, projection, null, null);
//Which columns to return, WHERE clause, Order-by clause.
We left the where clause argument of the managedQuery method null because, in this case, we
assumed that the note provider is smart enough to figure out the id of the book we wanted. This id is
embedded in the URI itself. We used the URI as a vehicle to pass the where clause. This becomes
apparent when you notice how the notes provider implements the corresponding query method. Here is
a code snippet from that query method:
//Retrieve a note id from the incoming uri that looks like
//content://.../notes/23
int noteId = [Link]().get(1);
//ask a query builder to build a query
//specify a table name
[Link](NOTES_TABLE_NAME);
//use the noteid to put a where clause
[Link](Notes._ID + "=" + noteId);
Notice how the ID of a note is extracted from the URI. The Uri class representing the incoming
argument uri has a method to extract the portions of a URI after the root
content://[Link]. These portions are called path segments; they‘re strings
between / separators such as /seg1/seg3/seg4/, and they‘re indexed by their positions. For the URI
here, the first path segment would be 23. We then used this ID of 23 to append to the where clause
specified to the QueryBuilder class. In the end, the equivalent select statement would be

select * from notes where _id = 23

NOTE: The classes Uri and UriMatcher are used to identify URIs and extract parameters from them.
SQLiteQueryBuilder is a helper class in [Link] that allows you to construct SQL
queries to be executed by SQLiteDatabase on a SQLite database instance.

Using Explicit where Clauses


Now that you have seen how to use a URI to send in a where clause, consider the other method by
which Android lets us send a list of explicit columns and their corresponding values as a where clause.
To explore this, let‘s take another look at the managedQuery method of the Activity class that we used
in Listing 4–4. Here‘s its signature:
77

public final Cursor managedQuery(Uri uri, String[] projection, String selection,


String[] selectionArgs, String sortOrder)

Notice the argument named selection, which is of type String. This selection string represents a filter
(a where clause, essentially) declaring which rows to return, formatted as a SQL where clause
(excluding the WHERE itself). Passing null will return all rows for the given URI. In the selection
string you can includes, which will be replaced by the values from selectionArgs in the order that they
appear in the selection. The values will be bound as Strings.

Because you have two ways of specifying a where clause, you might find it difficult to determine how
a provider has used these where clauses and which where clause takes precedence if both where
clauses are utilized.
For example, you can query for a note whose ID is 23 using either of these two methods:
//URI method
managedQuery("content://[Link]/notes/23",null,null,null,null);
or
//explicit where clause
managedQuery("content://[Link]/notes", null, "_id=?", new String[] {23}, null);
The convention is to use where clauses through URIs where applicable and use the explicit option as a
special case.

Inserting Records
Android uses a class called [Link] to hold the values for a single record that is
to be inserted. ContentValues is a dictionary of key/value pairs, much like column names and their
values. You insert records by first populating a record into ContentValues and then asking
[Link] to insert that record using a URI.
NOTE: You need to locate ContentResolver, because at this level of abstraction, you are not asking a
database to insert a record; instead, you are asking to insert a record into a provider identified by a
URI. ContentResolver is responsible for resolving the URI reference to the right provider and then
passing on the ContentValues object to that specific provider.
Here is an example of populating a single row of notes in ContentValues in preparation
for an insert:
ContentValues values = new ContentValues();
[Link]("title", "New note");
[Link]("note","This is a new note");
78

//values object is now ready to be inserted


You can get a reference to ContentResolver by asking the Activity class:
ContentResolver contentResolver = [Link]();
Now, all you need is a URI to tell ContentResolver to insert the row. These URIs are defined in a class
corresponding to the Notes table. In the Notepad example, this URI is
[Link].CONTENT_URI
We can take this URI and the ContentValues we have and make a call to insert the row:

Uri uri = [Link]([Link].CONTENT_URI, values);


This call returns a URI pointing to the newly inserted record. This returned URI would match the
following structure: [Link].CONTENT_URI/new_id

Adding a File to a Content Provider


Occasionally, you might need to store a file in a database. The usual approach is to save
the file to disk and then update the record in the database that points to the corresponding file name.
Android takes this protocol and automates it by defining a specific procedure for saving and retrieving
these files. Android uses a convention where a reference to the file name is saved in a record with a
reserved column name of _data. When a record is inserted into that table, Android returns the URI to
the caller. Once you save the record using this mechanism, you also need to follow it up by saving the
file in that location. To do this, Android allows ContentResolver to take the URI of the database record
and return a writable output stream. Behind the scenes, Android allocates an internal file and stores the
reference to that file name in the _data field. If you were to extend the Notepad example to store an
image for a given note, you could create an additional column called _data and run an insert first to get
a URI back. The following code demonstrates this part of the protocol:
ContentValues values = new ContentValues();
[Link]("title", "New note");
[Link]("note","This is a new note");
//Use a content resolver to insert the record
ContentResolver contentResolver = [Link]();
Uri newUri = [Link]([Link].CONTENT_URI, values);
Once you have the URI of the record, the following code asks the ContentResolver to get a reference
to the file output stream:
....
//Use the content resolver to get an output stream directly
//ContentResolver hides the access to the _data field where
79

//it stores the real file reference.


OutputStream outStream = [Link]().openOutputStream(newUri);
[Link]([Link], 50, outStream);
[Link]();
The code then uses that output stream to write to.

Updates and Deletes


Performing an update is similar to performing an insert, in which changed column values are passed
through a ContentValues object. Here is the signature of an update method on the ContentResolver
object:
int numberOfRowsUpdated = [Link]().update(Uri uri,
ContentValues values, String whereClause, String[] selectionArgs );

The whereClause argument constrains the update to the pertinent rows. Similarly, the
signature for the delete method is
int numberOfRowsDeleted = [Link]().delete(
Uri uri, String whereClause, String[] selectionArgs )

Clearly, a delete method will not require the ContentValues argument because you will not need to
specify the columns you want when you are deleting a record. Almost all the calls from
managedQuery and ContentResolver are directed eventually to the provider class. Knowing how a
provider implements each of these methods gives us enough clues as to how those methods are used
by a client.
80
81

UNIT III

Building User Interfaces

Android SDK provides a collection of controls that are appropriate for mobile devices. Examples:
TextView, EditText, Button etc. At the heart of the common controls are two classes:
[Link] and [Link].

The View class represents a general-purpose View object. The common controls in Android ultimately
extend the View class. ViewGroup is also a view, but it contains other views too. ViewGroup is the
base class for a list of layout classes. Layouts are used to manage how controls are laid out within a
container view.

UI Nomenclature

Term Description

View, widget, control Each of these represents a UI element. Examples include a button, a
grid, a list, a window, a dialog box, and so on.

Container This is a view used to contain other views. For example, a grid can be
considered a container because it contains cells, each of which is a view.

Layout This is a visual arrangement of containers and views and can include
other layouts.

There is a relation between ViewGroup and View instances that defines a tree like architecture for the
user interface that has as root a ViewGroup node:
82

Android Widget Framework


83

Several approaches to build UIs in Android

 Building UI entirely in code


 Define UI in XML.
 Define the UI in XML and then refer to it, and modify it, in code.

Building a UI Completely in Code


In this approach controls can be created by defining objects. The strength of java coding approach is
using dynamic user interfaces. The user interface may appear differently each time the activity
executes subject to external [Link] example consider the following code:
package [Link];
import [Link].*;
import [Link].*;
import [Link];
import [Link];

public class NewActivity extends Activity {


protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_new);
TextView txtInfo = new TextView(this);
[Link]("Hello World Android !");
[Link](20);
[Link]([Link]);
}
}
Building a UI in XML
XML resource files are useful while creating static layouts. Static layouts means layouts that are
unlikely to change significantly from one invocation of activity to the next. Here controls are defined
in XML resource files and are stored under /res directory. The following code defines a layout
resource and is stored in /res/layout folder.
activity_new.xml
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
84

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/txt1" />
</LinearLayout>

Advantage of XML over java code


 Ability to use Graphical Layout Tool which generates XML resource files.
 Once an app has been created changes to the user interface screens can be made by simply
modifying the XML file, therefore avoiding the necessity to recompiling the application.

Building a UI in XML and access it in code


The UI is designed in XML then reference the controls from java code. This approach enables us to
bind dynamic data to the controls defined at design time.
In XML IDs can be assigned to controls and they can be referenced in code using these IDs. For
example the TextView defined in xml layout resource file can be referred in code as follows:
package [Link];
import [Link].*;
import [Link].*;
import [Link];
import [Link];

public class NewActivity extends Activity {


protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_new);
TextView tv1=(TextView)[Link]([Link].txt1);
[Link]("new label");
}

}
findViewByID() method returns the instance of TextView with the specified id.

Text Controls
The common text controls include TextView, EditText, AutoCompleteTextView, and
MultiAutoCompleteTextView controls.

TextView

The TextView control knows how to display text but does not allow editing.
85

Creating TextView in XML

Tag name :<TextView>

Attribute Description

android:id This is the ID which uniquely identifies the control.

android:fontFamily Font family (named by string) for the text.

android:hint Hint text to display when the text is empty.

android:text Text to display.

android:textAllCaps Present the text in ALL CAPS. Possible value either "true" or "false".

android:textColor Text color. Color value, in the form of "#rgb" or ―#rrggbb‖

android:textColorHighlight Color of the text selection highlight.

android:textColorHint Color of the hint text. Color value, in the form of "#rgb" or ―#rrggbb‖

android:textSize Size of the text. 16pt, 10sp etc.

android:textStyle Style (bold, italic, bolditalic) for the text. You can use more than one
values separated by '|'.
normal – 0, bold – 1, italic – 2

android:typeface Typeface (normal, sans, serif, monospace) for the text. You can use or
more of the following values separated by '|'.
 normal – 0, sans – 1, serif – 2, monospace– 3

android:autoLink Controls whether links such as urls and email addresses are
automatically found and converted to clickable links. Values can be
none, web, email, phone, map, all (equivalent to
web|email|phone|map).Clicking a link will cause the default intent to
be called for that action. For example,clicking a web URL will launch
the browser with the URL. Clicking a phone number will launch the
phone dialer, and so on.

<TextView android:id="@+id/text_id"
android:layout_width="300dp"
86

android:layout_height="200dp"
android:text="[Link]"
android:textColor="@android:color/txtclr"
android:textSize="50dp"
android:autoLink="web"/>

The TextView can contain a web URL or an e-mail address. When the user clicks on one of these
highlighted items, the system will take care of launching the e-mail application with the e-mail
address, or a browser with the URL.

Creating TextView completely with java code


class
[Link]
↳ [Link]
↳ [Link]

Constructor:
TextView (Context obj)
The object of Context class points to the application environment.
Eg: TextView tv1=new TextView(this);
‗this‘ points to the current object of Activity class, and it represents the current application
environment.

Accessing a TextView created in xml

TextView txt1=(TextView)[Link]([Link].text_id);

Methods in TextView class

CharSequence getText() Return the text the TextView is displaying.

int length() Returns the length of the text of TextView.

void setTextColor(int color) Sets the text color. Color can be given using
[Link] class.
Eg. [Link], [Link] etc.

final void setText(int resid) Sets the text using a resource id defined in string resource files.

final void setText(CharSequence text) Sets the text of the TextView.

void setAutoLinkMask (int type)


sets the autolink mask of TextView. [Link] class contains constants to set the
type of value passed. The type can be Linkify.EMAIL_ADDRESSES,
Linkify.WEB_ADDRESSES, or Linkify.EMAIL_ADDRESSES|Linkify.WEB_ADDRESSES.
87

package [Link];
import [Link].*;
import [Link].*;
import [Link];
import [Link];
public class NewActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_new);
TextView tv1=(TextView)[Link]([Link].txt_id);
[Link]([Link]);
[Link]("Please visit my website,[Link] or email me at
davemac327@[Link].");
}
}

EditText
[Link]
↳ [Link]
↳ [Link]
↳ [Link]

The EditText control is a subclass of TextView. The EditTextcontrol allows for text editing.
Creating EditText in XML

Tag : <EditText>

Attributes
android:editable if set to true EditText is editable.
android:text This is the Text to display.
Android:inputType specifies the type of input. The values can be

"text" Normal text keyboard.


"textEmailAddress" Normal text keyboard with the @ character.
"textUri" Normal text keyboard with the / character.
"number" Basic number keypad.
"phone" Phone-style keypad.
"textCapSentences" Normal text keyboard that capitalizes the first letter for each new
sentence.
"textCapWords" Normal text keyboard that capitalizes every word. Good for
titles or person names.
88

"textAutoCorrect" Normal text keyboard that corrects commonly misspelled


words.
"textPassword" Normal text keyboard, but the characters entered turn into dots.
"textMultiLine" Normal text keyboard that allow users to input long strings of
text that include line breaks.

Creating EditText using code


Constructor:
EditText(Context obj)

Eg. In activity class

EditText t1=new EditText(this);

Methods

EditText includes the methods getText(), setText(), setTextColor() methods of TextView.

AutoCompleteTextView

The AutoCompleteTextView control is a TextView with auto-complete functionality. Inother words,


as the user types in the TextView, the control can display suggestions for selection.
Using an AutoCompleteTextView Control

<AutoCompleteTextView android:id="@+id/actv"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

In code
AutoCompleteTextView actv = (AutoCompleteTextView) [Link]([Link]);
String lan[]={"English", "Hebrew", "Hindi", "Spanish", "German", "Greek" };
ArrayAdapter<String>aa = new ArrayAdapter<String>
(this,[Link].simple_dropdown_item_1line,lan);
[Link](aa);

The AutoCompleteTextView control suggests a language to the user. For example, if the user types
en, the control suggests English. If the user types gr, the control recommends Greek, and so on. It has
two parts: a TextView control and a control that displays the suggestion(s). To use an
AutoCompleteTextView, you can define the control in your layout file and reference it inyour activity.
You then create an adapter class that holds the suggestions and define the ID of the control that will
show the suggestion (in this case, a simple list item). The second parameter to the ArrayAdapter tells
89

the adapter to use a simple list item to show the suggestion. The final step is to associate the adapter
with the AutoCompleteTextView, using the setAdapter() method.

MultiAutoCompleteTextView

AutoCompleteTextView control offers suggestions only for the entire text in the text view. In other
words, if you type a sentence, you don‘t get suggestions for each word. MultiAutoCompleteTextView
provide suggestions as the user types. For example, when the user typed the word English followed by
a comma, and then Ge, at which point the control suggested German. If the user were to continue, the
control would offer additional suggestions.
You have to tell the control where to start suggesting again. Forexample, the control can offer
suggestions at the beginning of the sentence and after it sees a comma. The
MultiAutoCompleteTextView control requires that you give it a tokenizer that can parse the sentence
and tell it whether to start suggesting again.

Using the MultiAutoCompleteTextView Control

<MultiAutoCompleteTextView android:id="@+id/mactv"
android:layout_width="fill_parent" android:layout_height="wrap_content" />

In java code:

MultiAutoCompleteTextViewmactv = (MultiAutoCompleteTextView)
[Link]([Link]);
String s[]={"English", "Hebrew", "Hindi", "Spanish", "German", "Greek" };

ArrayAdapter<String> aa2 = new ArrayAdapter<String>(this,


[Link].simple_dropdown_item_1line,s);
[Link](aa2);

[Link](new [Link]());

The setTokenizer() method uses CommaTokenizer, so that after a comma is typed into the EditText
field, the field will again make suggestions using the array of strings. Any other characters typed in
will not trigger the field to make suggestions. So even if you were to type French Spani, the partial
word Spani would not trigger the suggestion because it did not follow a comma.
Button Controls
The different types of button controls are : the Button, the ImageButton, and the ToggleButton.
Button
class :[Link]
90

[Link]

↳ [Link]

↳ [Link]

↳ [Link]
Important attributes:
android:clickable determines whether the Button reacts to click events. Values true or false.
android:onClick name of the method in this view‘s context to invoke when the button is clicked.
( From Android 1.6 only)
Handling Click Events on a Button
When the user clicks on a Button the Button object receives an on click event.
<Button android:id="@+id/button1"
android:text="@string/basicBtnLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
accessing it in code:
package [Link];

import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity


implements OnClickListener {

protected void onCreate(Bundle savedInstanceState) {


[Link](savedInstanceState);
setContentView([Link].activity_main);
Button button1 = (Button)[Link]([Link].button1);
[Link](this);

public void onClick(View v) {

//Code to execute when the button is clicked

}
91

Steps to handle button click:


 Implement OnClickListener interface in Activity class
 Register for the on-clickevent by calling the setOnClickListener() method in Button class.
Argument is an object of the class that implements OnClickListener. (here current object,
hence this is used)

 Whenthe button is clicked, the onClick() method of the listener is called and, in this
case,launches the browser to our web site.

Since Android SDK 1.6, there is an easier way to set up a click handler for the button. In the XML for
a Button, specify an attribute for the handler, plus the Java code that is the click handler.
Setting Up a Click Handler for a Button
<Button android:id="@+id/button1"
android:text="@string/basicBtnLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="myClickHandler" />

In java code:

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {


[Link](savedInstanceState);
setContentView([Link].activity_main);
Button button1 = (Button)[Link]([Link].button1);
}
public void myClickHandler(View target) {
//Code to execute when the button is clicked
}
}}
The handler method will be called with target set to the View object representing the button that was
clicked. Notice how the switch statement in the click handler method uses the resource IDs of the
buttons to select the logic to run. Using this method means you won‘t have to explicitly create each
Button object in your code, and you can reuse the same method across multiple buttons.

The ImageButton Control


92

Image button contains an image. Image can be described in drawable resource and can be referenced
in layout xml file.
class: [Link]
Using an ImageButton
<ImageButton android:id="@+id/imgbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon" />
Setting an image in java code
ImageButton imageButton2 = (ImageButton)[Link]([Link]);
[Link]([Link]);
Here we‘ve created the image button in XML and set the button‘s image from a drawable resource.
The image file for the button must exist under /res/drawable. setImageResource() method set the
button‘s image dynamically on the button and passing it a resource ID. You don‘t need to specify the
button image in both the XML file and in code.
One of the nice features of an image button is that you can specify a transparent background for the
button. The result will be a clickable image that acts like a button butcan look like whatever you want
it to look like. Just set android:background="@null" for the image button.
Because your image may be something very different than a standard button, you can customize how
the button looks in the two other states it can be in when used in your UI. Besides appearing as
normal, buttons can have focus, and they can be pressed. Having focus simply means the button is
currently where events will go. You can direct focus to a button using the arrow keys on the keypad or
D-pad, for example. Pressed means that the button‘s appearance changes when it has been pressed but
before the user has let go. To tell Android what the three images are for our button, and which oneis
which, we set up a selector. This is a simple XML file that resides in the /res/drawable folder of our
project.
Using a Selector with an ImageButton
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="[Link]
<item android:state_pressed="true"
android:drawable="@drawable/button_pressed" />
<!-- pressed -->
<item android:state_focused="true"
android:drawable="@drawable/button_focused" />
<!-- focused -->
<item android:drawable="@drawable/icon" />
<!-- default -->
93

</selector>
First, you do not specify a <resources> tag as in values XML files. Second, the order of the button
images is important. Android will test each item in the selector, in order, to see if it matches.
Therefore, you want the normal image to be last so it is used only if the button is not pressed and if the
button does not have focus. If the normal image was listed first, it would always match and be selected
even if the button is pressed or has focus. Of course, the drawables you refer to must exist in the
/res/drawables folder. In the definition of your button in the layout XML file, you want to set the
android:src property to the selector XML file as if it were a regular drawable, like so:
<ImageButton android:id="@+id/imgbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/imagebuttonselector"/>
The ToggleButton Control
The ToggleButton control, can be in either the On or Off state. The ToggleButton‘s default behavior is
to show a green bar when in the On state and a grayed-out bar when in the Off state. Moreover, the
default behavior also sets the button‘s text to On whenit‘s in the On state and Off when it‘s in the Off
state. You can modify the text for the ToggleButton if On/Off is not appropriate for your application.
For example, if you have a background process that you want to start and stop via a ToggleButton, you
could set the button‘s text to Stop and Run by using android:textOn and android:textOff properties.
<ToggleButton android:id="@+id/tglBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toggle Button"
android:textOn="Stop"
android:textOff="Run"/>
Responding to Button presses
To detect when the user activates the button
 Implement the listener [Link]
 Assign it to the button using setOnCheckedChangeListener()
 Override the method
public void onCheckedChanged(CompoundButton obj, boolean status)
Example:

package [Link];

import [Link];
import [Link];
import [Link].*;
import [Link].*;
94

public class MainActivity extends Activity implements


[Link]{
TextView tv;

protected void onCreate(Bundle savedInstanceState) {


[Link](savedInstanceState);
setContentView([Link].activity_main);
tv=(TextView)[Link]([Link]);
ToggleButton tbn=(ToggleButton)[Link]([Link].tb1);
[Link](this);
}
public void onCheckedChanged(CompoundButton t,boolean state){

if(state)
[Link]("ON");
else
[Link]("off");
}
}
The CheckBox Control
The CheckBox control is another two-state button that allows the user to toggle its state. The
difference is that, for many situations, the users don‘t view it as a button that invokes immediate
action. From Android‘s point of view, however, it is a button, and you can do anything with a check
box that you can do with a button.
In Android, a check box can be created by creating an instance of [Link]
<LinearLayout xmlns:android="[Link]
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<CheckBox android:id="@+id/en"
android:text="English"
android:checked="true"
android:layout_width=―wrap_content"
android:layout_height="wrap_content" />
<CheckBox android:id="@+id/ma" android:text="Malayalam"

android:layout_width="wrap_content" android:layout_height="wrap_content" />

<CheckBox android:id="@+id/hi"
android:text="Hindi" android:checked="true"
95

android:layout_width="wrap_content" android:layout_height="wrap_content" />


</LinearLayout>
You manage the state of a check box by calling setChecked() or toggle(). You can obtain the state by
calling isChecked(). If you need to implement specific logic when a check box is checked or
unchecked, you can register for the on-checked event by calling setOnCheckedChangeListener() with
an implementation of the onCheckedChangeListener interface. You‘ll then have to implement the
onCheckedChanged() method, which will be called when the check box is checked or unchecked.
The RadioButton Control
RadioButton controls are an integral part of any UI toolkit. A radio button gives the users several
choices and forces them to select a single item. To enforce this single-selection model, radio buttons
generally belong to a group, and each group is forced to have only one item selected at a time.
To create a group of radio buttons in Android, first create a RadioGroup, and then populate the group
with radio buttons.
Using Android RadioButton Widgets
<LinearLayout xmlns:android="[Link]
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RadioGroup android:id="@+id/rbngp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RadioButton android:id="@+id/rb1"
android:text="Linux" android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton android:id="@+id/rb2" android:text="Windows" android:checked="true"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</RadioGroup>
</LinearLayout>
In Android, you implement a radio group using [Link] and a radio
button using [Link].
Note that the radio buttons within the radio group are, by default, unchecked to begin with, although
you can set one to checked in the XML definition. To set one of the radio buttons to the checked state
programmatically, you can obtain a reference to the radio button and call setChecked():
RadioButton r1 = (RadioButton)[Link]([Link].rb1);
[Link](true);
96

You can also use the toggle() method to toggle the state of the radio button. As with the CheckBox
control, you will be notified of on-checked or on-unchecked events if you call the
setOnCheckedChangeListener() with an implementation of the OnCheckedChangeListener interface.
You can manipulate the RadioGroup programmatically. For example, you can obtain a reference to a
radio group and add a radio button.
Adding a RadioButton to a RadioGroup in Code
RadioGroup rbg = (RadioGroup)findViewById([Link]);
RadioButton rnew = new RadioButton(this);
[Link]("Mac OS");
[Link](rnew);
Once a user has checked a radio button within a radio group, the user cannot uncheck it by clicking it
again. The only way to clear all radio buttons in a radio group is to call the clearCheck() method on the
RadioGroup programmatically.
The getCheckedRadioButtonId(), returns the resource ID of the checked item or –1 if nothing is
checked.
The ImageView Control
The ImageView controlis usedto display an image, where the image can come from a file, a content
provider, or a resource such as a drawable. You can even specify just a color, and the ImageView
willdisplay that color.
ImageViews in XML and in Code
<ImageView android:id="@+id/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon" />
<ImageView android:id="@+id/image2"
android:layout_width="125dip"
android:layout_height="25dip"
android:src="#555555" />
<ImageView android:id="@+id/image3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
In code
ImageView imgView = (ImageView)findViewById([Link].image3);
[Link]([Link] );
97

In this example, we have four images defined in XML. The first is simply the icon for ourapplication.
The second is a gray bar that is wider than it is tall. The third definition doesnot specify an image
source in the XML, but we associate an ID with this one (image3) that we can use from our code to set
the image.
We first of course must get a reference to the ImageView by finding it using its resource ID. The first
setter method, setImageResource(), simply uses the image‘s resource ID to locate the image file to
supply the image for our ImageView.

Date and Time Controls


Android offers several date and time based controls specifically, DatePicker, TimePicker,
DigitalClock, and AnalogClock.
The DatePicker and TimePicker Controls
The DatePicker control is used to select a date and the TimePicker control is used to pick a time.
Defining in XML ([Link])
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView android:id="@+id/dt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnlabel"
/>
<DatePicker android:id="@+id/dp1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TimePicker
android:id="@+id/tp1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

[Link]
package [Link];

import [Link];
import [Link];
import [Link].*;
98

import [Link].*;

public class MainActivity extends Activity implements [Link]


{
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link]);
Button btn1=(Button)[Link]([Link].button1);
[Link](this);
}

public void onClick(View v){


DatePicker dp = (DatePicker)[Link]([Link].dp1);
TimePicker tp = (TimePicker)[Link]([Link].tp1);
TextView dt = (TextView)findViewById([Link].dt1);
int month=[Link]() + 1;
int day=[Link]();
int year=[Link]();
String date=day+"-"+month+"-"+year;
int h1=[Link]();
int m1=[Link]();
String time=h1+":"+m1;
[Link]("Selectd Date and Time "+date+ " " +time);

}
}
As with any other control in the Android toolkit, you can access the controls programmatically to
initialize them or to retrieve data from them. Note that for the month, the internal value is zero-based,
which means that January is 0 and December is 11.

XML attributes

android:calendarTextColor The text color list of the calendar.

android:datePickerMode Defines the look of the widget. The values can be


Spinner Date picker with spinner controls to select the date.
Calendar Date picker with calendar to select the date

android:endYear The last year (inclusive), for example "2010".

android:firstDayOfWeek The first day of week according to Calendar.

android:maxDate The maximal date shown by this calendar view in mm/dd/yyyy


format.

android:minDate The minimal date shown by this calendar view in mm/dd/yyyy


format.

android:startYear The first year (inclusive), for example "1940".


99

Methods

int getDayOfMonth()

int getFirstDayOfWeek()
Gets the first day of week.

long getMaxDate()
Gets the maximal date supported by this DatePicker in milliseconds since January 1,
1970 00:00:00 in getDefault() time zone.

long getMinDate()
Gets the minimal date supported by this DatePicker in milliseconds since January 1,
1970 00:00:00 in getDefault() time zone.

int getMonth()

int getYear()

void init(int year, int monthOfYear, int


dayOfMonth, [Link] onDateChangedListener)
Initialize the date.

void setEnabled(boolean enabled)


Set the enabled state of this view.

void setFirstDayOfWeek(int firstDayOfWeek)


Sets the first day of week.

void setMaxDate(long maxDate)


Sets the maximal date supported by this DatePicker in milliseconds since January 1,
1970 00:00:00 in getDefault() time zone.

void setMinDate(long minDate)


Sets the minimal date supported by this NumberPicker in milliseconds since January 1,
1970 00:00:00 in getDefault() time zone.

void updateDate(int year, int month, int dayOfMonth)


Update the current date.

TimePicker attributes

android:timePickerMode

spinner Defines the look of the widget. The values can be.

clock Time picker with spinner controls to select the time.


100

TimePicker methods

int getHour()
Returns the currently selected hour using 24-hour time.

int getMinute()
Returns the currently selected minute.

void setCurrentHour(Integer currentHour)


This method was deprecated in API level 23. Use setHour(int)

void setCurrentMinute(Integer currentMinute)


This method was deprecated in API level 23. Use setMinute(int)

void setEnabled(boolean enabled)


Set the enabled state of this view.

void setHour(int hour)


Sets the currently selected hour using 24-hour time.

void setIs24HourView(Boolean is24HourView)


Sets whether this widget displays time in 24-hour mode or 12-hour mode with an
AM/PM picker.

void setMinute(int minute)


Sets the currently selected minute..

void setOnTimeChangedListener([Link] onTimeChange


dListener)
Set the callback that indicates the time has been adjusted by the user.

The DigitalClock and AnalogClock Controls


Android also offers DigitalClock and AnalogClock controls. The digital clock supports seconds in
addition to hours and minutes. The AnalogClock in Android is a two-handed clock, with one hand for
the hour indicator and the other hand for the minute indicator.
Adding a DigitalClock or an AnalogClock in XML
<DigitalClockandroid:layout_width="wrap_content" android:layout_height="wrap_content" />
<AnalogClockandroid:layout_width="wrap_content" android:layout_height="wrap_content" />

These two controls are really just for displaying the current time and we cannot modify the date or
time.
101

The MapView Control


The [Link] control can display a map. You can instantiate this control
either via XML layout or code, but the activity that uses it must extend MapActivity.
Creating a MapView Control via XML Layout
<LinearLayout xmlns:android="[Link]
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<[Link]
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="myAPIKey"/>
</LinearLayout>

UNDERSTANDING ADAPTERS
List controls are used to display collections of data. But instead of using a single type of control to
manage both the display and the data, Android separates these two responsibilities into list controls
and adapters. List controls are classes that extend [Link] and include
ListView,GridView, Spinner, and Gallery.
AdapterView class hierarchy

AdapterView itself extends [Link], which means that ListView,GridView, and so


on are container controls. In other words, list controls contain collections of child views. . Adapters in
Android are a bridge between the Adapter View and the underlying data for that [Link] purpose of
an adapter is to manage the data for an AdapterView and to provide the child views for it .
102

ArrayAdapter

The ArrayAdapter is the simplest of the adapters in Android. It links the array to the Adapter View.
The default ArrayAdapter converts an array item into a String object putting it into a TextView. The
TextView is then displayed in the AdapterView (a ListView for example). It specifically targets list
controls and assumes that TextView controls represent the list items (the child views).
Class:
[Link]
↳ [Link]
↳ [Link]<T>

Constructor
ArrayAdapter (Context context, int resource, T[] objects)
103

Parameters

context The current context.

resource int: The resource ID for a layout file containing a TextView to use when
instantiating views.

objects T: The objects to represent in the ListView.

When you create the adapter, you need to supply the layout for displaying each array string. You can
define your own or use one of Android‘s, such as:

[Link].simple_list_item_1
Creating a new ArrayAdapter using a layout defined in Android
String na[]={"Dave","Satya","Dylan"};
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
[Link].simple_list_item_1,na);
Here this represents the context, [Link].simple_list_item_1 the childLayout resource ID
(already defined in Android) and array of strings na as the actual data.
Example 2: using a user defined layout
[Link]
<?xml version="1.0" encoding="utf-8"?>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

In activity class
String na[]={"Dave","Satya","Dylan"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, [Link], na);
The other types of adapters that Android provides are as follows:
CursorAdapter: This adapter, also meant to be used in a ListView, provides data to the list via a cursor.
SimpleAdapter: It is generally used to populate a list with static data (possiblyfrom resources).
ResourceCursorAdapter: This adapter extends CursorAdapter and knows how to create views from
resources.
SimpleCursorAdapter: This adapter extends ResourceCursorAdapter and creates
TextView/ImageView views from the columns in the cursor. The views are defined in resources.
104

Using Adapters with AdapterViews


Android List controls that supports Adapter binding extend the [Link] class.
ListView, GridView, Spinner and Gallery extends the AdapterView

ListView
The ListView control displays a list of items vertically. That is, if we‘ve got a list of items to view and
the number of items extends beyond what we can currently see in the display, we can scroll to see the
rest of the itemsAs we described previously, adapters link list controls to the data and help prepare the
child views for the list control. Items in a ListView can be clicked to take immediate action or selected
to act on the set of selected items later.
Class:
[Link]
Methods
int getSelectedItemPosition ()

Get the position of the currently selected list item.

ListView getListView ()

Get the activity's list view widget.

long getSelectedItemId ()

Get the cursor row ID of the currently selected list item.

void setListAdapter (ListAdapter adapter)

Provide the adapter for the list view.

void setSelection (int position)

Set the currently selected list item to the specified position with the adapter's data

Using the ListView control

res/layout/activity_main.xml

<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView android:id="@+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
105

<TextView android:id="@+id/lab"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</TextView>
</LinearLayout>

res/layout/activity_listview.xml

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


<!-- Single List Item Design -->
<TextView xmlns:android="[Link]
android:id="@+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold">
</TextView>

[Link]
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class ListDisplay extends Activity implements OnItemClickListener{

@Override
protected void onCreate(Bundle savedInstanceState){
[Link](savedInstanceState);
setContentView ( [Link].activity_main );
String[] mobileArray={"Android","IPhone","WindowsMobile","Blackberry‖,"Max OS X"};
ArrayAdapter adapter =new ArrayAdapter <String> (this, [Link].activity_listview,
mobileArray);
ListView listView= (ListView) findViewById ([Link].mobile_list);
[Link](adapter);
[Link](this);
}
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
int itemPosition = position;
106

// ListView Clicked item value


String itemValue = (String) [Link](position);
TextView tv=(TextView)[Link]([Link]);
[Link]("Click : \n Position :"+itemPosition+" \n ListItem : " +itemValue);
}
}
To read selected item from ListView implement OnItemClickListener and override the following
method.
public void onItemClick (AdapterView<?> parent, View view, int position, long id)
parent AdapterView where the click happened

v View: The view that was clicked within the ListView

position int: The position of the view in the list

id long: The row id of the item that was clicked

[Link](this);
This method registers the listView object with OnItemClickListener

Using the ListView control by extending ListActivity


You generally use a ListView by writing a new activity that extends [Link].
ListActivity contains a ListView, and you set the data for the ListView by calling the
setListAdapter()method.

activity_list.xml
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView android:id="@+id/output"
android:layout_height="wrap_content"
android:text="Click : " android:layout_width="fill_parent" />

<ListView
android:id="@android:id/list"
107

android:layout_height="wrap_content"
android:layout_width="match_parent">
</ListView>

</LinearLayout>
NOTE :
When creating Listview with ListActivity then two things are MUST contain a ListView with the
android:id attribute set to @android:id/list ( NOT android:id="@+id/list" ). if you will defined
ListView with the android:id attribute set to @+id/list then it will give error.
[Link]
public class ListDemo extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_list);
//listView = (ListView) findViewById([Link]); not required
String[] values = { "Android‖, ‖Symbian‖, ‖IOS‖, ―Windows CE‖};
// Define a new AdapterFirst parameter – Context, Second parameter - Layout for the //row
Third - the Array of data
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
[Link].simple_list_item_1, values);
// Assign adapter to List
setListAdapter(adapter);
}
protected void onListItemClick(ListView lv, View v, int position, long id) {
[Link](lv, v, position, id);
TextView content= (TextView) findViewById ([Link]);
String itemValue = (String) [Link](position);
[Link]("Click : \n Position :"+position+" \n ListItem : " +itemValue);
}
}
When click on list item then onListItemClick() method in ListViewItemClickListener is executed.
protected void onListItemClick (ListView l, View v, int position, long id)
108

The GridView Control


Android has a GridView control that can display data in the form of a grid. The contents of the grid
can be text, images, etc. The GridView control displays information in a grid. The usage pattern for
the GridView is to define the grid in the XML layout and then bind the data to the grid using an
[Link].
Definition of a GridView in an XML Layout and Associated Java Code
<? xml version="1.0" encoding="utf-8"?>
<!-- This file is at /res/layout/[Link] -->
<GridView xmlns:android="[Link]
android:id="@+id/gridview" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:padding="10px"
android:verticalSpacing="10px" android:horizontalSpacing="10px"
android:numColumns="3" android:columnWidth="100px"
android:stretchMode="columnWidth" android:gravity="center" />

[Link]
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];

public class GridActivity extends Activity {


protected void onCreate(Bundle savedInstanceState)
{
[Link](savedInstanceState);
setContentView([Link]);
GridView gv = (GridView) findViewById ([Link]);
Integer values[]={1,2,3,4,5,6,7,8,9};
ArrayAdapter<Integer> adapter = new
ArrayAdapter<Integer>(this,[Link].simple_list_item_1, values);
[Link](adapter);
109

}
}
Lists are generally one-dimensional, whereas grids are two-dimensional. The grid actually displays
list-oriented data. And it turns out that the list is displayed by rows. That is, the list goes across the
first row, then across the second row, and soon.

The Spinner Control


The Spinner control is like a drop-down menu. It is typically used to select from a relatively short list
of choices. If the choice list is too long for the display, a scrollbar is automatically added for you. You
can instantiate a Spinner via XML layout as simply as this:
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner android:id="@+id/spinner"
android:prompt="@string/spinnerprompt"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
Although a spinner is technically a list control, it will appear to you more like a simple TextView
control. In other words, only one value will be displayed when the spinner is at rest. The purpose of
the spinner is to allow the user to choose from a set of predetermined values: when the user clicks the
small arrow, a list is displayed, and the
user is expected to pick a new value. Populating this list is done in the same way as the
other list controls: with an adapter.
Notice the new attribute called android:prompt for setting a prompt at the top of the list to choose
from. The actual text for our spinner prompt is in our /res/values/[Link] file.
Code to Create a Spinner
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity {


110

public void onCreate(Bundle savedInstanceState) {


[Link](savedInstanceState);
setContentView([Link].activity_main);
Spinner spinner = (Spinner)findViewById([Link]);
String[] values = { "Android", "Symbian", "IOS", "Windows CE"};
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
[Link].simple_spinner_item, values);
[Link]
([Link].simple_spinner_dropdown_item);
[Link](adapter);
}
}

Because a spinner is often used like a drop-down menu, it is common to see the adapter get the list
choices from a resource file. If the values are stored in an array resource, the adapter can be created
using the method createFromResource().
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Spin</string>
<string name="spinnerprompt">Select One</string>
<string-array name="values">
<item> Android</item>
<item> Symbian </item>
<item>IOS</item>
<item>Windows CE</item>
</string-array>
</resources>

ArrayAdapter<CharSequence> adapter =
[Link](this, [Link],
[Link].simple_spinner_item);
The layout ([Link].simple_spinner_item), supplied as a parameter to the
[Link]() method, defines how the spinner looks in normal [Link]
layout for this list is set using the setDropDownViewResource() method. Again in this example, we‘re
111

using Android-provided layouts for these two needs, so if you want to inspect the definition of either
of these layouts, you can visit the Android res/layout folder
The Gallery Control
The Gallery control is a horizontally scrollable list control that always focuses at the center of the list.
This control generally functions as a photo gallery in touch mode. You
can instantiate a Gallery via either XML layout or code: The Gallery control is typically used to
display images, so your adapter is likely going to be specialized for images.
<Gallery android:id="@+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

Creating Custom Adapters


Standard adapters in Android are easy to use, but they have some limitations. To address this, Android
provides an abstract class called BaseAdapter that you can extend if you need a custom adapter. You
would use a custom adapter if you had special data management needs or if you wanted more control
over how to display child views. You might also use a custom adapter to improve performance by
using caching techniques.
Gallery is used to show Views in a horizontal list, and user will select a view , User selected view will
be shown in center of the Horizontal list
The items of Gallery are get from an Adapter, just like ListView, in which ListView items are get
from an Adapter.
We need to make an Adapter class that extends BaseAdapter class and override getView() method.
getView() method known as automatically for all items of Gallery

[Link]
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Gallery android:id="@+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

<ImageView android:id="@+id/imgView"
112

android:layout_marginTop="100dp"
android:layout_width="250dp"
android:layout_gravity="center_horizontal"
android:layout_height="250dp"
android:src="@drawable/img01" />
</LinearLayout>

[Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity implements OnItemClickListener {

ImageView selectedImage;
GalleryImageAdapter gadapter;
@Override
public void onCreate(Bundle savedInstanceState)
{
[Link](savedInstanceState);
setContentView([Link].activity_main);
Gallery gallery = (Gallery) findViewById([Link]);
selectedImage=(ImageView)findViewById([Link]);
[Link](1);
gadapter= new GalleryImageAdapter(this);
[Link](gadapter);
[Link](this);
113

}
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// show the selected Image
[Link]([Link][position]);
}
}

[Link]

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class GalleryImageAdapter extends BaseAdapter


{
private Context mContext;
public Integer[] images = {[Link].img01,[Link].img02, [Link].img03,
[Link].img04, [Link].img05, [Link].img06,
[Link].img07, [Link].img08};

public GalleryImageAdapter(Context context){


mContext = context;
}
public int getCount() {
return [Link];
}
114

public Object getItem( int position) {


return position;
}
public long getItemId(int position) {
return position;
}
// Override this method according to your need
public View getView(int index, View view, ViewGroup viewGroup)
{
ImageView i = new ImageView(mContext);
[Link](images[index]);
[Link](new [Link](200, 200));
[Link]([Link].FIT_XY);
return i;
}
}
Android Gallery is a View commonly used to display items in a horizontally scrolling list that locks
the current selection at the center.
Android Gallery View Overview
The items of Gallery are populated from an Adapter, similar to ListView, in which ListView items
were populated from an Adapter
We need to create an Adapter class which extends BaseAdapter class and override getView() method.
getView() method called automatically for all items of Gallery. It belongs
to [Link] class.
115

UNDERSTANDING LAYOUT MANAGERS


Android offers a collection of view classes that act as containers for views. These container classes are
called layouts (or layout managers), and each implements a specific strategy to manage the size and
position of its children. For example, the LinearLayout class lays out its children either horizontally or
vertically, one after the other. Layout managers extend [Link].
Android Layout Managers
LinearLayout Organizes its children either horizontally or vertically
TableLayout Organizes its children in tabular form
RelativeLayout Organizes its children relative to one another or to the parent
FrameLayout Allows you to dynamically change the control(s) in the layout
GridLayout Organizes its children in a grid arrangement

Common Attributes
android:id This is the ID which uniquely identifies the layout.

android:layout_width This is the width of the layout. The value can be


fill_parent, match_parent, or wrap_content
android:layout_height This is the height of the layout

android:layout_marginTop This is the extra space on the top side of the layout.

android:layout_marginBottom This is the extra space on the bottom side of the layout.

android:layout_marginLeft This is the extra space on the left side of the layout.

android:layout_marginRight This is the extra space on the right side of the layout.

android:layout_gravity This specifies how child Views are positioned.


Its value can be left, right, center, top, bottom, fill, fill_horizontal,
fill_vertical etc.
android:layout_weight This specifies how much of the extra space in the layout should be
allocated to the View.

android:layout_x This specifies the x-coordinate of the layout.

android:layout_y This specifies the y-coordinate of the layout.


116

The LinearLayout Manager


This layout manager organizes its children either horizontally or vertically based on the value of the
orientation property.
LinearLayout with a Horizontal Configuration
<LinearLayout xmlns:android="[Link]
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- add children here-->
</LinearLayout>
You can create a vertically oriented LinearLayout by setting the value of orientation to vertical.
You use weight to assign size importance to a control relative to the other controls in the container
(layout).
LinearLayout with Weight Configurations
<LinearLayout xmlns:android="[Link]
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText android:layout_width="fill_parent"
android:layout_weight="0.0"
android:layout_height="wrap_content" android:text="one"
android:gravity="left"/>
<EditText android:layout_width="fill_parent" android:layout_weight="1.0"
android:layout_height="wrap_content" android:text="two"
android:gravity="center"/>
<EditText android:layout_width="fill_parent" android:layout_weight="0.0"
android:layout_height="wrap_content" android:text="three"
android:gravity="right"/>
</LinearLayout>
Here the container has three controls: one has a weight of 1, whereas the others have a weight of 0. In
this case, the control whose weight equals 1 will consume the empty space in the container. The
android:layout_weight attribute of the center component is set to 1.0 and leaves the others to the
default value of 0.0. The center component should take up all the remaining whitespace in the
container and that the other two components should remain at their ideal size. Similarly, if you want
two of the three controls in the container to share the remaining whitespace among them, you would
set the weight to 1.0 for those two and leave the third one at 0.0.
117

android:gravity vs. android:layout_gravity


The android:gravity is a setting used by the view, whereas android:layout_gravity is used by the
container ([Link]). For example, you can set android:gravity to center to have the
text in the EditText centered within the control. Similarly, you can align an EditText to the far right of
a LinearLayout (the container) by setting android:layout_gravity="right".
<LinearLayout xmlns:android="[Link]
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText android:layout_width="wrap_content" android:gravity="center"
android:layout_height="wrap_content" android:text="one"
android:layout_gravity="right"/>
</LinearLayout>
The text is centered in the EditText, which is aligned to the right of the LinearLayout.

The TableLayout Layout Manager


The TableLayout layout manager is an extension of LinearLayout. This layout manager structures its
child controls into rows and columns.
A Simple TableLayout
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="[Link]
android:layout_width="fill_parent" android:layout_height="fill_parent">
<TableRow>
<TextView android:text="First Name:" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText android:text="Edgar" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow>
<TextView android:text="Last Name:"
android:layout_width="wrap_content" android:layout_height="wrap_content"
/>
<EditText android:text="Poe" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
118

To use this layout manager, you create an instance of TableLayout and place TableRow elements
within it. These TableRow elements contain the controls of the table. Because the contents of a
TableLayout are defined by rows, Android determines the number of columns in the table by finding
the row with the most cells.

Using an EditText Instead of a TableRow


<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="[Link]
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:stretchColumns="0,1,2" >
<EditText android:text="Fullname:"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
<TableRow>
<TextView android:text="Edgar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:text="Allen"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:text="Poe"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>

Notice that the EditText takes up the entire width of the screen, even though we have not specified this
in the XML layout. That‘s because children of TableLayout always span the entire row. In other
words, children of TableLayout can specify android:layout_width="wrap_content", but they are forced
to accept fill_parent. They can, however, set android:layout_height.
The android:stretchColumns property on the TableLayout is set to "0,1,2". This gives a hint to the
TableLayout that columns 0, 1, and 2 can be stretched if required, based on the contents of the table.
The android:shrinkColumns helps to wrap the content of a column or columns if other columns require
more space. The android:collapseColumns helps to make columns invisible. Note that columns are
identified with a zero-based indexing scheme. TableLayout also offers android:layout_span. You can
use this property to have a cell span multiple columns. At times, you might also need to provide
119

spacing within the contents of a cell or a control. The Android SDK supports this via android:padding.
It lets you control the space between a view‘s outer boundary and its content.
Using android:padding
<LinearLayout xmlns:android="[Link]
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText android:text="one"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:padding="40px" />
</LinearLayout>
The padding set to 40px creates 40 pixels of whitespace between the EditText control‘s outer
boundary and the text displayed within it. The android:padding sets the padding for all sides: left,
right, top, and bottom. You can control the padding for each side by using android:leftPadding,
android:rightPadding, android:topPadding, and android:bottomPadding.

The RelativeLayout Layout Manager


RelativeLayout manager implements a policy where the controls in the container are laid out relative
to either the container or another control in the container.
Attribute Description
android:layout_above Positions the bottom edge of this control above the given
control. The value must be a resource reference ID to that
control.

android:layout_alignBottom Positions the bottom edge of this control match the bottom edge
of the given control. The value must be a resource reference ID
to that control.

android:layout_alignLeft Makes the left edge of this view match the left edge of the
given view ID. The value must be a resource reference ID to
that control.

android:layout_alignParentBottom If true, makes the bottom edge of this view match the bottom
edge of the parent. Must be a boolean value, either "true" or
"false".

android:layout_alignParentEnd If true, makes the end edge of this view match the end edge of
the parent. Must be a boolean value, either "true" or "false".
120

android:layout_alignParentLeft If true, makes the left edge of this view match the left edge of
the parent. Must be a boolean value, either "true" or "false".

android:layout_alignParentRight If true, makes the right edge of this view match the right edge
of the parent. Must be a boolean value, either "true" or "false".

android:layout_alignParentStart If true, makes the start edge of this view match the start edge of
the parent. Must be a boolean value, either "true" or "false".

android:layout_alignParentTop If true, makes the top edge of this view match the top edge of
the parent. Must be a boolean value, either "true" or "false".

android:layout_alignRight Makes the right edge of this view match the right edge of the
given anchor view ID and must be a reference to another
resource, in the form "@[+][package:]type:name".

android:layout_alignStart Makes the start edge of this view match the start edge of the
given anchor view ID and must be a reference to another
resource, in the form "@[+][package:]type:name".

android:layout_alignTop Makes the top edge of this view match the top edge of the
given anchor view ID and must be a reference to another
resource, in the form "@[+][package:]type:name".

android:layout_below Positions the top edge of this view below the given anchor view
ID and must be a reference to another resource, in the form
"@[+][package:]type:name".

android:layout_centerHorizontal If true, centers this child horizontally within its parent. Must be
a boolean value, either "true" or "false".

android:layout_centerInParent If true, centers this child horizontally and vertically within its
parent. Must be a boolean value, either "true" or "false".

android:layout_centerVertical If true, centers this child vertically within its parent. Must be a
boolean value, either "true" or "false".
121

android:layout_toEndOf Positions the start edge of this view to the end of the given
anchor view ID and must be a reference to another resource, in
the form "@[+][package:]type:name".

android:layout_toLeftOf Positions the right edge of this view to the left of the given
anchor view ID and must be a reference to another resource, in
the form "@[+][package:]type:name".

android:layout_toRightOf Positions the left edge of this view to the right of the given
anchor view ID and must be a reference to another resource, in
the form "@[+][package:]type:name".

android:layout_toStartOf Positions the end edge of this view to the start of the given
anchor view ID and must be a reference to another resource, in
the form "@[+][package:]type:name".

Using a RelativeLayout Layout Manager


<RelativeLayout xmlns:android="[Link]
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/userNameLbl"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Username: " android:layout_alignParentTop="true" />
<EditText android:id="@+id/userNameText"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_toRightOf="@id/userNameLbl" />
<TextView android:id="@+id/pwdLbl"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/userNameText"
android:text="Password: " />
<EditText android:id="@+id/pwdText"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_toRightOf="@id/pwdLbl"
android:layout_below="@id/userNameText" />
122

</RelativeLayout>

The FrameLayout Layout Manager


Android offers FrameLayout manager that is mainly used to display a single item. It is mainly used to
dynamically display a single view, but you can populate it with many items, setting one to visible
while the others are invisible.
Populating FrameLayout
activity_next.xml

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


<FrameLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ImageView android:id="@+id/imgv1" android:src="@drawable/pogo"


android:scaleType="fitCenter"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
<ImageView android:id="@+id/imgv2" android:src="@drawable/rocket"
android:scaleType="fitCenter"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:visibility="gone" />

</FrameLayout>

[Link]

package [Link];

import [Link];
import [Link].*;
import [Link];
import [Link];
import [Link];
public class MainActivity extends Activity implements OnClickListener{
ImageView img1,img2;

protected void onCreate(Bundle savedInstanceState) {


[Link](savedInstanceState);
setContentView([Link].activity_next);
img1 = (ImageView)[Link]([Link].imgv1);
img2 = (ImageView)[Link]([Link].imgv2);
[Link](this);
[Link](this);
}
123

public void onClick(View view) {


if([Link]()==[Link].imgv1)
{
[Link]([Link]);
[Link]([Link]);
}
if([Link]()==[Link].imgv2)
{
[Link]([Link]);
[Link]([Link]);
}

}
}

The idea of the demonstration is to load two ImageView objects in the FrameLayout, with only one of
the ImageView objects visible at a time. In the UI, when the user clicks the visible image, we hide one
image and show the other one.
We define a FrameLayout with two ImageView objects (an ImageView is a control that knows how to
display images). Notice that the second ImageView‘s visibility is set to gone, making the control
invisible.
FrameLayout, however, does not force you to have only one control visible at a time. If you add many
controls to the layout, FrameLayout will simply stack the controls, one on top of the other, with the
last one on top. This can create an interesting UI. For example,
Another interesting aspect of the FrameLayout is that if you add more than one control to the layout,
the size of the layout is computed as the size of the largest item in the Container.
The GridLayout Layout Manager
GridLayout lays out views in a grid pattern of rows and columns. A row and column value can be
specified for a view. Views can span multiple grid cells. More than one view can be put into the same
grid cell.
attributes
layout_column specify the left-most column
layout_columnSpan specifies the number of columns the view takes up
layout_row specify the left-most row
layout_rowSpan specifies the number of rows the view takes up

[Link]
<GridLayout xmlns:android="[Link]
android:id="@+id/GridLayout1" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:columnCount="3">
124

<Button android:id="@+id/button3"
android:layout_column="0" android:layout_gravity="left|top"
ndroid:layout_row="0" android:text="Button" />

<Button android:id="@+id/button1" android:layout_column="1"


android:layout_gravity="left|top" android:layout_row="0"
android:text="Button" />

<Button android:id="@+id/button2"
android:layout_column="2" android:layout_gravity="fill_vertical"
android:layout_row="0" android:layout_rowSpan="2"
android:text="Button" />

<Button android:id="@+id/button4"
android:layout_column="0" android:layout_columnSpan="2"
android:layout_gravity="fill_horizontal" android:layout_row="1"
android:text="Button" />

</GridLayout>

<include /> tag in a layout file.


This tag allows you to insert a layout into another layout.
<include layout="@layout/layoutfile1" />

<LinearLayout xmlns:android="[Link]
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<include layout="@layout/activity_next”/>

<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>
...

</LinearLayout>

To set the orientation of the device in code


import [Link];
...
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
This code can be defined in onCreate() method of Activity class and forces your application to appear
on the device in landscape mode.
125

UNIT IV
WORKING WITH MENUS
Android SDK has extensive support for menus. It supports regular menus, submenus, context menus,
icon menus, secondary menus, and alternative menus. Android 3.0, in addition, introduced the action
bar, which integrates well with menu items. Now Android 4.0 has introduced pop-up menus: menus
that can be invoked at any time based on a button click or any other UI event. In Android, menus,
much like other resources, can be represented as both Java objects and entries in XML files. Android
generates resource IDs for each of the loaded menu items. Being resources, all menu items take
advantage of auto-generated resource IDs.
Understanding Android Menus
The key class in Android menu support is [Link]. Every activity in Android is
associated with one menu object of this type. The menu object then contains a number of menu items
and submenus. Menu items are represented by [Link]. Submenus are represented
by [Link]. These relationships are graphically represented in Figure.
126

Menu object contains a set of menu items. A menu item carries the following attributes:
Name : A string title
Menu item ID : An integer
Group ID : An integer representing which group this item should be part of.
Sort order : An integer identifying the order of this menu item when it is displayed in the
menu.
The name and menu item ID attributes are self explanatory. You can group menu items together by
assigning each one a group ID. Multiple menu items that carry the same group ID are considered part
of the same group. The sort-order attribute demands a bit of coverage. If one menu item carries an
order number of 4 and another menu item carries an order number of 6, the first menu item will appear
above the second menu item in the menu.
Working with Menus
Creating a Menu
In the Android SDK, you don‘t need to create a menu object from scratch. Because an activity is
associated with a single menu, Android creates this single menu for that activity and passes it to the
onCreateOptionsMenu() callback method of the activity class. (As the name of the method indicates,
menus in Android are also known as options menus.) Prior to SDK 3.0, onCreateOptionsMenu() is
called the first time an activity‘s options menu is accessed. Starting with 3.0, this method is called as
part of activity creation. This change is due to the fact that the action bar is always present in an
activity. A menu item that you create in this method for the options menu may sit in an action bar.
Because an action bar is always visible (unlike the options menu), the action bar must know its menu
items from the beginning. So Android cannot wait until the user opens an options menu to call the
onCreateOptionsMenu() method. This callback menu setup method allows you to populate the single
passed-in menu with a set of menu items.
Signature for the onCreateOptionsMenu Method
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// populate menu items
return true;
}
Once the menu items are populated, the code should return true to make the menu visible. If this
method returns false, the menu is invisible.
To add an item into the menu add() method in Menu class is used.
127

MenuItem add (int groupId, int itemId, int order, CharSequence title)

MenuItem add (int titleRes)

MenuItem add (CharSequence title)

MenuItem add (int groupId, int itemId, int order, int titleRes)

titleRes represenrs a string resource identifier instead of the string


All these methods returns the MenuItem object.

Working with Menu Groups


Using Group IDs to Create Menu Groups
Override this method in Activity class
public boolean onCreateOptionsMenu(Menu menu) {
int group1 = 1;
[Link] (group1, 1, 1, "item1");
[Link](group1, 2, 2,"item2");
int group2 = 2;
[Link] (group2, 3, 3, "item3");
[Link] (group2, 4, 4, "item4");
return true; // it is important to return true
}
Notice how the menu item IDs and the order IDs are independent of the groups. Android provides a set
of methods on the [Link] class that are based on group IDs. You can manipulate a
group‘s menu items using these methods:
void removeGroup(int groupid)
void setGroupCheckable((int groupid , boolean checkable, boolean exclusive)
setGroupEnabled((int groupid ,boolean enabled)
setGroupVisible(id,visible)
removeGroup() removes all menu items from that group, given the group ID.
You can enable or disable menu items in a given group using the setGroupEnabled method().
Similarly, you can control the visibility of a group of menu items using setGroupVisible().
setGroupCheckable()method is used to show a check mark on a menu item when that menu item is
selected. When applied to a group, it enables this functionality for all menu items within that group. If
128

this method‘s exclusive flag is set, only one menu item within that group is allowed to go into a
checked state. The other menu items remain unchecked.
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MenuActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);

}
public boolean onCreateOptionsMenu(Menu menu) {
[Link](menu);
[Link](0,1,1,"Clear"); // Group id , item id, order, title
[Link](0,2,2,"Format");
[Link](0,3,3,"New");
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {

TextView tv1=(TextView)[Link]([Link].tv1);
switch([Link]()) {
case 1:
[Link](""); //clears the TextView
break;
case 2:
[Link]([Link]); //set a color to the
//TextView
break;
case 3:
[Link]("welcome"); // set a new text to the TextView
}
return true;
}
}

Loading Menus through XML Files


You can define menus through XML files, which is possible in Android because menus are also
resources. The XML approach to menu creation offers several advantages, such as the ability to name
menus, order them automatically, and give them IDs. Follow these steps to work with XML-based
menus:
129

1. Define an XML file with menu tags.


2. Place the file in the /res/menu subdirectory. The name of the file is arbitrary, and you can have as
many files as you want. Android automatically generates a resource ID for this menu file.
3. Use the resource ID for the menu file to load the XML file into the menu.
4. Respond to the menu items using the resource IDs generated for each menu item. The following
sections talk about each of these steps and provide corresponding code snippets.
Structure of an XML Menu Resource File
All menu files start with the same high-level menu tag followed by a series of group tags. Each of
these group tags corresponds to the menu item group. You can specify an ID for the group using the
@+id approach. Each menu group has a series of menu items with their menu item IDs tied to
symbolic names.
a) Create a menu in XML File
<menu xmlns:android="[Link] >
<group android:id="@+id/mg1">
<item android:id="@+id/m1"
android:orderInCategory="1"
android:title="Clear"/>
<item android:id="@+id/m2"
android:orderInCategory="2"
android:title="Format"/>
<item android:id="@+id/m3"
android:orderInCategory="3"
android:title="New"/>
</group>
</menu>
The menu XML file has one group. Based on the resource ID definition @+id/mg1, this group is
automatically assigned a resource ID called mg1 in the [Link] resource ID file. Similarly, all the child
menu items are allocated menu item IDs based on their symbolic resource ID definitions in this XML
file.
b) Inflating XML Menu Resource Files in Activity class
Let‘s assume that the name of this XML file is [Link]. You need to place this file in the /res/menu
subdirectory. Placing the file in /res/menu automatically generates a resource ID called [Link].
Android provides a class called [Link] to populate Menu objects from XML files.
You use an instance of this MenuInflater to make use of the [Link] resource ID to populate a
menu object.
package [Link];

import [Link];
import [Link];
import [Link].*;
import [Link];
130

public class MenuActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
}

public boolean onCreateOptionsMenu(Menu menu) {


MenuInflater inflater = getMenuInflater(); //from activity
[Link]([Link], menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
TextView tv1=(TextView)[Link]([Link].tv1);
switch([Link]()) {
case [Link].m1:
[Link](""); //clears the TextView
break;
case [Link].m2:
[Link]([Link]); //set a color to the TextView
break;
case [Link].m3:
[Link]("welcome"); // set a new text to the TextView
}
return true;
}
}
In this code, you first get the MenuInflater from the Activity class and then tell it to inflate the menu
XML file into the menu directly.
Responding to Menu Items
There are multiple ways of responding to menu item clicks in Android. You can use the
onOptionsItemSelected() method of the activity class; you can use stand-alone listeners.
Responding to Menu Items through onOptionsItemSelected
When a menu item is clicked, Android calls the onOptionsItemSelected() callback method on the
Activity class
Signature and Body of the onOptionsItemSelected Method
public boolean onOptionsItemSelected(MenuItem item) {
switch([Link]()) {
.....
//for items handled
return true;
//for the rest
...return [Link](item);
}}
131

The key pattern here is to examine the menu item ID through the getItemId() method of the MenuItem
class and do what‘s necessary. If onOptionsItemSelected() handles a menu item, it returns true. The
menu event will not be further propagated. For the menu item callbacks that onOptionsItemSelected()
doesn‘t deal with, onOptionsItemSelected() should call the parent method through
[Link](). The default implementation of the onOptionsItemSelected() method
returns false so that the normal processing can take place. Normal processing includes alternative
means of invoking responses for a menu click, such as invoking a listener directly that can be directly
tied to the menu item.
Responding to Menu Items through Listeners
A menu item allows you to register a listener that could be used as a callback. A listener implies object
creation and a registry of the listener. This approach is a two-step process. In the first step, you
implement the OnMenuClickListener interface. Then, you take an instance of this implementation and
pass it to the menu item. When the menu item is clicked, the menu item calls the onMenuItemClick()
method of the OnMenuClickListener interface.
In the second step, register the menu item with listener interface.
a) Create menu using xml file.
(refer [Link] defined above)
b) Create Activity class ([Link])

package [Link];

import [Link];
import [Link];
import [Link].*;
import [Link];
import [Link];

public class MainActivity extends Activity implements OnMenuItemClickListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
[Link]([Link], menu);
MenuItem item1=[Link](0);
MenuItem item2=[Link](1);
MenuItem item3=[Link](2);
[Link](this);
[Link](this);
[Link](this);
return true;
}
132

public boolean onMenuItemClick(MenuItem item) {

TextView tv1=(TextView)[Link]([Link].tv1);
switch([Link]()) {
case [Link].m1:
[Link](""); //clears the TextView
break;
case [Link].m2:
[Link]([Link]);
break;
case [Link].m3:
[Link]("welcome"); // set a new text to the TextView
}
return true;
}
}
The onMenuItemClick() method is called when the menu item has been invoked. This code executes
as soon as the menu item is clicked, even before the onOptionsItemSelected() method is called. If
onMenuItemClick() returns true, no other callbacks are executed—including the
onOptionsItemSelected() callback method. This means that the listener code takes precedence over the
onOptionsItemSelected() method.
Responding to XML-Based Menu Items
Android not only generates a resource ID for the XML file but also generates the necessary menu item
IDs to help you distinguish between the menu items. This is an advantage in terms of responding to the
menu items because you don‘t have to explicitly create and manage their menu item IDs.
The resource type to identify the ID of a menu item ([Link].menu_item_id) is different from the resource
type to identify the menu itself ([Link].some_menu_file_id).
Responding to Menu Items from an XML Menu Resource File
private void onOptionsItemSelected (MenuItem item){
if ([Link]() == [Link].menu_clear){
//do something
}
else if ([Link]() == [Link].menu_new){
//do something
}
......etc
}
133

Working with Other Menu Types


Android also supports icon menus, submenus, context menus, etc.
Working with Icon Menus
You can use icons to represent menu items instead of and in addition to text. Note a few limitations
when it comes to using icon menus. Icon menu items do not support menu item check marks. If the
text in an icon menu item is too long, it‘s truncated after a certain number of characters, depending on
the size of the display.
To set an icon to a menu item use the setIcon() method on the MenuItem class to set the image. You
need to use the image‘s resource ID, so you must generate it first by placing the image or icon in the
/res/drawable directory. For example, if the icon‘s file name is balloons, then the resource ID is
[Link].
Attaching an Icon to a Menu Item
MenuItem item = [Link](―Settings‖);
[Link]([Link]);
The icon shows as long as the menu item is displayed on the main application screen.
Working with Submenus
A Menu object can have multiple SubMenu objects. Each SubMenu object is added to the Menu object
through a call to the [Link]() method. You add menu items to a submenu the same way
that you add menu items to a menu. This is because SubMenu is also derived from a Menu object.
However, you cannot add additional submenus to a submenu.

Adding Submenus
In activity class override the following method
public boolean onCreateOptionsMenu(Menu menu)
{
SubMenu sm = [Link](―languages‖);
[Link](0,1,1,‖java‖);
[Link](0,2,2,‖c‖);
[Link](0,3,3,‖c#‖);
[Link](sm);
return true;
}
134

Working with Context Menus

In Windows applications, for example, you can access a context menu by right-clicking a UI element.
Android supports the same idea of context menus through an action called a long click. A long click is
a mouse click held down slightly longer than usual on any Android view. On handheld devices such as
cell phones, mouse clicks are implemented in a number of ways, depending on the navigation
mechanism. Or if the device has a touch pad, a tap or a press is equivalent to a mouse click. Or you
might have a set of arrow buttons for movement and a selection button in the middle; clicking that
button is equivalent to clicking the mouse.
A context menu is represented as a ContextMenu class in the Android menu architecture. Just like a
Menu, a ContextMenu can contain a number of menu items. You use the same set of Menu methods to
add menu items to the context menu.
The difference between a Menu and a ContextMenu is an activity owns a regular options menu,
whereas a view owns a context menu. So an activity can have only one options menu but many
context menus. Because an activity can contain multiple views, and each view can have its own
context menu, an activity can have as many context menus as there are views.
Although a context menu is owned by a view, the method to populate context menus resides in the
Activity class. This method is called onCreateContextMenu(), and its role resembles that of the
onCreateOptionsMenu() method. This callback method also carries with it (as an argument to the
method) the view for which the context menu items are to be populated.
The onCreateOptionsMenu() method is automatically called for every activity, this is not the case with
onCreateContextMenu(). If you want a particular view to own a context menu, you must register that
view with its activity through the registerForContextMenu() method.
135

Context menus do not support shortcuts, icons, or submenus. The steps to implement a context menu:
1. Register a view for a context menu in an activity‘s onCreate() method.
2. Populate the context menu using onCreateContextMenu(). You must complete step 1 before this
callback method is invoked by Android.
3. Respond to context menu clicks.

Registering a View for a Context Menu


The first step in implementing a context menu is to register a view for the context menu in an
activity‘s onCreate() method. You first find the TextView and then call registerForContextMenu() on
the activity using the TextView as an argument. This sets up the TextView for context menus.
Syntax: void registerForContextMenu (View v)
Populating a Context Menu
Once a view like the TextView in this example is registered for context menus, Android calls the
onCreateContextMenu() method with this view as the argument. This is where you can populate the
context menu items for that context menu. The onCreateContextMenu() callback method provides
three arguments to work with.

The first argument is a ContextMenu object, the second is the view (such as the TextView) that
generated the callback, and the third is the ContextMenuInfo class.
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
//adding menu dynamically
[Link]("Sample Context Menu");
[Link]("item1");
[Link]("item2");
}
Responding to Context Menu Items
The third step in the implementation of a context menu is responding to context menu clicks. The
mechanism of responding to context menus is similar to the mechanism of responding to options
menus. Android provides a callback method similar to onOptionsItemSelected() called
onContextItemSelected(). This method, is also available on the Activity class.
public boolean onContextItemSelected(MenuItem item) {
return true;
}
136

Sample Application
[Link]
<menu xmlns:android="[Link] >
<group android:id="@+id/mg1">
<item android:id="@+id/m1"
android:orderInCategory="1"
android:title="Clear"/>
<item android:id="@+id/m2"
android:orderInCategory="2"
android:title="Format"/>
<item android:id="@+id/m3"
android:orderInCategory="3"
android:title="New"/>
</group>
</menu>

[Link]
package [Link];

import [Link];
import [Link];
import [Link].*;
import [Link];

public class MainActivity extends Activity {


TextView tv1;

protected void onCreate(Bundle savedInstanceState) {


[Link](savedInstanceState);
setContentView([Link].activity_main);
tv1=(TextView)[Link]([Link].tv1);
[Link](tv1);
}
public void onCreateContextMenu(ContextMenu menu, View v,
[Link] menuInfo) {
MenuInflater inflater = getMenuInflater();
[Link]([Link], menu);
}

public boolean onContextItemSelected(MenuItem item) {


switch([Link]()) {
case [Link].m1:
[Link](""); //clears the TextView
break;
case [Link].m2:
[Link]([Link]);
break;
case [Link].m3:
[Link]("welcome"); // set a new text to the TextView
}
return true;
137

}
}

Dynamic Menus
If you want to create dynamic menus, use the onPrepareOptionsMenu() method that Android provides
on an activity class. This method is called every time a menu is invoked. You should use
onPrepareOptionsMenu() if you want to disable some menu items or menu groups based on what you
are displaying. You can call this method any time something changes in your application state that
would require a change to the menu.
Pop-up Menus
A pop-up menu can be invoked against any view in response to a UI event. An example of a UI event
is a button click or a click on an image view. Popup menu can be created using xml as normal menu.
Creating a pop-up menu
a) Refer the [Link] file to define menu
b) [Link]

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity implements OnClickListener{


Button btn;
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);

//to show the menu on button click


btn=(Button)[Link]([Link].btn1);
[Link](this);
}
public void onClick(View v){
PopupMenu pp=new PopupMenu(this,btn);
[Link]([Link]);
[Link]();
}
}

As you can see, a pop-up menu behaves much like an options menu. The key differences are as
follows:
138

A pop-up menu is used on demand, whereas an options menu is always available.


A pop-up menu is anchored to a view, whereas an options menu belong to the entire activity.
A pop-up menu uses its own menu item callback, whereas the options menu uses the
onOptionsItemSelected() callback on the activity.

FRAGMENT

A fragment is an independent Android component which can be used by an activity. A fragment


encapsulates functionality so that it is easier to reuse within activities and layouts. A fragment runs in the
context of an activity, but has its own life cycle and typically its own user interface. Fragments can only
exist within the context of an activity; you can‘t use a fragment without an activity. Fragments can
coexist with other elements of an activity, which means you do not need to convert the entire user
interface of your activity to use fragments. You can create an activity‘s layout as before and only use a
fragment for one piece of the user interface.

It is also possible to define fragments without a user interface, i.e., headless fragments.

An application might want to let the user view the list of emails in their inbox and at the same time
show the currently selected e-mail text in another window. Or an application might want to show a list
of contacts and at the same time show the currently selected contact in a detail view.

Fragment allows to group view objects together and consolidate the logic for them, so that chunks of
an application could be reused across screen sizes and devices. It minimizes the work a developer has
to do to maintain their application. And that is why we have fragments.

Advantages of using fragments

Fragments simplify the reuse of components in different layouts and their logic. You can easily build
single-pane layouts for handsets (phones) and multi-pane layouts for tablets. You can also use fragments
also to support different layout for landscape and portrait orientation on a smartphone.

How to support different screen sizes with fragments

As it is possible to dynamically add and remove fragments from an activity, the usage of fragments
allows to design very flexible user interfaces. The typical example is a list of items in an activity. On a
tablet you see the details immediately on the same screen on the right hand side if you click on item. On
a smartphone you jump to a new detail screen.
139

It is possible to define in the layout file of an activity that it contains fragments (static definition). You
can also modify the fragments of an activity at runtime (dynamic definition).

In landscape mode, two fragments may sit nicely side by side. In portrait mode, we might be able to
put one fragment above the other. But if we‘re trying to run the same application on a device with a
smaller screen, we might need to show either fragment 1 or fragment 2 but not both at the same time.
When using fragments, our layouts become simple; they‘re dealing with the fragments themselves, not
the internal structure of each fragment. Each fragment will have its own layout that can be reused
across many configurations.

Now imagine that a user is in your activity, and they‘ve been doing some work. And imagine that the
user interface has changed within the same activity, and the user wants to go back a step, or two, or
three. In an old-style activity, pressing the Back button will take the user out of the activity entirely.
With fragments, the Back button can step backward through a stack of fragments while staying inside
the current activity.

The Structure of a Fragment

A fragment can have a view hierarchy to engage with a user. This view hierarchy is like any other
view hierarchy in that it can be created (inflated) from an XML layout specification or created in code.

Besides the view hierarchy, a fragment has a bundle that serves as its initialization arguments. Similar
to an activity, a fragment can be saved and later restored automatically by the system. When the
system restores a fragment, it calls the default constructor (with no arguments) and then restores this
140

bundle of arguments to the newly created fragment. Subsequent callbacks on the fragment have access
to these arguments and can use them to get the fragment back to its previous state. For this reason, it is
imperative that you ensure that there‘s a default constructor for your fragment class.

An activity can have multiple fragments in play at one time; and if a fragment has been switched out
with another fragment, the fragment-switching transaction can be saved on a back stack. The back
stack is managed by the fragment manager tied to the activity. The back stack is how the Back button
behavior is managed.

What you need to know here is that a fragment knows which activity it is tied to, and from there it can
get to its fragment manager. A fragment can also get to the activity‘s resources through its activity.
Because a fragment can be managed, it has some identifying information about itself, including a tag
and an ID. These identifiers can be used to find this fragment later, which helps with reuse.

Creating a Fragment

To create a Fragment, a class must inherit from [Link] and then override the
onCreateView() method. The onCreateView() will be called by the hosting Activity when it is time to
put the Fragment on the screen. This method will return a View. A typical onCreateView will create
this View by inflating a layout file and then attaching it to a parent container. The container‘s
characteristics are important as Android will apply the layout parameters of the parent to the UI of the
Fragment. Fragment sub-classes must have a public default no argument constructor.

There are two ways that a Fragment may be hosted inside an Activity:

 Fragments can be used statically within .xml layout files by using the <Fragment> tag.
 Fragments can also be instantiated dynamically by using the FragmentManager class‘s API.

Static Fragment Creation in Android

Adding a Fragment inside the layout requires using the <fragment> tag and then identifying the
Fragment by providing either the class attribute or the android:name attribute. When the Activity is
being created, Android will instantiate each Fragment specified in the layout file and insert the view
that is created from OnCreateView in place of the Fragment element. Fragments that are declaratively
added to an Activity are static and will remain on the Activity until it is destroyed; it is not possible to
dynamically replace or remove such a Fragment during the lifetime of the Activity to which it is
attached. Each Fragment must be assigned a unique identifier:
141

android:id – As with other UI elements in a layout file, this is a unique ID.


android:tag – This attribute is a unique string.

If neither of the previous two methods is used, then the Fragment will assume the ID of the container
view.

a) Layout file for Fragment1 (/res/layout/ [Link] )

<RelativeLayout xmlns:android="[Link]
xmlns:tools="[Link]
android:background="#7B68EE"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="30dp"
android:text="Fragment 1" />
</RelativeLayout>

b) Java class for Fragment1 ([Link] )

package package [Link];


import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return [Link]([Link].fragment1, container, false);
}}

c) Layout file for Fragment2 (/res/layout/ [Link] )

<RelativeLayout xmlns:android="[Link]
xmlns:tools="[Link]
142

android:background="#00FF00"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="30dp"
android:text="Fragment 2" />
</RelativeLayout>

d) Java class for Fragment2 ([Link] )


package package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class Fragment2 extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return [Link]([Link].fragment2, container, false);
}}

e) Layout file for the hosting activity (/res/layout/activity_main.xml )

<LinearLayout xmlns:android="[Link]
xmlns:tools="[Link]
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:name="[Link].Fragment1 "
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment
android:name=" [Link].Fragment2 "
android:id="@+id/fragment2"
143

android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>

f) [Link]

package [Link];
import [Link];
import [Link];

public class MainActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
}}

Fragment Transactions and the Fragment Back Stack

To manage fragments we need a FragmentManager that help us to handle Android


fragment trasaction between fragments. With Android fragment transaction we mean a sequence of
steps to add, replace or remove fragments. FragmentManager class and FragmentTransaction class
helps to create fragments dynamically.

Creating fragments dynamically


a) Create class for Fragment1 by extending [Link]
b) Create class for Fragment2 by extending [Link]
(Refer [Link] and [Link] in the above example)
c) Create a layout file for the hosting activity

/res/layout/activity_main.xml
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout android:id="@+id/frag1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</FrameLayout>
<FrameLayout android:id="@+id/frag2"
android:layout_width="wrap_content"
144

android:layout_height="wrap_content">
</FrameLayout>
</LinearLayout>
Here framelayout act as the place holder for fragments.

[Link]
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
Fragment1 f1=new Fragment1();
Fragment1 f2=new Fragment1();
FragmentManager fm=getFragmentManager();
FragmentTransaction ft=[Link]();
[Link]([Link].frag1, f1);
[Link]([Link].frag2,f2);
[Link](); }}

A key concept to understand is that a fragment must live inside a view container, also known as a view
group. The ViewGroup class includes such things as layouts. FrameLayout is a good choice as the
container for fragments in the activity_main.xml layout file of your activity. A FrameLayout is simple,
and all you need is a simple container for your fragment. The FrameLayout is where your fragment is
going to go. A fragment defined using <fragment> tag in the activity’s layout file could not be
replaced with another one dynamically. The FragmentTransaction class replaces whatever is in the
frame layout with the specified fragment.

A Fragment’s Lifecycle

The onInflate() Callback

If your fragment is defined by a <fragment> tag in a layout that is being inflated (typically when an
activity has called setContentView() for its main layout), your fragment‘s onInflate() callback is
called.
145

The Fragment is not associated with its Activity yet, but the Activity, Bundle, and AttributeSet from
the view hierarchy are passed in as parameters. This method is best used for parsing the AttributeSet
with the attributes from the <fragment> tag, and for saving the attributes that might be used later by
the Fragment. The saved bundle is the one with the saved state values in it. The expectation of
onInflate() is that you‘ll read attribute values and save them for later use.

void onInflate (Activity activity, AttributeSet attrs, Bundle savedInstanceState)

The onAttach() Callback

The onAttach() callback is invoked after your fragment is associated with its activity. The activity
reference is passed to you if you want to use it. You can also use the activity as a context to do other
operations. The Fragment class has a getActivity() method that will always return the attached activity
for your fragment. The initialization arguments bundle is available to you from the fragment‘s
getArguments() method.

void onAttach (Context context)


146

The onCreate() Callback

This method is similar to the activity‘s onCreate(). The fragment may be associated to its activity by
now, but you haven‘t yet been notified that the activity‘s onCreate() has finished. This callback gets
the saved state bundle passed in.

void onCreate (Bundle savedInstanceState)

The onCreateView() Callback

The next callback is onCreateView(). The expectation here is that you will return a view hierarchy for
this fragment. The arguments passed in to this callback include a LayoutInflater (which you can use to
inflate a layout for this fragment), a ViewGroup parent (layout of activity), and the saved bundle if one
exists. It is very important to note that you should not attach the view hierarchy to the ViewGroup
parent passed in. That association will happen automatically later. You will very likely get exceptions
if you attach the fragment‘s view hierarchy to the parent in this callback.

The parent is provided so you can use it with the inflate() method of the LayoutInflater. If the parent
container value is null, that means this particular fragment won‘t be viewed because there‘s no view
hierarchy for it to attach to. In this case, you can simply return null from here. Remember that there
may be fragments floating around in your application that aren‘t being displayed.
Creating a Fragment View Hierarchy in onCreateView()
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
If(container == null)
return null;
View v = [Link]([Link], container, false);
return v; }

Here you see how you can access a layout XML file that is just for this fragment and inflate it to a
view that you return to the caller. There are several advantages to this approach. You could always
construct the view hierarchy in code, but by inflating a layout XML file, you‘re taking advantage of
the system‘s resource-finding logic.

Depending on which configuration the device is in, or for that matter which device you‘re on, the
appropriate layout XML file will be chosen. You can then access a particular view within the layout—
in this case, the text1, TextView field—to do what you want with.
147

The onActivityCreated() Callback

You‘re now getting close to the point where the user can interact with your fragment. The next
callback is onActivityCreated(). This is called after the activity has completed its onCreate() callback.
This is where you can do final tweaks to the user interface before the user sees it. This could be
especially important if this activity and its fragments are being re-created from a saved state.

The onStart() Callback

The next callback in your fragment lifecycle is onStart(). Now your fragment is visible to the user. But
you haven‘t started interacting with the user just yet. This callback is tied to the activity‘s onStart().
You can put your logic into the fragment‘s onStart(), because that is also where the user interface
components are.

The onResume() Callback

The last callback before the user can interact with your fragment is onResume(). This callback is tied
to the activity‘s onResume(). When this callback returns, the user is free to interact with this fragment.
For example, if you have a camera preview in your fragment, you would probably enable it in the
fragment‘s onResume().

The onPause() Callback

The first undo callback on a fragment is onPause(). This callback is tied to the activity‘s onPause();
just as with an activity, if you have a media player in your fragment or some other shared object, you
could pause it, stop it, or give it back via your onPause() method.

The onSaveInstanceState() Callback

Similar to activities, fragments have an opportunity to save state for later reconstruction. This callback
passes in a Bundle object to be used as the container for whatever state information you want to hang
onto. This is the saved-state bundle passed to the callbacks covered earlier. To prevent memory
problems, be careful about what you save into this bundle. Only save what you need. If you need to
keep a reference to another fragment, save its tag instead of trying to save the other fragment.

Although you may see this method usually called right after onPause(), the activity to which this
fragment belongs calls it when it feels that the fragment‘s state should be saved. This can occur any
time before onDestroy().
148

The onStop() Callback

The next undo callback is onStop(). This one is tied to the activity‘s onStop() and serves a purpose
similar to an activity‘s onStop(). A fragment that has been stopped could go straight back to the
onStart() callback, which then leads to onResume().

The onDestroyView() Callback

If your fragment is on its way to being killed off or saved, the next callback in the undo direction is
onDestroyView(). This will be called after the view hierarchy you created on your onCreateView()
callback earlier has been detached from your fragment.

The onDestroy() Callback

Next up is onDestroy(). This is called when the fragment is no longer in use. Note that it is still
attached to the activity and is still findable, but it can‘t do much.

The onDetach() Callback

The final callback in a fragment‘s lifecycle is onDetach(). Once this is invoked, the fragment is not
tied to its activity, it does not have a view hierarchy anymore, and all its resources should have been
released.

Using setRetainInstance()

One of the cool features of a fragment is that you can specify that you don‘t want the fragment
completely destroyed if the activity is being re-created and therefore your fragments will be coming
back also. Therefore, fragment comes with a method called setRetainInstance(), which takes a boolean
parameter to tell it ―Yes; I want you to hang around when my activity restarts‖ or ―No; go away, and
I‘ll create a new fragment from scratch.‖ The best place to call setRetainInstance() is in the onCreate()
callback of a fragment.

If the parameter is true, that means you want to keep your fragment object in memory and not start
over from scratch. However, if your activity is going away and being recreated, you‘ll have to detach
your fragment from this activity and attach it to the new one. The bottom line is that if the retain
instance value is true, you won‘t actually destroy your fragment instance, and therefore you won‘t
need to create a new one on the other side. All other callbacks will be invoked, however. The dotted
lines on the diagram mean you would skip the onDestroy() callback on the way out, and you‘d skip the
onCreate() callback when your fragment is being re-attached to your new activity.
149

Because an activity is re-created most likely for configuration changes, your fragment callbacks
should probably assume that the configuration has changed, and therefore should take appropriate
action. This would include inflating the layout to create a new view hierarchy in onCreateView().

Fragment Transactions
You can perform many other operations on dynamic fragments other than adding them to an activity,
such as removing them and changing their visibility.
 Each set of changes that you commit to the activity is called a transaction.
 You perform fragment operations using the methods in the FragmentTransaction class.
Methods include:
add() Add a fragment to the activity.
remove() Remove a fragment from the activity. This operation destroys the fragment instance
unless the transaction is added to the transaction back stack, described later.
replace() Remove one fragment from the UI and replace it with another.
hide() Hide a fragment in the UI (set its visibility to hidden without destroying the view
hierarchy).
show() Show a previously hidden fragment.

Performing Fragment Transactions

To perform a fragment transaction:

1. Obtain an instance of FragmentTransaction by calling [Link]().


2. Perform any number of fragment operations using the transaction instance.

Most of the FragmentTransaction operations return a reference to the same FragmentTransaction


instance, allowing method chaining.

3. Call commit() to apply the transaction to the activity.

You can commit a transaction using commit() only prior to the activity saving its state.

The order in which you add changes to a FragmentTransaction doesn‘t matter, except:
 You must call commit() last.
 If you‘re adding multiple fragments to the same container, then the order in which you add
them determines the order they appear in the view hierarchy.
150

Managing the Fragment Back Stack

Similar to the way the system automatically maintains a task back stack for activities, you have the
option of saving fragment transactions onto a back stack managed by the activity.
 If you add fragment transactions to the back stack, then the user can navigate backward
through the fragment changes by pressing the device‘s Back button.
 Once all fragment transactions have been removed from the back stack, pressing the Back
button again destroys the activity.
To add a transaction to the back stack, invoke
[Link] (String name)
before committing the transaction.
 The String argument is an optional name to identify the back stack state, or null. The
FragmentManager class has a popBackStack() method, which can return to a previous back
stack state given its name.
 If you add multiple changes to the transaction and call addToBackStack(), then all changes
applied before you call commit() are added to the back stack as a single transaction and the
Back button will reverse them all together.
If you call addToBackStack() when removing or replacing a fragment:
 The system invokes onPause(), onStop(), and onDestroyView() on the fragment when it is
placed on the back stack
 If the user navigates back, the system invokes onCreateView(), onActivityCreated(), onStart(),
and onResume() on the fragment.

The FragmentManager

The FragmentManager is a component that takes care of the fragments belonging to an activity. You
use the getFragmentManager() method on either an activity or an attached fragment to retrieve a
fragment manager. A fragment manager can also be used to get a fragment transaction. The
FragmentManager class has methods for finding a fragment contained within an activity:
Fragment findFragmentById(int id)
Finds a fragment with the specified ID.
Fragment findFragmentByTag(String tag)
Finds a fragment with the specified tag.
Both of these methods return a reference to the fragment, or null if no matching fragment is found.
151

Finally, the fragment manager has methods for some debugging features, such as turning on
debugging messages to LogCat using enableDebugLogging() or dumping the current state of the
fragment manager to a stream using dump().

Saving Fragment State

Another interesting class was introduced in Android 3.2: [Link]. Using the
saveFragmentInstanceState() method of FragmentManager, you can pass this method a fragment, and
it returns an object representing the state of that fragment. You can then use that object when
initializing a fragment, using Fragment‘s setInitialSavedState() method.

Persistence of Fragments

When you play with this sample application, make sure you rotate the device (pressing Ctrl+F11
rotates the device in the emulator). You will see that the device rotates, and the fragments rotate right
along with it. If you watch the LogCat messages, you will see a lot of them for this application. In
particular, during a device rotation, pay careful attention to the messages about fragments; not only
does the activity get destroyed and recreated, but the fragments do also.

So far, you only wrote a tiny bit of code on the titles fragment to remember the current position in the
titles list across restarts. You didn‘t do anything in the details fragment code to handle
reconfigurations, and that‘s because you didn‘t need to. Android will take care of hanging onto the
fragments that are in the fragment manager, saving them away, then restoring them when the activity
is being re-created. You should realize that the fragments you get back after the reconfiguration is
complete are very likely not the same fragments in memory that you had before. These fragments have
been reconstructed for you. Android saved the arguments bundle and the knowledge of which type of
fragment it was, and it stored the saved-state bundles for each fragment that contain saved-state
information about the fragment to use to restore it on the other side.

The LogCat messages show you the fragments going through their lifecycles in sync with the activity.
You will see that your details fragment gets re-created, but your newInstance() method does not get
called again. Instead, Android uses the default constructor, attaches the arguments bundle to it, and
then starts calling the callbacks on the fragment. This is why it is so important not to do anything
fancy in the newInstance() method: when the fragment gets re-created, it won‘t do it through
newInstance().

You should also appreciate by now that you‘ve been able to reuse your fragments in a few different
places. The titles fragment was used in two different layouts, but if you look at the titles fragment
152

code, it doesn‘t worry about the attributes of each layout. You could make the layouts rather different
from each other, and the titles fragment code would look the same. The same can be said of the details
fragment. It was used in your main landscape layout and within the details activity all by itself. Again,
the layout for the details fragment could have been very different between the two, and the code of the
details fragment would be the same. The code of the details activity was very simple, also.

Communications with Fragments

Because the fragment manager knows about all fragments attached to the current activity, the activity
or any fragment in that activity can ask for any other fragment using the getter methods described
earlier. Once the fragment reference has been obtained, the activity or fragment could cast the
reference appropriately and then call methods directly on that activity or fragment. This would cause
your fragments to have more knowledge about the other fragments than might normally be desired, but
don‘t forget that you‘re running this application on a mobile device, so cutting corners can sometimes
be justified. A code snippet is provided in Listing 8–12 to show how one fragment might communicate
directly with another fragment.

Direct Fragment-to-Fragment Communication

FragmentOther fragOther = (FragmentOther) getFragmentManager().findFragmentByTag (―other‖);

[Link]( arg1, arg2 );

Here the current fragment has direct knowledge of the class of the other fragment and also which
methods exist on that class. This may be okay because these fragments are part of one application, and
it can be easier to simply accept the fact that some fragments will know about other fragments.

Using startActivity() and setTargetFragment()

A feature of fragments that is very much like activities is the ability of a fragment to start an activity.
Fragment has a startActivity() method and startActivityForResult() method. These work just like the
ones for activities; when a result is passed back, it will cause the onActivityResult() callback to fire on
the fragment that started the activity. There‘s another communication mechanism you should know
about. When one fragment wants to start another fragment, there is a feature that lets the calling
fragment set its identity with the called fragment.

Fragment-to-Target-Fragment Setup
mCalledFragment = new CalledFragment();
153

[Link](this, 0);
[Link]().add(mCalledFragment, "work").commit();

With these few lines, you‘ve created a new CalledFragment object, set the target fragment on the
called fragment to the current fragment, and added the called fragment to the fragment manager and
activity using a fragment transaction. When the called fragment starts to run, it will be able to call
getTargetFragment(), which will return a reference to the calling fragment. With this reference, the
called fragment could invoke methods on the calling fragment or even access view components
directly.

Target Fragment-to-Fragment Communication


TextView tv = (TextView) getTargetFragment().getView().findViewById([Link].text1);
[Link](―Set from the called fragment‖);

Working with Dialogs


The Android SDK offers extensive support for dialogs. A dialog is a smaller window that pops up in
front of the current window to show an urgent message, to prompt the user for a piece of input, or to
show some sort of status like the progress of a download. The user is generally expected to interact
with the dialog and then return to the window underneath to continue with the application.
Technically, Android allows a dialog fragment to also be embedded within an activity‘s layout.

Dialogs that are explicitly supported in Android include the alert, prompt, pick-list, single-choice,
multiple-choice, progress, time-picker, and date-picker dialogs. Android also supports custom dialogs
for other needs.

Using Dialogs in Android

Dialogs in Android are asynchronous, which provides flexibility. However, if you are accustomed to a
programming framework where dialogs are primarily synchronous (such as Microsoft Windows, or
JavaScript dialogs in web pages) With a synchronous dialog, the line of code after the dialog is shown
does not run until the dialog has been dismissed. This means the next line of code could interrogate
which button was pressed, or what text was typed into the dialog.

In Android however, dialogs are asynchronous. As soon as the dialog has been shown, the next line of
code runs, even though the user hasn‘t touched the dialog yet. Your application has deal with this fact
154

by implementing callbacks from the dialog, to allow the application to be notified of user interaction
with the dialog.
This also means your application has the ability to dismiss the dialog from code, which is powerful. If
the dialog is displaying a busy message because your application is doing something, as soon as your
application has completed that task, it can dismiss the dialog from code.

Understanding Dialog Fragments


In this section, you learn how to use dialog fragments to present a simple alert dialog and a custom
dialog that is used to collect prompt text.
DialogFragment Basics
Dialog-related functionality uses a class called DialogFragment. A DialogFragment is derived from
the class Fragment and behaves much like a fragment. You will then use the DialogFragment as the
base class for your dialogs. You can then show this dialog fragment MyDialogFragment as a dialog
using a fragment transaction.

1. Creating dialog fragment

First step towards creating dialog fragment is to create a new class and extend it from DialogFragment.

public class MyDialogFragment extends DialogFragment {

As a DialogFragment is much like any other fragment, the same lifecycle rules are applied. Now we
have to override onCreateView or onCreateDialog method to provide the view hierarchy and construct
the dialog fragment.

package [Link];

import [Link].*;
import [Link];
import [Link].*;
import [Link];
import [Link];

public class MyDialogFragment extends DialogFragment implements OnClickListener{

public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle


savedInstanceState) {
View rootView = [Link]([Link], container, false);
getDialog().setTitle("Simple Dialog");
Button btn=(Button)[Link]([Link]);
[Link](this);
155

return rootView;
}
public void onClick (View v) {
dismiss();
}
}

In the above code, the onCreateView() method is expected to return the instance of view that represent
the view hierarchy for your dialog. The instance of layout inflater can be used to inflate the layout for
the fragment. ViewGroup represents the parent view where the fragment to be attached, and the
Bundle param is the saved bundle data if available to restore the fragment to previous state.

2. Defining dialog fragment layout

The [Link] is a layout for the dialog. Let us create a simple layout.

/res/layout/[Link]

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


<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="10dp"
android:orientation="vertical">

<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to dialog fragments "
android:textSize="20dp" />

<Button
android:id="@+id/close"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OK" />
</LinearLayout>

3. Displaying dialog fragment

The steps to show a dialog fragment are as follows:


 Create a dialog fragment.
 Get a fragment transaction.
 Show the dialog using the fragment transaction from step 2.
156

[Link]
package [Link];

import [Link];
import [Link].*;

public class MainActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
FragmentManager fm = getFragmentManager();
MyDialogFragment dialog = new MyDialogFragment ();
[Link](fm, "Sample Fragment");
}}

Overriding onCreateView()
When you inherit from a dialog fragment, you need to override one of two methods to provide the
view hierarchy for your dialog. The first option is to override onCreateView() and return a view. The
second option is to override onCreateDialog() and return a dialog
Overriding onCreateDialog()
As an alternate to supplying a view in onCreateView(), you can override onCreateDialog() and supply
a dialog instance.

Dialog onCreateDialog (Bundle savedInstanceState)

Override to build your own custom Dialog container. This is typically used to show an AlertDialog
instead of a generic Dialog; when doing so, onCreateView() does not need to be implemented since
the AlertDialog takes care of its own content. This method will be called after onCreate(Bundle) and
before onCreateView(). The default implementation simply instantiates and returns a Dialog class.

[Link]

package [Link];

import [Link].*;
import [Link];

public class MyDialogFragment extends DialogFragment {


public Dialog onCreateDialog(Bundle state){
[Link] b = new [Link](getActivity());
[Link]("My Dialog Title");
[Link]("welcome");
return [Link]();
}
157

[Link]
package [Link];

import [Link];
import [Link];
import [Link].*;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
FragmentManager fm = getFragmentManager();
MyDialogFragment dialog = new MyDialogFragment();
[Link](fm, "Sample Fragment");
}
}
Displaying a Dialog Fragment
The show() method uses the fragment transaction to add this dialog to the activity and then commits
the fragment transaction. However, the show() method does not add the transaction to the back stack.
If you want to do this, you need to add this transaction to the back stack first and then pass it to the
show() method. The show() method of a dialog fragment has the following signatures:
public int show(FragmentTransaction transaction, String tag)
public int show(FragmentManager manager, String tag)
The first show() method displays the dialog by adding this fragment to the passed-in transaction with
the specified tag. This method then returns the identifier of the committed transaction.
The second show() method automates getting a transaction from the transaction manager. This is a
shortcut method. However, when you use this second method, you don‘t have an option to add the
transaction to the back stack. If you want that control, you need to use the first method. The second
method could be used if you wanted to simply display the dialog, and you had no other reason to work
with a fragment transaction at that time.
Dismissing a Dialog Fragment
To close a dialog call the dismiss() method on the dialog fragment in response to a button or some
action on the dialog view. The dialog fragment‘s dismiss() method removes the fragment from the
fragment manager and then commits that transaction. If there is a back stack for this dialog fragment,
then the dismiss() pops the current dialog out of the transaction stack and presents the previous
fragment transaction state. Whether there is a back stack or not, calling dismiss() results in calling the
standard dialog fragment destroy callbacks, including onDismiss().
158

ACTIONBAR
ActionBar was introduced in the Android 3.0 SDK for tablets and is now available for phones as well
in 4.0. It allows you to customize the title bar of an activity. Android ActionBar is modeled similar to
the menu/title bar of a web browser. With the 4.0 SDK, the phone and tablet aspects of the SDK are
merged to provide a uniform API.
A key goal of the action bar design is to make the frequently used actions easily available to the user
without searching through option menus or context [Link] action bar is owned by an activity and
follows its lifecycle. An action bar can take one of three forms: tabbed action bar, list action bar, or
standard action bar.
Anatomy of an ActionBar

Home Icon or App icon: The icon at upper left on the action bar is sometimes called the Home icon or
App icon. This is similar to a web site navigation context, where clicking the Home icon takes you to a
starting point. When youtransfer the user to the home activity, don‘t start a new home activity; instead,
transfer to it by using an intent flag that clears the stack of allactivities on top of the home activity.
View Control – A dedicated space to display app title (Title area). Also provides option to switch
between views by adding spinner or tabbed navigation (Tabs area).
The Tabs area is where the action bar paints the list of tabs specified. The content of this area is
variable. If the action bar navigation mode is tabs, then tabs are shown here. If the mode is list
navigation mode, then a navigable list of drop-down items is shown. Instandard mode, this area is
ignored and left empty.
159

Action Buttons orAction Icon area: Following the Tabs area, the Action Icon area shows some of the
option menu items as icons. Some important actions of the app can be added here.
Action Overflow or Menu Icon area: All unimportant action will be shown as a [Link] is a single
standard menu icon. When you click this menu icon, you see the expanded menu. This expanded menu
looks different or shows up in a different location depending on the size of the Android device.
Every application unless otherwise specified has an ActionBar by default. The ActionBar by default
now has just the title for the current activity.

1) Changing the ActionBar Title and Icon

The ActionBar title displayed at the top of the screen is governed by the [Link] file
within the activity nodes.
In the example below, the activity "MainActivity" will have an ActionBar with the string value of the
resource identified by @string/activity_name. If the value of that resource is "SimpleApp," the string
displayed in the ActionBar for this activity will be "SimpleApp". Note that theapplication node can
supply a android:label that acts as the default for activities and components with no other specified
label.
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="[Link]"
android:icon=‖@drawable/myicon‖
android:label="@string/activity_name">
</activity>
</application>

Change the android:label or android:icon to modify the ActionBar title or icon for a given activity or
for the application as a whole. In any Java activity, you can also call getActionBar() to retrieve a
reference to the ActionBar and modify or access any properties of the ActionBar at runtime.
[Link] package defines the class ActionBar.
Syntax:
ActionBar getActionBar ()
To change the title at run time call setTitle() method using ActionBar object.
void setTitle(CharSequence title)
To set the logo or icon void setLogo (int drawable)
or void setIcon (int drawable)
160

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
ActionBar actionBar = getActionBar();
[Link]("SimpleApp"); // set the top title
[Link]([Link]);
}
}
2) View Control
This area provides option to switch between views by adding spinner or tabbed navigation (Tabs area).
Three types of navigation modes can be implemented in Actionbar. Tabbed navigation, list navigation
and standard navigation. The primary difference between these navigation modes are that each
configures the action bar differently.
To set the navigation mode setNavigationMode() is used.
void setNavigationMode (int mode) : The values that can be given to mode is
NAVIGATION_MODE_STANDARD
NAVIGATION_MODE_LIST
NAVIGATION_MODE_TABS
They are defined in ActionBar class and can be referred using ActionBar object.
Tabbed Navigation Action Bar
To implement tabbed navigation use setNavigationMode() with NAVIGATION_MODE_TABS as
argument.
Next create tabs and add it to the action bar. To create tabs use newTab().
[Link] newTab() It create and return a new [Link]. This tab will not be
included in the action bar until it is added using addTab().

void addTab ([Link] tab)

Example:
161

ActionBar bar = getActionBar();

[Link](ActionBar.NAVIGATION_MODE_TABS);

Tab tab1 = [Link]();

[Link]("Tab 1");

[Link](tab1);

Tab listener

What we want is when user touches one of the tab the UI content changes. To achieve it we need two
things:

 Fragment that fills the UI when user changes the tab according to the tab selected
 A listener that gets notification when user interacts with the tabs

We can make our Activity implements the listener so that when user selects a tab we show the relative
fragment. TabListener has the following methods we have to override.
public void onTabUnselected(Tab tab, FragmentTransaction ft)
public void onTabReselected(Tab tab, FragmentTransaction ft)
public void onTabSelected(Tab tab, FragmentTransaction ft)
The most important is onTabSelected that is called when user selects a tab. In this method first we
check if we have our fragment in the fragment list, if so we reuse it and show the fragment. If not, we
create our fragment and add it to our fragment list. We simply replace the UI content with the right
fragment.
Android action bar was introduced to maintain a consistent navigation across the application. It has the
powerful capabilities like adapting to screen configurations (landscape & portrait), prioritizing
important actions, adding widgets to action bar (search, sharing etc.), providing navigation between
screens (drop-down & tabbed navigation) and much more.

package [Link];

import [Link];
import [Link];
import [Link].*;
import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link].*;
162

public class MainActivity extends Activity implements TabListener{

protected void onCreate(Bundle savedInstanceState) {


[Link] (savedInstanceState);
setContentView ([Link].activity_main);
ActionBar actionBar = getActionBar();
[Link]("My New Title");
[Link]([Link]);
[Link](ActionBar.NAVIGATION_MODE_TABS);
Tab tab1 = [Link]();
[Link]("Names");
[Link](this);
[Link](tab1);
Tab tab2 = [Link]();
[Link]("Courses");
[Link](this);
[Link](tab2);
}
public void onTabUnselected(Tab tab, FragmentTransactionft) {
}
public void onTabReselected(Tab tab, FragmentTransactionft) {
}
public void onTabSelected(Tab tab, FragmentTransactionft) {
TextView tv=(TextView) [Link] ([Link].tv1);
[Link]([Link]());
}
}

List Navigation Action Bar

You can use an Action Bar drop-down list, as shown in Figure.


163

To configure your Action Bar to display a drop-down list, call its setNavigationMode() method.
[Link] (ActionBar.NAVIGATION_MODE_LIST);

The drop-down list is implemented much like a Spinner — a view that displays one child at a time and
lets the user pick from among them. Populate the drop-down list by creating a new Adapter that
implements the SpinnerAdapter interface, such as an Array Adapter.
String values[]={―Local‖, ―Myplaces‖, ‖Checkins‖, ―Latitude‖};
ArrayAdapter<String> list = new
ArrayAdapter<String> (this, [Link].simple_list_item_1, values);

To assign the Adapter to your Action Bar, and handle selections, implement OnNavigationListener
and override the method
public boolean onNavigationItemSelected(int itemPosition, long itemId)
When a user selects an item from the drop-down list, the onNavigationItemSelected handler will be
triggered. Use the itemPosition and itemId parameters to determine how your UI should be adapted
based on the new selection.
To respond to actionbar navigation register it with the listener.
[Link](list,this);
this represents the activity class that implements the OnNavigationListener.
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity implements OnNavigationListener{

String values[]={"Local", "Myplaces", "Checkins", "Latitude"};


protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
ActionBar actionBar = getActionBar();
[Link]("My New Title"); [Link]([Link].img06);
ArrayAdapter<String> list = new ArrayAdapter<String> (this,
[Link].simple_list_item_1, values);
[Link](ActionBar.NAVIGATION_MODE_LIST);
[Link](list, this);
}
164

public boolean onNavigationItemSelected(int itemPosition, long itemId) {


TextView tv=(TextView)[Link]([Link].tv1);
[Link](values[itemPosition]);
return true;
}
}

Standard Navigation Action Bar


For a standard action bar, there are no tabs or lists and there are no listeners other than the menu
callbacks. The menu callbacks don‘t need to be specially set up because they are hooked up
automatically by the SDK. As a result, it is quite easy to set up the action bar in the standard
navigation mode.

3) Action Buttons

When you want to add primary actions to the ActionBar, you add the items to the activity context
menu and if properly specified, they will automatically appear at the top right as icons in the
ActionBar. An activity populates the ActionBar from within the onCreateOptionsMenu() method.
Override the method in above mentioned [Link]:

public boolean onCreateOptionsMenu (Menumenu) {


// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate([Link], menu);
return true;
}}
Entries in the action bar are typically called actions. Use this method to inflate a menu resource that
defines all the action items within a res/menu/menu_main.xml file, for example:
\res\menu\[Link]

<menu xmlns:android=‖[Link]
<item android:id="@+id/item1"
android:icon="@drawable/icon1"
android:showAsAction="ifRoom">
</item>
<item android:id="@+id/item2"
android:icon="@drawable/icon2"
android:showAsAction="ifRoom|withText">
</item>
</menu>
The above code results in two action icons being displayed:
The@drawable/icon1 and @drawable/icon2 refers to drawable resources. The icon1 and icon2 images
would have to exist in the drawable folder.
165

Here the important xml attributes should be known are

and roid :i con – Defines the icon of the action item.


and roid :ti tle – Title for the icon.
and roid :show AsActi on – Defines the visibility of the action item. It accepts following values.

ifRoom Displays the icon if there is space available on the screen

never Never places this icon on the action bar

Forces to display the icon always irrespective of space available. This


always way is not suggested.

Displays a text along with the icon. Normally the text value defined by
withText android:title will be displayed

Handling Action Button Clicks

To execute code when the user clicks on action item, use the onOptionsItemSelected() method. Using
the MenuItem passed to this method, you can identify the action by calling getItemId(). This returns
the unique ID provided by the item tag's id attribute so you can perform the appropriate action:

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MenuActivity extends Activity {


protected void onCreate(Bundle savedInstanceState) {
[Link] (savedInstanceState);
setContentView ([Link].activity_main);
ActionBar actionBar = getActionBar();
[Link]("My New Title");
[Link]([Link].img06);
}
public boolean onCreateOptionsMenu (Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate([Link], menu);
return true;
}
166

public boolean onOptionsItemSelected(MenuItem item) {


// Handle presses on the action bar items
TextView tv=(TextView) [Link] ([Link].tv1);
switch ([Link]()) {
case [Link].item1:
[Link]("Icon1 clicked");
return true;
case [Link].item2:
[Link]("Icon2 clicked");
return true;
default:
return [Link](item);
}
}
}

4) Overflow Icon and Overflow menu

The items in a menu can be declared within an XML file, which is then inflated and displayed to the
user on demand. This involves the use of the <menu> element, containing an <item> sub-element for
each menu item.

\res\menu\[Link]

<menu xmlns:android="[Link] >

<item
android:id="@+id/help"
android:orderInCategory="1"
android:showAsAction="never"
android:title="@string/txthelp‖ />
<item
android:id="@+id/settings"
android:orderInCategory="2"
android:showAsAction="never"
android:title="@string/txtsettings"/>
</menu>

The android:showAsAction property, on the other hand, controls the conditions under which the
corresponding item appears as an item within the action bar itself. If set to ifRoom, for example, the
item will appear in the action bar if there is enough room. If set to never the item will not be shown in
the action bar. It is added to overflow menu.
167

Displaying an Overflow Menu

An overflow menu is created by overriding the onCreateOptionsMenu() method of the corresponding


activity and then inflating the menu‘s XML file. For example, the following code creates the menu
contained within a menu XML file named [Link].

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate([Link], menu);
return true;
}

If the hardware button menu is present in the phone the overflow icon will not show in the action bar.
To show it in emulator disable hardware skin option while creating AVD.

Responding to Menu Item Selections

Once a menu has been implemented, the question arises as to how the application receives notification
when the user makes menu item selections. All that an activity needs to do to receive menu selection
notifications is to override the onOptionsItemSelected() method. Passed as an argument to this method
is a reference to the selected menu item. The getItemId() method may then be called on the item to
obtain the ID which may, in turn, be used to identify which item was selected. We can implement it as
in same way in the above example.

Adding search widget to Action Bar

Adding search widget involves these steps.

 Adding the Search Widget to action bar action item.


 Defining the searchable configuration in the xml.
 Creating the activity to handle search query and display the results
 Defining the default searchable activity and SEARCH intent filter in
[Link] file
Defining a Search View Widget as a Menu Item
To define a search view to appear in the action bar of your activity, you need to define a menu item in
one of your menu XML files, as shown below.
Search View Menu Item Definition
<!-- /res/xml/[Link] -->
<menu xmlns:android=‖[Link]
<item android:id="@+id/menu_search"
168

android:title="Search"
android:showAsAction="ifRoom"
android:actionViewClass="[Link]"
/>
</menu>
The key element in above code is the actionViewClass attribute pointing to
[Link].

Create Searchable Configuration


 Searchable Configuration defines how SearchView behaves.
 Need to define it in a xml (res/xml/[Link]). Following is an example searchable
configuration file

<!-- /res/xml/[Link] -->


<searchable xmlns:android="[Link]
android:label="@string/search_label"
android:hint="@string/search_hint" />
The hint attribute will appear on the search view widget as a hint that disappears when you start
typing. The label doesn‘t play a significant role in the action bar. However, when you use the same
search results activity in a search dialog, the dialog has the label defined here.

Add this element into a relevant activity with <meta-data> tag in the Manifest File

Tying an Activity to Its [Link]


<activity
android:name="[Link]"
android:label="@string/app_name" >
<intent-filter>
<action android:name="[Link]" />
<category android:name="[Link]" />
</intent-filter>
<meta-data android:name="[Link]"
android:resource="@xml/searchable"/>
</activity>

Add Menu and Searchable Configuration to activity

Associate searchable configuration with the SearchView in the activity class. You do this in the
onCreateOptions() callback of the search-invoking activity as part of setting up our menu. The
following method can be called from onCreateOptionsMenu() to link the search view widget and the
search results activity.
169

Now the SearchView added to the activity. But still searching functionality not working.

Add searching functionality

Implement [Link] in activity, need to override two new methods now.

public boolean onQueryTextSubmit(String query)


public boolean onQueryTextChange(String newText)

This interface listen to text change events in SearchView. The SearchView must be linked with the
listener using

[Link](this);
this represents the class that implements the OnQueryTextListener interface.

package [Link];

import [Link];
import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class SearchActivity extends Activity implements OnQueryTextListener {

SearchView searchView;

protected void onCreate(Bundle savedInstanceState) {


[Link](savedInstanceState);
setContentView([Link].activity_main);
ActionBar actionBar = getActionBar();
[Link]("My New App");
[Link]([Link].img06);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate([Link], menu);
// returns a SearchManager for handling search.
SearchManager searchManager =(SearchManager)
getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo =
[Link](getComponentName());
170

searchView = (SearchView) [Link]([Link].menu_search).getActionView();


[Link](searchableInfo);
[Link](this);
return true;
}
public boolean onQueryTextSubmit(String query) {
TextView tv=(TextView)[Link]([Link].tv1);
[Link](query);
return true;
}
public boolean onQueryTextChange(String newText) {
return false;
}
}

getSystemService(Context.SEARCH_SERVICE) returns a SearchManager for handling search.

WORKING WITH TOAST


A Toast is like an alert dialog that has a message and displays for a certain amount of time and then
goes away. It does not have any buttons. So it can be said that it is a transient alert message. It‘s called
Toast because it pops up like toast out of a toaster.

The makeText() method can take not only an activity but any context object.

Toast makeText (Context context, int resId, int duration)

context : The context to use. Usually your Application or Activity object.

resId : The resource id of the string resource to use. Can be formatted text.

Duration : How long to display the message. Either LENGTH_SHORT or LENGTH_LONG

Toast makeText (Context context, CharSequence s, int duration)

This method returns a Toast object and it can be used to show the toast.
void show()
Show the view for the specified duration.
Example:

String s = "hai welcome";


Toast t=[Link] (this, s, Toast.LENGTH_LONG);
[Link]();
171

Action Bar and Fragments


The action bar is generally recommended for use with fragments. Because fragments are inside an
activity, and an activity owns the action bar, all fragments share the same activity, so they also share
the same action bar.
UNIT V
PERSISTING DATA

In this chapter, you‘ll be introduced to three of the most versatile data persistence techniques in
Android — preferences, local files, and SQLite databases. Saving and loading data is an essential
requirement for most applications. At a minimum, Activities should save their User Interface (UI)
state each time they move out of the foreground. This ensures that the same UI state is presented when
it‘s next seen, even if the process has been killed and restarted before that happens. It‘s also likely that
you‘ll need to save preferences, to let users customize the application, and persist data entered or
recorded.
Android‘s nondeterministic Activity and Application lifetimes make persisting UI state and
application data between sessions particularly important. Preferences are a simple, light weight
key/value pair mechanism for saving primitive application data.
1. Saving Application Data
The data persistence techniques in Android provide options for balancing speed, efficiency, and
robustness:
Shared Preferences
When storing UI state, user preferences, or application settings, you want a lightweight mechanism to
store a known set of values. Shared Preferences let you save groups of name/value pairs of primitive
data as named preferences.
Saved application UI state
Activities and Fragments include specialized event handlers to record the current UI state when your
application is moved to the background.
Files
Android lets you create and load files on the device‘s internal or external media. Android provides
access to the local file system, both through specialized methods and the normal [Link] classes.
SQLite Databases
When managed, structured data is the best approach; Android offers the SQLite relational database
library. Every application can create its own databases over which it has total control.
By default, access to all files, databases, and preferences is restricted to the application that created
them. Content Providers let you expose a well-defined interface for using and sharing private data.
172

You can control access to Content Providers using the standard permission system. As a result, your
applications can use the Content Providers offered by others, including native providers.
Shared Preferences
1.1 Creating and Saving Shared Preferences
Using SharedPreferences, you can create named maps of key/value pairs within your application that
can be shared between application components running in the same Context.
Shared Preferences support the primitive types Boolean, string, float, long, and integer, making them
an ideal way to quickly store default values, class instance variables, the current UI state, and user
preferences. They are most commonly used to persist data across user sessions and to share settings
between application components.
To create or modify a Shared Preference, call getSharedPreferences() on the application Context,
passing in the name of the Shared Preferences to change.

SharedPreferences getSharedPreferences (String name, int mode)

String name Retrieve and hold the contents of the preferences file given as the first argument. If
that file does not exist, android will create it.

int mode File creation mode


MODE_PRIVATE , the default mode, where the created file can only be accessed
by the calling application.
Returns a SharedPreferences object through which you can retrieve and modify its values.

Shared Preferences are shared across an application‘s components but aren‘t available to other
applications.
To modify a Shared Preference, use the [Link] class. Get the Editor object by
calling edit on the SharedPreferences object you want to change. To save edits, call commit on the
Editor.

Methods in [Link]

[Link] putBoolean(String key, boolean value)


Set a boolean value in the preferences editor
[Link] putFloat(String key, float value)
Set a float value in the preferences editor
[Link] putInt(String key, int value)
Set an int value in the preferences editor
[Link] putLong(String key, long value)
Set a long value in the preferences editor
173

[Link] putString(String key, String value)


Set a String value in the preferences editor
[Link] remove(String key)
Mark in the editor that a preference value should be removed,
which will be done in the actual preferences once commit() is
called.

boolean commit()
Commit your preferences changes back from this Editor to
the SharedPreferences object it is editing.

Example:
// Create or retrieve the shared preference object.
SharedPreferences myPreferences = getSharedPreferences
(―newprefs ―, Activity.MODE_PRIVATE);
// Retrieve an editor to modify the shared preferences.
[Link] editor = [Link]();
// Store new primitive types in the shared preferences object.
[Link](―name‖, ―John‖);
[Link](―age‖, 20);
[Link](―employed‖, true);
// Commit the changes.
[Link]();
Retrieving Shared Preferences
Accessing saved Shared Preferences is also done with the getSharedPreferences method. Pass in the
name of the Shared Preference you want to access, and use the type-safe get<type> methods to extract
saved values.
Each getter takes a key and a default value (used when no value is available for that key).

boolean getBoolean(String key, boolean defValue)


Retrieve a boolean value from the preferences.
float getFloat(String key, float defValue)
Retrieve a float value from the preferences.
int getInt(String key, int defValue)
Retrieve an int value from the preferences.
long getLong(String key, long defValue)
Retrieve a long value from the preferences.
String getString(String key, String defValue)
Retrieve a String value from the preferences.
174

Example:
// Create or retrieve the shared preference object.
SharedPreferences myPreferences = getSharedPreferences
(―newprefs ―, Activity.MODE_PRIVATE);
String name = [Link](―name‖, ―‖);
int age = [Link](―age‖, 0);
boolean state = [Link](―employed‖, false);

Example Program to input your name and save in preferences and retrieve it when the user clicked on
the menu in action bar.

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate([Link], menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
SharedPreferences myPreferences = getSharedPreferences("newprefs",
Activity.MODE_PRIVATE);
EditText txt2=(EditText)[Link]([Link].txt1);
if([Link]()==[Link]){
[Link] editor = [Link]();
// get the data from the EditText
String name=[Link]().toString();
[Link]("name",name);
[Link](this, "Successfully saved", Toast.LENGTH_SHORT) .show();
[Link]();
}
175

if([Link]()==[Link]){
//TextView to display the saved content
TextView txt1=(TextView)[Link]([Link]);
String name = [Link]("name", "");
[Link](name);
}
return true;
}
}
1.2 Persisting the Application Instance State
To save Activity instance variables, Android offers two specialized variations of Shared Preferences.
The first uses a Shared Preference named specifically for your Activity, whereas the other relies on a
series of lifecycle event handlers.
Shared Preferences and a set of event handlers used for saving Activity instance state.

Saving Activity State Using Shared Preferences


If you want to save Activity information (e.g., class instance variables) that doesn‘t need to be shared
with other components, you can call getPreferences() without specifying a preferences name. Access
to the Shared Preferences map returned is restricted to the calling Activity; each Activity supports a
single unnamed SharedPreferences object.

SharedPreferences getPreferences (int mode)

int mode: Operating mode. Use MODE_PRIVATE for the default operation.
Retrieve a SharedPreferences object for accessing preferences that are private to this activity.

The following skeleton code shows how to use the Activity‘s private Shared Preferences:
// Create or retrieve the activity preferences object.
SharedPreferences activityPreferences =
getPreferences (Activity.MODE_PRIVATE);
// Retrieve an editor to modify the shared preferences.
[Link] editor = [Link]();
// Retrieve the View
EditText text1 = (EditText)findViewById([Link].text1);
// Store new primitive types in the shared preferences object.
[Link](―name‖, [Link]().toString());
// Commit changes.
[Link]();
The data can be restored using the SharedPreferences and getString(), getInt() methods etc. (already
described in the above example).
176

Saving and Restoring Activity Instance State Using the Lifecycle Handlers
It‘s designed specifically to persist the UI state when the Activity becomes eligible for termination by
a resource-hungry run time. To save Activity instance variables, Android offers a specialized
alternative to Shared Preferences, by overriding an Activity‘s onSaveInstanceState event handler.
The handler works like the Shared Preference mechanism. It offers a Bundle parameter that represents
a key/value map of primitive types that can be used to save the Activity‘s instance values. This Bundle
is then made available as a parameter passed in to the onCreate and onRestoreInstanceState method
handlers. This UI state Bundle is used to record the values needed for an Activity to provide an
identical UI following unexpected restarts.

@Override
public void onSaveInstanceState(Bundle outState) {
// code to store value to bundle object
[Link](outState);
}
This handler will be triggered whenever an Activity completes its Active life cycle, but only when it‘s
not being explicitly finished. As a result, it‘s used to ensure a consistent Activity state between active
life cycles of a single user session.
To store values to Bundle object, the following methods in Bundle class can be used
void putString(String key, String value)
void putInt(String key, int value)
The saved Bundle is passed in to the onRestoreInstanceState and onCreate methods if the application
is forced to restart during a session. The following snippet shows how to extract values from the
Bundle and use them to update the Activity instance state:
@Override
public void onCreate(Bundle state) {
[Link](state);
//code to extract values from Bundle object
}
The following methods in Bundle class can be used to extract values.
boolean containsKey(String key) - returns whether the key is present in the Bundle object.
String getString(String key)
int getInt(String key)
It’s important to remember that onSaveInstanceState is called only when an Activity becomes inactive,
but not when it is being closed by a call to finish or by the user pressing the Back button.
177

Program to store/retrieve the user name


package [Link];

import [Link];
import [Link];
import [Link];
public class SaveActivity extends Activity {
EditText txtUname;
@Override
protected void onCreate(Bundle state) {
[Link](state);
setContentView([Link].save_layout);
txtUname=(EditText)[Link]([Link]);

// if the key is already stored retrieve it and set in the EditText

if ((state!=null) && [Link]("username")) {


String uname=[Link]("username");
[Link](uname);
}
}

public void onSaveInstanceState(Bundle state)


{
// To store the username in bundle

String uname=[Link]().toString();
[Link]("username",uname);
[Link](state);
}
}

Introducing the Preference Framework and the Preference Activity


Every good application needs preferences that enable the user to customize and personalize it to his
needs. Android provides us with a preference framework ready to use. Like the rest of the UI, you
have the choice to define your preference declaratively or programmatically. Android stores the
preferences as key-value pairs of primitive data types in a shared preferences object. Android
offers an XML-driven framework to create system-style Preference Screens for your applications. By
using this framework you can create Preference Activities that are consistent with those used in both
native and other third-party applications.
This has two distinct advantages:
 Users will be familiar with the layout and use of your settings screens.
 You can integrate settings screens from other applications (including system settings such as
location settings) into your application‘s preferences.
The preference framework consists of four parts:
178

Preference Screen layout — An XML file that defines the hierarchy of items displayed in your
Preference screens. It specifies the text and associated controls to display, the allowed values, and the
Shared Preference keys to use for each control.
Preference Activity and Preference Fragment — Extensions of PreferenceActivity and
PreferenceFragment respectively, that are used to host the Preference Screens. Prior to Android 3.0,
Preference Activities hosted the Preference Screen directly; since then, Preference Screens are hosted
by Preference Fragments, which, in turn, are hosted by Preference Activities.
Preference Header definition — An XML file that defines the Preference Fragments for your
application and the hierarchy that should be used to display them.
Shared Preference Change Listener — An implementation of the
OnSharedPreferenceChangeListener class used to listen for changes to Shared Preferences.
Defining a Preference Screen Layout in XML
Unlike in the standard UI layout, preference
definitions are stored in the res/xml resources
folder. Although conceptually they are similar to
the UI layout resources Preference Screen layouts
use a specialized set of controls designed
specifically for preferences. These native
preference controls are described in the next
section.
Each preference layout is defined as a hierarchy,
beginning with a single PreferenceScreen element:
<?xml version=‖1.0‖ encoding=‖utf-8‖?>
<PreferenceScreen
xmlns:android=‖[Link]
[Link]/apk/res/android‖>
</PreferenceScreen>
You can include additional Preference Screen
elements, each of which will be represented as a
selectable element that will display a new screen
when clicked.
Within each Preference Screen you can include any combination of PreferenceCategory and
Preference<control> elements. Preference Category elements, as shown in the following snippet, are
used to break each Preference Screen into subcategories using a title bar separator:
179

<PreferenceCategory
android:title=‖My Preference Category‖/>
Figure 7-2 shows the SIM card lock, device administration, and credential storage Preference
Categories used on the Security Preference Screen.
All that remains is to add the preference controls that will be used to set the preferences. Although the
specific attributes available for each preference control vary, each of them includes at least the
following four:
android:key The Shared Preference key against which the selected value will be recorded.
android:title The text displayed to represent the preference.
android:summary The longer text description displayed in a smaller font below the title
text.
android:defaultValue The default value that will be displayed (and selected) if no preference
value has been assigned to the associated preference key.
Native Preference Controls
Android includes several preference controls to build your Preference Screens:
CheckBoxPreference A standard preference check box control used to set preferences to true or
false.
EditTextPreference Allows users to enter a string value as a preference. Selecting the
preference text at run time will display a text-entry dialog.
ListPreference The preference equivalent of a spinner. Selecting this preference will
display a dialog box containing a list of values from which to select. You
can specify different arrays to contain the display text and selection values.
MultiSelectListPreference Introduced in Android 3.0 (API level 11), this is the preference
equivalent of a check box list.
RingtonePreference A specialized List Preference that presents the list of available
ringtones for user selection. This is particularly useful when
you‘re constructing a screen to configure notification settings.
You can use each preference control to construct your Preference Screen hierarchy. Alternatively, you
can create your own specialized preference controls by extending the Preference class.
Example Preference Screen – Preference Screen xml files must be stored in a folder in /res/xml.
/res/xml/[Link]
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="[Link]

<PreferenceCategory android:title="Settings" >


<EditTextPreference
android:title="User Name"
android:summary="Set Your User name"
180

android:key="username"/>
<CheckBoxPreference
android:key="title_status"
android:title="Show User Name"
android:summary="Check if you want to show username in all activities"
android:defaultValue="true"/>
</PreferenceCategory>
</PreferenceScreen>

Introducing the Preference Fragment


Since Android 3.0, the PreferenceFragment class has been used to host the preference screens defined
by Preferences Screen resources. To create a new Preference Fragment, extend the
PreferenceFragment class ([Link] package).
To inflate the preferences, override the onCreate handler and call addPreferencesFromResource, as
given in the following example.
Your application can include several different Preference Fragments, which will be grouped according
to the Preference Header hierarchy and displayed within a Preference Activity, as described in the
following sections.
Example program to include [Link] in a Fragment
[Link]
package [Link];

import [Link];
import [Link];

public class SettingsFragment extends PreferenceFragment {


@Override
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);

// Load the preferences from an XML


resource

addPreferencesFromResource([Link]
);

}
}
181

Introducing the Preference Activity


The PreferenceActivity class is used to host the Preference Fragment hierarchy. To display your
settings in an activity, extend the PreferenceActivity class. This is an extension of the
traditional Activity class that displays a list of settings based on a hierarchy of Preference objects.
The PreferenceActivity automatically persists the settings associated with each Preference when
the user makes a change.

Prior to Android 3.0, the Preference Activity was used to host Preference Screens directly. For
applications that target devices prior to Android 3.0, you may still need to use the Preference Activity
in this way.

public class SettingsActivity extends PreferenceActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
addPreferencesFromResource([Link]);
}
}

If you're developing for Android 3.0 (API level 11) and higher, you should use
a PreferenceFragment to display your list of Preference objects. You can add a PreferenceFragment to
any activity.

Fragments provide a more flexible architecture for your application, compared to using activities
alone. As such, we suggest you use PreferenceFragment to control the display of your settings.

SettingsActivity with SettingsFragment added to it.

package [Link];

import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];

public class SettingsActivity extends PreferenceActivity {


public void onCreate(Bundle savedInstanceState) {
182

[Link](savedInstanceState);
SettingsFragment sett=new SettingsFragment();
FragmentTransaction ft=getFragmentManager().beginTransaction();
[Link]([Link],sett);
[Link]();
}

Like all Activities, the Preference Activity must be included in the application manifest:
<activity android:name=‖.MyPreferenceActivity‖
android:label=‖My Preferences‖>
</activity>

Reading Preferences

By default, all your app's preferences are saved to a file that's accessible from anywhere within your
application by calling the static method [Link](). This
returns the SharedPreferences object containing all the key-value pairs that are associated with
the Preference objects used in your PreferenceActivity.

For example, here's how you can read one of the preference values from any other activity in your
application:

SharedPreferences sharedPref = [Link](this);

String uname = [Link](―uname‖, "");

Listening for preference changes


There are several reasons you might want to be notified as soon as the user changes one of the
preferences. In order to receive a callback when a change happens to any one of the preferences,
implement the
[Link] interface and register the listener for
the SharedPreferences object by calling registerOnSharedPreferenceChangeListener().
The interface has only one callback method, onSharedPreferenceChanged(), and you might find it
easiest to implement the interface as a part of your activity.

public class SettingsActivity extends PreferenceActivity


implements OnSharedPreferenceChangeListener {
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
…………
………...
183

SharedPreferences pref = [Link](this);

[Link](this);
}

public void onSharedPreferenceChanged (SharedPreferences sharedPreferences,


String key) {

if ([Link](―uname‖)) {
Preference pref = findPreference(key);
// Set summary to be the username if the key is uname
[Link]([Link](key, ""));
}
}
}

In this example, the method checks whether the changed setting is for a known preference key. It
calls findPreference() to get the Preference object that was changed so it can modify the item's
summary to be the user name.

Example program to display settings page when settings menu is selected. User can set username and
user name must be displayed in the action bar if checkbox is selected.

Refer [Link] and [Link] listed above

[Link]

package [Link];

import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class SettingsActivity extends PreferenceActivity implements


OnSharedPreferenceChangeListener{
SettingsFragment sett;
SharedPreferences prefs;
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
sett=new SettingsFragment();
FragmentTransaction ft=getFragmentManager().beginTransaction();
[Link]([Link],sett);
[Link]();
prefs = [Link](this);
}
184

protected void onResume(){


[Link]();
[Link](this);
ActionBar abar=[Link]();
String user=[Link]("username", "");
boolean status=[Link]("title_status", true);
if (status)
[Link](user);
else
[Link]("");

public void onSharedPreferenceChanged(SharedPreferences pref, String key) {


if ([Link]("username")) {
String user=[Link](key, "");
[Link](key).setSummary(user);
}
if ([Link]("title_status")) {
boolean status=[Link]("title_status", true);
ActionBar abar=[Link]();
String user=[Link]("username","");
if (status)
[Link](user);
else
[Link]("");
}}}

[Link]
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
// setContentView([Link].activity_main);
}

protected void onResume() {


[Link]();
ActionBar abar=[Link]();
185

SharedPreferences prefs = [Link](this);


String user=[Link]("username", "");
boolean status=[Link]("title_status", true);
if (status)
[Link](user);
else
[Link]("");

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate([Link], menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
if([Link]()==[Link]){
Intent intent = new Intent(this,[Link]);
startActivityForResult(intent,1);
}
return true;
}
}
/res/menu/[Link]
<menu xmlns:android="[Link] >

<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
<item
android:id="@+id/sett"
android:orderInCategory="100"
android:showAsAction="ifRoom"
android:title="@string/action_settings"/>
</menu>
186

Defining the Preference Fragment Hierarchy Using Preference Headers


In some cases, you might want to design your settings such that the first screen displays only a list
of subscreens. When you're developing such a design for Android 3.0 and higher, you should use the
"headers" feature instead of building subscreens with nested PreferenceScreen elements.

To build your settings with headers, you need to:


1. Separate each group of settings into separate instances of PreferenceFragment. That is, each group
of settings needs a separate XML file.
2. Create an XML headers file that lists each settings group and declares which fragment contains the
corresponding list of settings.
3. Extend the PreferenceActivity class to host your settings.
4. Implement the onBuildHeaders() callback to specify the headers file.

A great benefit to using this design is that PreferenceActivity automatically presents the two-pane
layout when running on large screens.

Creating the headers file


Each group of settings in your list of headers is specified by a single <header> element inside a
root <preference-headers> element. For example:

/res/xml/[Link]

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

<preference-headers xmlns:android="[Link]
187

<header
android:fragment="[Link]. SettingsFragment1"
android:title="@string/prefs_category1"
android:summary="@string/prefs_summ1" />
<header
android:fragment="[Link]. SettingsFragment2"
android:title="@string/prefs_category2"
android:summary="@string/prefs_summ2"/ >

</preference-headers>
188

A handset device with setting headers. When an item is selected, the


associated PreferenceFragment replaces the headers.

With the android:fragment attribute, each header declares an instance of PreferenceFragment that
should open when the user selects the header. In the above example the SettingsFragment1 and
SettingsFragment2 need to be created with preference screens.

Displaying the headers


To display the preference headers, you must implement the onBuildHeaders() callback method and
call loadHeadersFromResource().

For example:

public class SettingsActivity extends PreferenceActivity {


@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource([Link]. headers, target);
}
}

When the user selects an item from the list of headers, the system opens the
associated PreferenceFragment.

Note: When using preference headers, your subclass of PreferenceActivity doesn't need to implement
the onCreate() method, because the only required task for the activity is to load the headers.

SQLite Database
Android uses the SQLite database engine, a self-contained, transactional database engine that requires
no separate server process. Many applications and environments beyond Android make use of it, and a
large open source community actively develops SQLite. In contrast to desktop-oriented or enterprise
databases, which provide a plethora of features related to fault tolerance and concurrent access to data,
SQLite aggressively strips out features that are not absolutely necessary in order to achieve a small
footprint. For example, many database systems use static typing, but SQLite does not store database
type information. Instead, it pushes the responsibility of keeping type information into high-level
languages, such as Java, that map database structures into high-level types.

SQLite is not a Google project, although Google has contributed to it. SQLite has an international
team of software developers who are dedicated to enhancing the software‘s capabilities and reliability.
Reliability is a key feature of SQLite. More than half of the code in the project is devoted to testing the
library. The library is designed to handle many kinds of system failures, such as low memory, disk
189

errors, and power failures. The database should never be left in an unrecoverable state, as this would
be a showstopper on a mobile phone where critical data is often stored in a database.
Fortunately, the SQLite database is not susceptible to easy corruption—if it were, an inopportune
battery failure could turn a mobile phone into an expensive paperweight.

The SQL Language


Writing Android applications usually requires a basic ability to program in the SQL language,
although higher-level classes are provided for the most common data-related activities. This chapter
provides a beginner‘s introduction to SQLite. With SQLite, the database is a simple file in the Android
file system, which could reside in flash or external card memory, but you will find that most
applications‘ databases reside in a directory called
/data/data/[Link]/databases. You can issue the ls command in the adb shell to
list the databases that Android has created for you in that directory.
The database takes care of persistence—that is, it updates the SQLite file in the way specified by each
SQL statement issued by an application. In the following text, we describe SQLite commands as they
are used inside the sqlite3 command-line utility.
Later we will show ways to achieve the same effects using the Android API. Although command-line
SQL will not be part of the application you ship, it can certainly help to debug applications as you‘re
developing them. You will find that writing database code in Android is usually an iterative process of
writing Java code to manipulate tables, and then peeking at created data using the command line.
SQLite is a well-regarded relational database management system (RDBMS). It is:
 Open-source
 Standards-compliant
 Lightweight
 Single-tier
It has been implemented as a compact C library that‘s included as part of the Android software stack.
By being implemented as a library, rather than running as a separate ongoing process, each SQLite
database is an integrated part of the application that created it. This reduces external dependencies,
minimizes latency, and simplifies transaction locking and synchronization.
SQLite has a reputation for being extremely reliable and is the database system of choice for many
consumer electronic devices, including many MP3 players and smartphones.
Lightweight and powerful, SQLite differs from many conventional database engines by loosely typing
each column, meaning that column values are not required to conform to a single type; instead, each
value is typed individually in each row. As a result, type checking isn‘t necessary when assigning or
extracting values from each column within a row.
190

Database Manipulation Using sqlite3


Now that you understand the basics of SQL as it pertains to SQLite, let‘s have a look at a simple
database for storing video metadata using the sqlite3 command-line tool and the Android debug shell,
which you can start by using the adb command. Using the command line will allow us to view
database changes right away, and will provide some simple examples of how to work with this useful
database debugging tool. Note that it is likely easiest at first to run this example using the Android
emulator, since you will need root access in order to run it on a device.
We‘ll get the example started by initializing the database:
$ adb shell
# cd /data/data/
# mkdir [Link]
# cd [Link]
# mkdir databases
# cd databases
#
# sqlite3 simple_video.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
The sqlite3 command line accepts two kinds of commands: legal SQL, and single-word commands
that begin with a period (.). You can see the first (and probably most important!) of these in the
introduction message: .help. Try it out, just to get an idea of the options available to you:
sqlite> .help

SQL Data Definition Commands


Statements in the SQL language fall into two distinct categories: those used to create and modify
tables—the locations where data is stored—and those used to create, read, update, and delete the data
in those tables.
Data definition commands
CREATE TABLE
Developers start working with SQL by creating a table to store data. The CREATE TABLE command
creates a new table in an SQLite database. It specifies a name, which must be unique among the tables
in the database, and various columns to hold the data. Each column has a unique name within the table
and a type (the types are defined by SQL, such as a date or text string). The column may also specify
191

other attributes, such as whether values have to be unique, whether there is a default value when a row
is inserted without specifying a value, and whether NULL is allowed in the column.
A table is similar to a spreadsheet. Returning to the example of a contact database, each row in the
table contains the information for one contact. The columns in the table are the various bits of
information you collect about each individual contact: first name, last name, birthday, and so on.
The tables created by SQL CREATE TABLE statements and the attributes they contain are called a
database schema.

DROP TABLE
This removes a table added with the CREATE TABLE statement. It takes the name of the table to be
deleted. On completion, any data that was stored in the table may not be retrieved.
Here is some SQL code that will create and then delete a simple table for storing contacts:
sqlite> CREATE TABLE contacts ( first_name TEXT, last_name TEXT, phone_number
TEXT, height_in_meters REAL);
sqlite> DROP TABLE contacts;
When entering commands through sqlite3, you must terminate each command with a semicolon. You
may change the database schema after you create tables (which you may want to do to add a column or
change the default value of a column) by entering the ALTER TABLE command.
SQLite types
You must specify a type for each column that you create in all tables that you define SQLite supports
the following data types:
TEXT A text string, stored using the database encoding (UTF-8, UTF-16BE, or UTF-16LE).
You will find that the TEXT type is the most common.
REAL A floating-point value, stored as an 8-byte IEEE floating-point number.
BLOB Arbitrary binary data, stored exactly as if it was input. You can use the BLOB data type
to store any kind of variable-length data, such as an executable file, or a downloaded
image. Generally, blobs can add a large performance overhead to a mobile database and
you should usually avoid using them.
INTEGER A signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the
value.
Database constraints
Database constraints mark a column with particular attributes. Some constraints enforce data-oriented
limitations, such as requiring all values in a column to be unique (e.g., a column containing Social
Security numbers). Other constraints exhibit more functional uses. Relational constraints, PRIMARY
KEY and FOREIGN KEY, form the basis of inter table relationships.
192

Most tables should have a particular column that uniquely identifies each given row. Designated in
SQL as a PRIMARY KEY, this column tends to be used only as an identifier for each row and (unlike
a Social Security number) has no meaning to the rest of the world. Thus, you do not need to specify
values for the column. Instead, you can let SQLite assign incrementing integer values as new rows are
added. Other databases typically require you to specially mark the column as auto incrementing to
achieve this result. SQLite also offers an explicit AUTOINCREMENT constraint, but auto increments
primary keys by default. The incrementing values in the column take on a role similar to an opaque
object pointer in a high-level language such as Java or C: other database tables and code in a high-
level language can use the column to reference that particular row.

When database rows have a unique primary key, it is possible to start thinking about dependencies
between tables. For example, a table used as an employee database could define an integer column
called employer_id that would contain the primary key values of rows in a different table called
employers. If you perform a query and select one or more rows from the employers table, you can use
grab their IDs and to look up employees in an employees table through the table's employer_id
column. This allows a program to find the employees of a given employer. The two tables (stripped
down to a few columns relevant to this example) might look like this:
CREATE TABLE employers ( _id INTEGER PRIMARY KEY, company_name TEXT);
CREATE TABLE employees ( name TEXT, annual_salary REAL NOT NULL CHECK
(annual_salary > 0), employer_id REFERENCES employers(_id));
The idea of a table referring to another table‘s primary key has formal support in SQL as the
FOREIGN KEY column constraint, which enforces the validity of cross-table references.
This constraint tells the database that integers in a column with a foreign key constraint must refer to
valid primary keys of database rows in another table. Thus, if you insert a row into the employees
table with an employer_id for a row that does not exist in the employers table, many flavors of SQL
will raise a constraint violation. This may help you to avoid orphaned references, also known as
enforcement of foreign keys.
However, the foreign key constraint in SQLite is optional, and is turned off in Android. As of Android
2.2, you cannot rely on a foreign key constraint to catch incorrect foreign key references, so you will
need to take care when creating database schemas that use foreign keys.
There are several other constraints with less far-reaching effects:
UNIQUE
Forces the value of the given column to be different from the values in that column in all existing
rows, whenever a row is inserted or updated. Any insert or update operation that attempts to insert a
duplicate value will result in an SQLite constraint violation.
193

NOT NULL
Requires a value in the column; NULL cannot be assigned. Note that a primary key is both UNIQUE
and NOT NULL.
CHECK
Takes a Boolean-valued expression and requires that the expression return true for any value inserted
in the column. An example is the CHECK (annual_salary > 0), attribute shown earlier in the
employees table.
SQL Data Manipulation Commands
Once you have defined tables using data definition commands, you can then insert your data and query
the database. The following data manipulation commands are the most commonly used SQL
statements:
SELECT
This statement provides the main tool for querying the database. The result of this statement is zero or
more rows of data, where each row has a fixed number of columns. You can think of the SELECT
statement as producing a new table with only the rows and columns that you choose in the statement.
The SELECT statement is the most complicated command in the SQL language, and supports a broad
number of ways to build relationships between data across one or more database tables.
Clauses for SQL‘s SELECT command, which are all supported by the Android API, include the
following:
• FROM, which specifies the tables from which data will be pulled to fulfill the query.
• WHERE, which specifies conditions that selected rows in the tables must match to be returned by the
query.
• GROUP BY, which orders results in clusters according to column name.
• HAVING, which further limits results by evaluating groups against expressions. You might remove
groups from your query that do not have a minimum number of elements.
• ORDER BY, which sets the sort order of query results by specifying a column name that will define
the sort, and a function (e.g., ASC for ascending, DSC for descending) that will sort the rows by
elements in the specified column.
• LIMIT, which limits the number of rows in a query to the specified value (e.g., five rows). Here are a
few examples of SELECT statements:
SELECT * FROM contacts;
SELECT first_name, height_in_meters FROM contacts WHERE last_name = "Smith";
SELECT [Link], [Link] FROM employees, employers WHERE
employee.employer_id = employer._id ORDER BY
employer.company_name ASC;
194

The first statement retrieves all the rows in the contacts table, because no WHERE clause filters
results. All columns (indicated by the asterisk, *) of the rows are returned. The second statement gets
the names and heights of the members of the Smith family. The last statement prints a list of
employees and their employers, sorted by company name.
INSERT
This statement adds a new data row to a specified database table along with a set of specified values of
the proper SQLite type for each column (e.g., 5 for an integer). The insert may specify a list of
columns affected by the insert, which may be less than the number of columns in the table. If you
don‘t specify values for all columns, SQLite will fill in a default value for each unspecified column, if
you defined one for that column in your CREATE TABLE statement. If you don‘t provide a default,
SQLite uses a default of NULL.
Here are a few examples of INSERT statements:
INSERT INTO contacts(first_name) VALUES("Thomas");
INSERT INTO employers VALUES(1, "Acme Balloons");
INSERT INTO employees VALUES("Wile E. Coyote", 100000.000, 1);
The first adds a new row to the contacts for someone whose first name is Thomas and whose last
name, phone number, and height are unknown (NULL). The second adds Acme Balloons as a new
employer, and the third adds Wile E. Coyote as an employee there.
UPDATE
This statement modifies some rows in a given table with new values. Each assignment specifies a table
name and a given function that should provide a new value for the column. Like SELECT, you can
specify a WHERE clause that will identify the rows that should be updated during an invocation of the
UPDATE command. Like
INSERT, you can also specify a list of columns to be updated during command execution. The list of
columns works in the same manner as it does with INSERT. The
WHERE clause is critical; if it matches no rows, the UPDATE command will have no effect, but if the
clause is omitted, the statement will affect every row in the table.
Here are a few examples of UPDATE statements:
UPDATE contacts SET height_in_meters = 10, last_name = "Jones";
UPDATE employees SET annual_salary = 200000.00 WHERE employer_id =
( SELECT _id FROM employers WHERE company_name = "Acme Balloons");
The first claims that all your friends are giants with the last name Jones. The second is a more complex
query. It gives a substantial raise to all the employees of Acme Balloons.
195

The Android Database Classes


This section introduces the Java classes that give you access to the SQLite functions described earlier
in the chapter, with the data-centric model we just described in mind:
SQLiteDatabase
Android‘s Java interface to its relational database, SQLite. It supports an SQL implementation rich
enough for anything you‘re likely to need in a mobile application, including a cursor facility. Provides
methods to create, drop tables, insert, update select data from tables.
Cursor
A container for the results of a database query that supports an MVC-style observation system.
Cursors are similar to JDBC result sets and are the return value of a database query in Android. A
cursor can represent many objects without requiring an instance for each one. With a cursor, you can
move to the start of query results and access each row one at a time as needed. To access cursor data,
you call methods named as [Link]*(int columnNumber) (e.g., getAsString). The values the
cursor will return depend on the current cursor index, which you can increment by calling
[Link], or decrement by calling [Link], as needed. You can think of
the current index of the cursor as a pointer to a result object. Cursors are at the heart of the basis for
Android MVC.
SQLiteOpenHelper
class : [Link]
Provides a life cycle framework for creating and upgrading your application database.
It is a helper class to manage database creation and version management. This class takes care of
opening the database if it exists, creating it if it does not, and upgrading it as necessary. Transactions
are used to make sure the database is always in a sensible state.

void onCreate (SQLiteDatabase db)

Called when the database is created for the first time. This is where the creation of tables and the
initial population of the tables should happen.

void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion)

Called when the database needs to be upgraded. The implementation should use this method to drop
tables, add tables, or do anything else it needs to upgrade to the new schema version. This method
executes within a transaction. If an exception is thrown, all changes will automatically be rolled back.

Example Program :

public class DatabaseHandler extends SQLiteOpenHelper {


196

public DatabaseHandler(Context context) {


// Context, Database name, Cursor Factory, Database version are parameters
super(context, ―College‖, null, 1);
}

// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String table = "CREATE TABLE student (_id INTEGER PRIMARY KEY, name TEXT, course
TEXT, batch TEXT)‖;
[Link](table);
}
// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
[Link]("DROP TABLE IF EXISTS student");

// Create tables again


onCreate(db);
}
When we create an object of the above class in Activity class, the onCreate() is executed
automatically.
DatabaseHandler db = new DatabaseHandler(this);

SQLiteQueryBuilder
Provides a high-level abstraction for creating SQLite queries for use in Android applications. Using
this class can simplify the task of writing a query since it saves you from having to fiddle with SQL
syntax yourself.
[Link]

Cursor query(SQLiteDatabase db, String[] projectionIn, String selection,


String[] selectionArgs, String groupBy, Stringhaving, String sortOrder)

Perform a query by combining all current settings and the information passed into this method.

Android Database Manipulation using code


You should keep the following Android-specific considerations in mind when designing your
database.
 Files (such as bitmaps or audio fi les) are not usually stored within database tables. Use a string
to store a path to the file, preferably a fully qualified URI.
197

 Although not strictly a requirement, it‘s strongly recommended that all tables include an auto-
increment key field as a unique index field for each row. If you plan to share your table using a
Content Provider, a unique ID field is required.
If you want to manage the creation and opening of your databases directly, you can use the application
Context‘s openOrCreateDatabase method to create the database itself:
SQLiteDatabase openOrCreateDatabase (String name, int mode, CursorFactory
factory)

name refers to the name of the database, if it does not exists android will create it. If already exists
android will open it.

If mode is MODE_PRIVATE the database is accessible to the current application only.

It returns SQLiteDatabase object which can be used to create, insert, update and select tables.

Example: The following code can be defined in Activity class, this represents the Activity context.

String DATABASE_NAME="[Link]";
SQLiteDatabase db = [Link](DATABASE_NAME, this.MODE_PRIVATE, null);
It‘s good practice to defer creating and opening databases until they‘re needed, and to cache database
instances after they‘re successfully opened to limit the associated efficiency costs. At a minimum, any
such operations must be handled asynchronously to avoid impacting the main application thread.

Creating, Adding, Updating, and Removing Rows


The SQLiteDatabase class exposes insert, delete, and update methods that encapsulate the SQL
statements required to perform these actions.
Creating a table
The execSQL() method lets you execute any valid SQL statement on your database tables, should you
want to execute these (or any other) operations manually.
String DATABASE_NAME="[Link]";
SQLiteDatabase db = [Link](DATABASE_NAME, this.MODE_PRIVATE, null);
[Link]("CREATE TABLE student (_id INTEGER PRIMARY KEY AUTOINCREMENT, name
TEXT, batch TEXT, course TEXT)");

Inserting data into a Table


Content Values are used to insert new rows into tables. Each ContentValues object represents a single
table row as a map of column names to values.
Inserting Rows
To create a new row, construct a ContentValues object and use its put methods to add name/value
pairs representing each column name and its associated value.
Insert the new row by passing the Content Values into the insert method called on the target.
198

long insert (String table, String nullColumnHack, ContentValues values)

table String: the table to insert the row into


nullColumnHack String: optional; may be null. SQL doesn't allow inserting a completely empty
row without naming at least one column name.
values ContentValues: this map contains the initial column values for the row. The
keys should be the column names and the values the column values
returns the row ID of the newly inserted row, or -1 if an error occurred
Example:
// Create a new row of values to insert.
ContentValues newValues = new ContentValues();
// Assign values for each row.
[Link]("name","deepa");
[Link]("batch","Sem V");
[Link]("course","BCA");
[Link]("student", null, newValues);
When inserting a new row into an SQLite database, you must always explicitly specify at least one
column and a corresponding value, the latter of which can be null. If you set the null column hack
parameter to null.
When inserting an empty Content Values object SQLite will throw an exception. It‘s generally good
practice to ensure that your code doesn‘t attempt to insert empty Content Values into an SQLite
database.
Updating Rows
Updating rows is also done with Content Values. Create a new ContentValues object, using the put
methods to assign new values to each column you want to update. Call the update method on the
database, passing in the table name, the updated ContentValues object, and a where clause that
specifies the row(s) to update.

int update (String table, ContentValues values, String whereClause,

String[] whereArgs)

table String: the table to update in

values ContentValues: a map from column names to new column values. null is a
valid value that will be translated to NULL.

whereClause String: the optional WHERE clause to apply when updating. Passing null
will update all rows.
199

whereArgs String: You may include ?s in the where clause, which will be replaced by
the values from whereArgs. The values will be bound as Strings.
Returns the number of rows affected

// Create the updated row Content Values.


ContentValues newValues = new ContentValues();
// Assign values for the row to be updated.
[Link]("batch","Sem VI");
// Specify a where clause the defines which rows should be updated.
//Specify where arguments as necessary.
String where = ―_id = ?‖;
String whereArgs[] = {―1‖};
// Update the row with the specified index with the new values.
[Link](―student‖,newValues,where,whereArgs);
Deleting Rows
To delete a row, simply call the delete method on a database, specifying the table name and a where
clause that returns the rows you want to delete.
// Specify a where clause that determines which row(s) to delete.
// Specify where arguments as necessary.
String where = ―_id = ?‖;
String whereArgs[] = {―1‖};
// Delete the rows that match the where clause.
[Link](―student‖,where, whereArgs);

Querying a Database
Each database query is returned as a Cursor. This lets Android manage resources more efficiently by
retrieving and releasing row and column values on demand.
To execute a query on a Database object, use the query method, passing in the following:

Cursor query (String tablename, String[] projection, String selection,

String[] selectionArgs, String sortOrder)

The name of the table to query.


tablename

projection String array: A list of which columns to return. Passing null will return all
columns, which is inefficient.
200

selection String : A filter declaring which rows to return, formatted as an SQL WHERE
clause (excluding the WHERE itself). Passing null will return all rows in the
given table
You can include ? wildcards that will be replaced by the values passed in
through the selection argument parameter.

selectionArgs String: You may include ?s in selection, which will be replaced by the values
from selectionArgs, in the order that they appear in the selection. The values
will be bound as Strings.

sortOrder String: How to order the rows, formatted as an SQL ORDER BY clause
(excluding the ORDER BY itself). Passing null will use the default sort order,
which may be unordered.

Returns Cursor object that can be used to retrieve data.


// Specify the result column projection. Return the minimum set of columns
// required to satisfy your requirements.
String[] columns = new String[] {―_ID‖, ―NAME‖, ―COURSE‖, ‖BATCH‖};
// Specify the where clause that will limit our results.
String selection = ‖COURSE=?‖;
// Replace these with valid SQL statements as necessary.
String args[] = {―BCA‖};
String groupBy = null;
String having = null;
String order = null;
String DATABASE_NAME="[Link]";
SQLiteDatabase db = [Link](DATABASE_NAME, this.MODE_PRIVATE,
null);
Cursor cursor = [Link](―student‖, columns, selection, args, groupBy, having, order);
Extracting Values from a Cursor
Database queries are returned as Cursor objects. Rather than extracting and returning a copy of the
result values, Cursors are pointers to the result set within the underlying data. Cursors provide a
managed way of controlling your position (row) in the result set of a database query.
To extract values from a Cursor, first use the moveTo<location> methods described earlier to position
the cursor at the correct row of the result Cursor, and then use the type-safe get<type> methods
(passing in a column index) to return the value stored at the current row for the specified column. To
201

find the column index of a particular column within a result Cursor, use its getColumnIndexOrThrow
and getColumnIndex methods.
The Cursor class includes a number of navigation functions, including, but not limited to, the
following:
boolean moveToFirst() Moves the cursor to the fi rst row in the query result
boolean moveToNext() Moves the cursor to the next row
boolean moveToPrevious() Moves the cursor to the previous row
int getCount() Returns the number of rows in the result set
int getColumnIndexOrThrow(String colname) Returns the zero-based index for the column with
the specified name (throwing an exception if no column exists
with that name)
String getColumnName(int index) Returns the name of the specified column index
String[] getColumnNames() Returns a string array of all the column names in the current
Cursor
boolean moveToPosition(int position) Moves the cursor to the specified row
int getPosition() Returns the current cursor position

Android provides a convenient mechanism to ensure queries are performed asynchronously.


// Iterate over the cursors rows. The Cursor is initialized at before first, so we can
// check only if there is a ―next‖ row available.
//If the result Cursor is empty this will return false.
while ([Link]()) {
// code to retrieve columns
}
// Close the Cursor when you‘ve finished with it.
[Link]();
Because SQLite database columns are loosely typed, you can cast individual values into valid types, as
required. For example, values stored as floats can be read back as strings. When you have finished
using your result Cursor, it‘s important to close it to avoid memory leaks and reduce your application‘s
resource load:
Example:
int id;
String name, course, batch;
while([Link]())
{
id=[Link](0);
name=[Link](1);
course=[Link](2);
202

batch=[Link](3);
}
[Link]();

Example program:

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class MainActivity extends Activity {


SQLiteDatabase db;
String DATABASE_NAME="[Link]";
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].stud_layout);
db = [Link](DATABASE_NAME, this.MODE_PRIVATE, null);
[Link]("CREATE TABLE student (_id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT, batch TEXT, course TEXT)");
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate([Link], menu);
return true;
}

public boolean onOptionsItemSelected(MenuItem item) {


// Inflate the menu; this adds items to the action bar if it is present.
if([Link]()==[Link])
{
ContentValues newValues = new ContentValues();
EditText txtN=(EditText)[Link]([Link]);
EditText txtC=(EditText)[Link]([Link]);
EditText txtB=(EditText)[Link]([Link]);
String n,c,b;
n=[Link]().toString();
c=[Link]().toString();
b=[Link]().toString();
203

// Assign values for each row.


[Link]("name",n);
[Link]("batch",c);
[Link]("course",b);

[Link]("student", null, newValues);


[Link]("");
[Link]("");
[Link]("");

}
if([Link]()==[Link])
{
String columns[]={"_ID", "NAME", "COURSE","BATCH"};
Cursor c=[Link]("student", columns, null, null, null, null, null);
int id;
String name,course,batch;
LinearLayout ll = (LinearLayout) findViewById([Link]);
while([Link]())
{
id=[Link](0);
name=[Link](1);
course=[Link](2);
batch=[Link](3);
TextView tv1=new TextView(this);
[Link](id+" "+name+" "+course+" "+batch);
[Link](tv1);
}
[Link]();
}
return true;
}
}
/res/layout/stud_layout.xml

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

<LinearLayout xmlns:android="[Link]
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name" />
<EditText
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
204

android:layout_height="wrap_content"
android:text="Course" />
<EditText
android:id="@+id/txtCourse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Batch" />
<EditText
android:id="@+id/txtBatch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/txtView"
android:layout_width="wrap_content"
android:layout_height="wrap_content” />
</LinearLayout>

/res/menu/[Link]

<menu xmlns:android="[Link] >


<item
android:id="@+id/save"
android:orderInCategory="101"
android:showAsAction="ifRoom"
android:title="@string/insert"/>
<item
android:id="@+id/load"
android:orderInCategory="102"
android:showAsAction="ifRoom"
android:title="@string/open"/>
</menu>

SQL and the Database-Centric Data Model for Android


Applications
Now that you have some basic SQL programming knowledge, we can start thinking about how to put
it to use in an Android application. Our goal is to create robust applications based on the popular
Model-View-Controller (MVC) pattern that underlies well-written UI programs, specifically in a way
that works well for Android. One fundamental difference between mobile phone apps and desktop
apps is how they handle persistence. Traditional desktop-based applications—word processors, text
editors, drawing programs, presentation programs, and so on—often use a document centric form of
the MVC pattern. They open a document, read it into memory, and turn it into objects in memory that
form the data model. Such programs will make views for the data model, process user input through
their controller, and then modify the data model. The key consequence of this design is that you
205

explicitly open and save documents in order to make the data model persist between program
invocations.
We‘ve seen how user interface components work in Android. Next we‘ll explore the Android APIs for
database manipulation, which will prepare you to implement an application data model that works in a
new way.
Robust use of Android combines data models and user interface elements in a different manner. Apps
run on mobile devices with limited memory, which can run out of battery power at unpredictable and
possibly inopportune times. Small mobile devices also place a premium on reducing the interactive
burden on the user: reminding a user he ought to save a document when he is trying to answer a phone
call is not a good user experience.

Figure 10-1. Document-centric applications, which implement a data model with in-memory objects
The whole concept of a document is absent in Android. The user should always have the right data at
hand and be confident her data is safe. To make it easy to store and use application data incrementally,
item by item, and always have it in persistent memory without explicitly saving the whole data model,
Android provides support in its database, view, and activity classes for database-centric data (Figure
10-2). We‘ll explain how to use Android database classes to implement this kind of model.

Including Static Files as Resources


If your application requires external file resources, you can include them in your distribution package
by placing them in the res/raw folder of your project hierarchy.
206

To access these Read Only file resources, call the openRawResource method from your application‘s
Resource object to receive an InputStream based on the specified resource. Pass in the filename
(without extension) as the variable name from the [Link] class, as shown in the skeleton code below:
Resources myResources = getResources();
InputStream myFile = [Link]([Link]);
Adding raw files to your resources hierarchy is an excellent alternative for large, pre-existing data
sources (such as dictionaries) where it‘s not desirable (or even possible) to convert them into an
Android database.
Android‘s resource mechanism lets you specify alternative resource files for different languages,
locations, or hardware configurations. As a result, you could, for example, create an application that
dynamically loads a dictionary resource based on the user‘s current settings.
Working with the File System
File Management Tools
Android supplies some basic file management tools to help you deal with the file system. Many of
these utilities are located within the standard [Link] package. Android does supply some specialized
utilities for file management available from the application‘s Context.

boolean deleteFile (String name) Delete the given private file associated with this Context's
application package.

String[] fileList () Returns an array of strings naming the private files


associated with this Context's application package.

Using Application-Specific Folders to Store Files


Many applications will create or download files that are specific to the application. There are two
options for storing these application-specific files: internally or externally. When referring to the
external storage, we refer to the shared/media storage that is accessible by all applications and can
typically be mounted to a computer file system when the device is connected via USB. Although it is
typically located on the SD Card, some devices implement this as a separate partition on the internal
storage.
The most important thing to remember when storing files on external storage is that no security is
enforced on files stored here. Any application can access, overwrite, or delete files stored on the
external storage.
It‘s also important to remember that files stored on external storage may not always be available. If the
SD Card is ejected, or the device is mounted for access via a computer, your application will be unable
to read (or create) files on the external storage.
Android offers two corresponding methods via the application Context, getDir() and
207

getExternalFilesDir(), both of which return a File object that contains the path to the internal and
external application file storage directory, respectively.
All files stored in these directories or the subfolders will be erased when your application is
uninstalled.
It‘s good practice to store your application-specific data in its own subdirectory using the same style as
getExternalFilesDir() that is,
/Android/data/[YourPackage Name]/files
Note that this work-around will not automatically delete your application files when it is uninstalled.
Both of these methods accept a string parameter that can be used to specify the subdirectory into
which you want to place your files.
In Android 2.2 (API level 8) the Environment class introduced a number of DIRECTORY_[Category]
string constants that represent standard directory names, including downloads, images, movies, music,
and camera files. Files stored in the application folders should be specific to the parent application and
are typically not detected by the media-scanner, and therefore won‘t be added to the Media Library
automatically.
If your application downloads or creates files that should be added to the Media Library or otherwise
made available to other applications, consider putting them in the public external storage directory.

Creating Private Application Files

Save a File on Internal Storage

Android offers standard Java I/O classes and methods to simplify reading and writing streams from
and to local files.
To open a private file associated with this Context's application package the openFileOuput() method
defined in Context class is used.(Activity represents the Context).

FileOutputStream openFileOutput (String name, int mode)

If the file doesn't already exist, android will create it. No additional permissions are required for the
calling app to read or write the returned file.

name represents the name of the file and mode can be 0 or MODE_PRIVATE for the default
operation. Use MODE_APPEND to append to an existing file. It returns the
resulting FileOutputStream.

String FILE_NAME = ―[Link]‖;


// Create a new output file stream that‘s private to this application.
208

FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE);


This method only support files in the current application folder; specifying path separators will cause
an exception to be thrown. If the filename you specify when creating a FileOutputStream does not
exist, Android will create it for you. The default behavior for existing files is to overwrite them; to
append an existing file, specify the mode as Context.MODE_APPEND.
Alternatively, you can specify either Context.MODE_WORLD_READABLE or
Context.MODE_WORLD_WRITEABLE when creating the output file to make them available in
other applications, as shown in the following snippet:
String OUTPUT_FILE = ―[Link]‖;
FileOutputStream fos = openFileOutput(OUTPUT_FILE, Context.MODE_WORLD_WRITEABLE);
Writing Data into a File
The FileOutputStream class is defined in [Link] package and the write() methods can be used to
write data to the stream.

void write(byte[] b)
Write bytes from the specified byte array to this file output stream.

void write(byte[] b, int off, int len)


Writes len bytes from the specified byte array starting at offset off to this file output
stream.
void write(int b)
Writes the specified byte to this file output stream.

Example:

String filename = "myfile";


String txt = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
//converts txt into byte array and write it.
[Link]([Link]());
[Link]();
} catch (Exception e) {
[Link]();
}

Reading Data from a File


// Create a new file input stream.
FileInputStream fis = openFileInput(FILE_NAME);
A FileInputStream obtains input bytes from a file in a file system. What files are available depends on
the host environment. The read methods can be used to read the stream.
209

int read()
Reads a byte of data from this input stream.
int read(byte[] b, int off, int len)
Reads up to len bytes of data from this input stream into an array of bytes.
int read(byte[] b)
Reads up to [Link] bytes of data from this input stream into an array of bytes.

Example:
You can find the location of files stored in your sandbox by calling getFilesDir. This method will
return the absolute path to the files created using openFileOutput:
File file = getFilesDir();
Log.d(―OUTPUT_PATH_‖, [Link]());

Using the Application File Cache


Should your application need to cache temporary files, Android offers both a managed internal cache,
and (since Android API level 8) an unmanaged external cache. You can access them by calling the
getCacheDir and getExternalCacheDir methods, respectively, from the current Context.
Files stored in either cache location will be erased when the application is uninstalled. Files stored in
the internal cache will potentially be erased by the system when it is running low on available storage;
files stored on the external cache will not be erased, as the system does not track available storage on
external media. In either case it‘s good form to monitor and manage the size and age of your cache,
deleting files when a reasonable maximum cache size is exceeded.

Storing Publicly Readable Files


Android 2.2 (API level 8) also includes a convenience method,
[Link], that can be used to find a path in which to store your
application files.
The returned location is where users will typically place and manage their own files of each type. This
is particularly useful for applications that provide functionality that replaces or augments system
applications, such as the camera, that store files in standard locations. The
getExternalStoragePublicDirectory method accepts a String parameter that determines which
subdirectory you want to access using a series of Environment static constants:
DIRECTORY_ALARMS — Audio files that should be available as user-selectable alarm sounds
DIRECTORY_DCIM — Pictures and videos taken by the device
DIRECTORY_DOWNLOADS — Files downloaded by the user
DIRECTORY_MOVIES — Movies
210

DIRECTORY_MUSIC — Audio files that represent music


DIRECTORY_NOTIFICATIONS — Audio files that should be available as user-selectable
notification sounds
DIRECTORY_PICTURES — Pictures
DIRECTORY_PODCASTS — Audio files that represent podcasts
DIRECTORY_RINGTONES — Audio files that should be available as user-selectable ringtones
Note that if the returned directory doesn‘t exit, you must create it before writing files to the directory,
as shown in the following snippet:
String FILE_NAME = ―MyMusic.mp3‖;
File path = [Link] (
Environment.DIRECTORY_MUSIC);
File file = new File(path, FILE_NAME);
try {
[Link]();
[... Write Files ...]
} catch (IOException e) {
Log.d(TAG, ―Error writing ― + FILE_NAME, e);
}

To write to the external storage, you must request the WRITE_EXTERNAL_STORAGE permission
in your manifest file.

<manifest >
<uses-permission

android:name="[Link].WRITE_EXTERNAL_STORAGE" />
...
</manifest>

<manifest ...>
<uses-permission
android:name="[Link].READ_EXTERNAL_STORAGE" />
...
</manifest>
However, if your app uses the WRITE_EXTERNAL_STORAGE permission, then it implicitly has
permission to read the external storage as well.

You might also like