2. Why mobile application development?
Worldwide mobile device sales to end users totaled 1.55 billion
units in 2011, a 11 percent increase from 2010 [IDC]
Sales for the first quarter of 2012 [IDC]:
3. Phones get “smarter”
Around 26% of worldwide sales in 2011 are smartphones, and
estimated to reach 1 billion (47%) in 2015 [Gartner]
In U.S., 49.7% have smartphones, the trend is accelerating [Nielsen]
5. Apps can make a lot of money
The mobile app market will reach $15 billion by 2013
[Research2guidance]
6. Mobile applications are not ported desktop apps!
Factors that need to consider when working on a mobile app:
Memory
Limited, and much of it is already allocated
App speed
Usage patterns of mobile app are different
Apps need to load and work quickly
Internet access
Network is not always available and typically slow
Display
Smaller display
User input
Buttons, touch screen
15. Apple vs. Google
Battle continues, arguments varied . . .
. . . depending on who you ask
A look into history: compare with Mac/PC battles
Similar (many PC manufacturers, one Apple)
Different (Microsoft sells Windows, Google gives away
Android)
19. This course
Application development for the Android platform
Introduction to iOS
Emphasis on basics to make the contents robust to changes.
Theories behind mobile communication
Prerequisite: strong Java programming skills
Important: Things change and not everything can be covered in
this course. Self-learning skill is necessary.
Android phone is not required
20. Topics
Java refresher
Key concepts of Android
Designing the user interface
2D graphics
Multimedia
Local data storage
Network access
Embedded database
3D graphics in OpenGL
Multi-touch
Widget
21. Schedule
On
10 Jun, 24 Jun, 8 Jul, 22 Jul, 19 Aug, 2 Sep, 16 Sep, 30 Sep
Lecture: 08:30–12:00
Lab: 13:00–17:00
Don’t come to class late!
22. Grading
Midterm exam 25%
Final exam 25%
Project 25%
Lab 15%
Attendance & Participation 10%
Below 50% is fail, above 80% is A
The rests are proportional
23. Project
At the end of the course, each of you must program an
application on Android
You can program anything you want (but use your creativity!)
Due date: 30 September
Each of you must give a presentation on that day
Make sure your program is fully tested (non-functional
programs are worse than simple but functional programs)!
Write down a documentation of what your program does
Marks are given based on creativity, complexity,
documentations, and the presentation
24. Literature
The slides will be updated during the course of the lecture
References:
“Hello, Android – Introducing Google’s Mobile
Development Platform”, Ed Burnette, 3rd Edition (2010).
http://developer.android.com
Any Java and Android books on the market
26. Why refresh?
Android applications are written in Java
Without fully understanding Java, you will not be able to write
any Android applications
Important: Take your time with Java, make sure you understand
its concepts
We will use the slides Java Refresher Course from
Andrea Camesi, EPFL
28. What is Android?
An open source software stack that includes
Operating system: Linux kernel, provides low level
interface with hardware, memory management, and
process control
Middleware: A run time to execute Android applications,
including Dalvik virtual machine and core libraries
Key mobile apps: Email, SMS, PIM, web browser, etc
API libraries for writing mobile app such as SQLite,
WebKit, and OpenGL ES
Open-source development platform for creating mobile apps
29. Android history
Android Inc. founded in 2003. Google acquired Android Inc.
in 2005
Open Handset Alliance established on 5 November 2007
Led by Google with 34 members (now 80 firms)
Android is first announced on that day
Code name based on a
dessert item, in
alphabetical order:
1.5 Cupcake, 1.6 Donut,
2.0/2.1 Eclair, 2.2 Froyo,
2.3 Gingerbread,
3.0/3.1 Honeycomb, and
4.0 Ice Cream Sandwich
30. Android SDK features
No licensing, distributions, or development frees or release
approval processes
GSM, EDGE, and 3G networks for telephony and data transfer
Full multimedia hardware control
APIs for using sensor hardware including accelerometer and
the compass.
APIs for location based services
Inter-process communication
Shared data storage
Background applications and processes
Home screen widgets, Live Folders
HTML5 WebKit-based web browser
And many more . . .
31. Android SDK
The Android SDK includes
The Android APIs: the core of the SDK
Development tools: for compiling and debugging
The Android Virtual Device (AVD) Manager and Emulator
Documentations
Sample code
There is no dedicated IDE for Android
However, Android has a special plugin for Eclipse, called ADT
Plugin, for creating Android projects
ADT Plugin tightly integrates Eclipse with the Android Emulator
and debugging tools
34. Linux kernel
Android is built on top of a solid and proven foundation: the
Linux kernel
Created by Linus Torvalds in 1991
Linux can be found today in everything from wristwatches to
supercomputer
It provides the hardware abstraction layer for Android as well as
memory management, process management, networking, and
other operating system services
Android phone user will never see Linux, and your programs
will not make Linux calls directly
35. Native libraries
Next layer above the kernel, written in C or C++
Compiled for the particular hardware architecture used by the
phone, and preinstalled by the phone vendor
Important libraries include:
Surface Manager: a compositing window manager
2D and 3D graphics
Media codecs for recording and playing variety of formats
including AAC, AVC (H.264), H.263, MP3, and MPEG-4
SQLite database for storing persistent data
WebKit: a browser engine for fast display of HTML content
Libraries are not applications by themselves. They are only to
be called by higher-level layers.
36. Android runtime
Another layer on top of the kernel.
Android runtime includes the Dalvik virtual machine (VM) and
the core Java libraries.
Dalvik VM is Google’s implementation of Java, optimized for
mobile devices
Differ from traditional Java VM:
Dalvik VM runs .dex files, converted at compile time from
standard .class and .jar files. Reason: .dex files are
more compact.
Android’s core Java libraries are different from both the
Java Standard Edition (Java SE) libraries and the Java
Mobile Edition (Java ME) libraries
37. Application framework
Sitting above the native libraries and runtime
Provides high-level building blocks for creating applications
Comes pre-installed with Android, can be extend if needed
Important parts are:
Activity manager controls the life cycles of applications and
user navigation
Content providers encapsulate data that needs to be
shared between applications, such as contacts
Resource manager provides access to non-code resources
such as localized strings, graphics, and layout files
Location manager provides location information
Notification manager presents messages to users
38. Applications and widgets
The highest layer. They are what users see.
Applications are programs that take over the whole screen and
interact with users
Widgets operate only in a small rectangle of the Home screen
application
Standard system applications: phone dialer, email, contacts,
web browser, Android markets
The most part of this course will cover application development.
Widgets development is at the end of the course.
40. One foreground application at a time
On PC, many applications running and visible at once in
different windows. One of the windows has keyboard focus, but
otherwise all the programs are equal.
In Android, one foreground application, typically takes over the
whole screen except for the status line.
Users first see the Home application when turning on their
phones
41. Application stack
When the user runs an application, Android starts it and brings
it to the foreground.
From that application, the user might invoke another
application, or another screen in the same application, and then
another and another.
All these programs and screens are recorded on the application
stack by the system’s Activity Manager.
At any time, the user can press the Back button to the previous
screen on the stack.
42. Process = application
Internally, each user interface screen is represented by an
Activity class
Each activity has its own life cycle
An application is one or more activities plus a Linux process to
contain them
However, the activity life cycle is not tied to the process life
cycle
Processes are just disposable containers for activities, so an
application can be “alive” even if its process has been killed!
43. Life cycle
During its lifetime, each activity of an Android program can be
in one of the following states:
44. Life cycle (cont.)
Developers do not have control over what states their programs
are in
The system manages changes of states and notify developers
when they are about to change through the onXX() method
calls
We override these methods in the Activity class, and
Android will call them at the appropriate time:
onCreate(Bundle): This is called when the activity first
starts up.
You can use it to perform one-time initialization such as
creating the user interface. onCreate() takes one
parameter that is either null or some state information
previously saved by the onSaveInstanceState()
method.
45. Life cycle (cont.)
onStart(): This indicates the activity is about to be
displayed to the user
onResume(): This is called when your activity can start
interacting with the user. This is a good place to start
animations and music.
onPause(): This runs when the activity is about to go into
the background, usually because another activity has been
launched in front of it. This is where you should save your
program’s persistent state, such as a database record
being edited.
onStop(): This is called when your activity is no longer
visible to the user and it won’t be needed for a while. If
memory is tight, onStop() may never be called (the
system may simply terminate your process).
46. Life cycle (cont.)
onRestart(): Indicates that your activity is being
redisplayed to the user from a stopped state
onDestroy(): This is called right before your activity is
destroyed. If memory is tight, onDestroy() may never be
called (the system may simply terminate your process).
onSaveInstanceState(Bundle): Android will call this
method to allow the activity to save per-instance state,
such as a cursor position within a text field. Usually you
won’t need to override it because the default
implementation saves the state for all your user interface
controls automatically.
onRestoreInstanceState(Bundle): This is called
when the activity is being reinitialized from a state
previously saved by the onSaveInstanceState()
method. The default implementation restores the state of
your user interface.
47. Caveat
Activities that are not running in the foreground may be
stopped, or the Linux process that houses them may be killed
at any time in order to make room for new activities
So, design your app with this in mind!
In some cases, onPause() may be the last method called in
your activity, so that’s where you should save any data you want
to keep around for next time.
49. Activities
An activity is a user interface screen
Applications can define one or more activities to handle
different phases of the program.
As discussed earlier, each activity is responsible for saving its
own state so that it can be restored later as part of the
application life cycle
50. Intents
An intent is a mechanism for describing a specific action, such
as “pick a photo”, “phone home”, or “open the pod bay doors”
Just about everything goes through intents, many components
can be replaced or reused
For example, there is an intent for “send an email”. Your app
can invoke that intent to send emails.
Or you can write a new email application, and register an
activity to handle that intent and replace the standard mail
program
Next time somebody tries to send an email, they’ll get the
option to use your program instead of the standard one
51. Services
A service is a task that runs in the background without the
user’s direct interaction
For example, consider a music player. The music may be
started by an activity, but you want it to keep playing even when
the user has moved on to a different program.
So, the code that does the actual playing should be in a
service.
Later, another activity may bind to that service and tell it to
switch tracks or stop playing.
Android comes with many services built in, along with
convenient APIs to access them.
52. Content providers
A content provider is a set of data wrapped up in a custom API
to read and write it
This is the best way to share global data between applications.
For example, Google provides a content provider for contacts.
All the information there—names, addresses, phone numbers,
and so forth—can be shared by any application that wants to
use it.
53. Resources
A resource is a localized text string, bitmap, or other small
piece of noncode information that your program needs.
Useful for internationalization and for supporting multiple device
types
Inside your project, resources are stored in the res directory.
Its subfolders determine the content types, e.g. PNG and JPG
in res/drawable and XMLs for screen layouts in
res/layout
At build time all resources get compiled into the application.
The compiler generates a class named R that contains
identifiers that can be used to reference those resources in the
program
54. The AndroidManifest.xml file
Every application must have an AndroidManifest.xml file
(with precisely that name) in its root directory.
The manifest presents essential information about the
application to the Android system
Among other things, the manifest
names the Java package for the application
describes the components of the application—the
activities, services, broadcast receivers, and content
providers that the application is composed of
determines which processes will host application
components
declares which permissions the application must have
declares the minimum level of the Android API that the
application requires.
55. Security
As mentioned earlier, every application runs in its own Linux
process
The hardware forbids one process from accessing another
process’s memory
Furthermore, every application is assigned a specific user ID.
Any files it creates cannot be read or written by other
applications.
Access to certain critical operations are restricted. To use
them, permissions must be specifically asked in a file named
AndroidManifest.xml
When installing, the Package Manager either grants or doesn’t
grant the permissions based on certificates and, if necessary,
user prompts
56. Permissions in AndroidManifest.xml
Common permissions:
INTERNET: Access the Internet
READ_CONTACTS: Read the user’s contacts data
WRITE_CONTACTS: Write the user’s contacts data
RECEIVE_SMS: Monitor incoming SMS messages
ACCESS_COARSE_LOCATION: Use a coarse location
provider such as cell towers or wifi
ACCESS_FINE_LOCATION: Use a more accurate location
provider such as GPS
E.g., add the following tag to monitor incoming SMS messages:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
58. Designing the User Interface
In this section: how to design user interfaces
We will learn by going through examples based on Sudoku
59. Sudoku
You have a grid of 81 tiles (9 × 9)
When the game starts, some numbers are already filled in
You try to fill in the rest so that each column, each row, and
each of the 3 × 3 sub-grids contains the numbers 1 through 9
only once
60. Procedural vs. declarative UI design
Procedural design is done in code, e.g. Java Swing where code
must be written to create and manipulate UI objects such as
JFrame and JButton
Declarative design does not involve code, e.g. HTML where you
describe what you want to see, not how you want to do it
Android can handle both, either in Java or XML
It is recommended, however, to use XML as much as possible
as it is often shorter and easier to understand, and less likely to
change
61. R.java
By default, the main (declarative) UI of your program is kept in
main.xml in the res/layout directory
The file can be referred in the code by using the resource
identifier R.layout.main
Eclipse plug-in automatically generates the class R.java from
files in the res directory
Values in R.java are not objects, but simply handles that refer
to the real data
public static final class layout {
public static final int main=0x7f030000;
}
62. Layout resource
Define the architecture for the UI in an Activity or a component
of a UI
Start with
<?xml version="1.0" encoding="utf-8"?>
Technically, a layout resource contains ViewGroup and View
For example,
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/nameTextbox"
... />
<!- ... ->
</LinearLayout>
63. ViewGroup
A container for View elements
FrameLayout arranges its children so they all start at the top
left of the screen. This is used for tabbed views and image
switchers.
LinearLayout arranges its children in a single column or row.
This is the most common layout you will use.
RelativeLayout arranges its children in relation to each
other or to the parent
TableLayout arranges its children in rows and columns,
similar to an HTML table
64. View
An individual UI component, generally referred to as a “widget”,
e.g. TextView, Button, CheckBox
Use @+id/name to define an ID
In Java, use findViewById(R.id.nameTextbox) to refer
to the TextView nameTextBox
Reference to layout resource:
http://developer.android.com/guide/topics/resources/layout-
resource.html
66. Some parameters to all layouts
xmlns:android="http://schemas.android.com/apk/res/android"
Defines the XML namespace for Android. You should define
this once, on the first XML tag in the file.
android:layout_width="fill_parent",
android:layout_height="fill_parent"
Takes up the entire width and height of the parent (in this case,
the window)
android:layout_width="wrap_content",
android:layout_height="wrap_content"
Just big enough to enclose its content
67. strings.xml
Do not hard-code strings. Instead, define them in
res/values/strings.xml.
For example,
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Sudoku</string>
<string name="main_title">Android Sudoku</string>
<!- ... ->
</resources>
Use @string/resid to refer the the string resid
app_name, used in AndroidManifest.xml, is the app name
main_title can be used in main.xml, e.g.
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/main_title" />
68. colors.xml
Define colors in res/values/colors.xml
For example,
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="background">#3500ffff</color>
</resources>
Colors are defined in Alpha-Red-Green-Blue format
Use @color/resid to refer to the color resid, e.g.
android:background="@color/background"
69. Activity (revisited)
An activity is a single, focused thing that the user can do
The Activity class takes care of creating a window.
Subclasses of Activity should implement:
onCreate(Bundle) initialize your activity.
Call setContentView(int) with a layout resource to
define UI.
Use findViewById(int) to retrieve the widgets in that
UI that you need to interact with programmatically.
onPause() deals with the user leaving your activity. Any
changes made by the user should be committed at this
point.
70. Intent (revisited)
An intent is an abstract description of an operation to be
performed.
It can be used with startActivity(Intent) to launch an
Activity
Declare all activities you start in AndroidManifest.xml, e.g.
<activity android:name=".About"
android:label="@string/about_title" >
</activity>
Think of an intent as a glue between activities, basically a
passive data structure holding an abstract description of an
action to be performed.
71. Styles
A style is a collection of properties that specify the look and
format for a View or window.
A style can specify properties such as height, padding, font
color, font size, background color, etc.
Similar to cascading stylesheets (CSS)
Define a style using XML in res/values/
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont"
parent="@android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
72. Styles and Themes
Apply a style to a View
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
A theme is a style applied to an entire Activity or
application. When applied, every View in the Activity or
application will apply each style property that it supports
Apply a theme to an Activity
<activity android:theme="@android:style/Theme.Dialog">
The @android: prefix means this is a reference to a resource
defined by Android, not one that is defined in your program
73. Options menu
Define a menu using XML in res/menu/
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/settings"
android:title="@string/settings_label"
android:alphabeticShortcut="@string/settings_shortcut" />
</menu>
Override Activity.onCreateOptionsMenu(Menu)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
getMenuInflater() is used to read the menu definition from
main.xml and turns it into a real view
74. Options menu and context menu
When the user selects any menu item,
onOptionsItemSelected() will be called
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
startActivity(new Intent(this, Prefs.class));
return true;
// More items go here (if any) ...
}
return false;
}
Apart from options menu, a context menu can be used to
provide the user access to actions that pertain to a specific item
In this case, use onCreateContextMenu and
onContextItemSelected instead
75. Preferences
Define a preference screen using XML in res/xml/
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="music"
android:title="@string/music_title"
android:summary="@string/music_summary"
android:defaultValue="true" />
<!- ... ->
</PreferenceScreen>
Subclass PreferenceActivity, and override onCreate to
call addPreferencesFromResource
public class Prefs extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
76. AlertDialog
A Dialog that can display an array of things
new AlertDialog.Builder(this)
.setTitle(R.string.new_game_title)
.setItems(R.array.difficulty,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface,
int i) {
startGame(i);
}
})
.show();
An array can be defined using XML in res/values
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="difficulty">
<item>@string/easy_label</item>
<item>@string/medium_label</item>
<item>@string/hard_label</item>
</array>
</resources>
77. Debugging
The Log class provides several static methods to print
messages of various severity levels to the Android system log:
Log.e(): Errors
Log.w(): Warnings
Log.i(): Information
Log.d(): Debugging
Log.v(): Verbose
Log.wtf(): What a Terrible Failure
Open LogCat to view the logs
In addition, the Eclipse debugger can be used to set
breakpoints, single step, and view the state of your program.
Add android:debuggable=“true” in
AndroidManifest.xml
79. Graphics in Android
In this section: how to make graphics in Android
Good graphics is very important these days
Android has very powerful graphics libraries: both 2D and 3D
We cover 2D graphics here, and apply it to the Sudoku example
3D graphics will be covered later
80. The basics
Native 2D graphics library: android.graphics package
Let’s start with Color, Paint, Canvas, Path, Drawable
classes
81. Color
Colors are represented with four numbers: alpha, red, green,
and blue (ARGB)
Each has 8 bits or 256 possible values
Alpha is a measure of transparency: 0 is completely
transparent.
Example:
int b = Color.BLUE; // solid blue
int c = Color.argb(127, 255, 0, 255); // translucent purple
Define your colors in an XML resource file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="mycolor">#1fff00ff</color>
</resources>
In Java, we can reference colors by their names
color = getResources().getColor(R.color.mycolor);
82. Paint
Hold the style and color information about how to draw
geometries, text and bitmaps
Examples:
setColor(int): sets the paint’s color
setTextSize(float): sets the paint’s text size
setStyle(Paint.Style): sets the paint’s style, used
for controlling how primitives’ geometries are interpreted
(filled and/or stroked)
83. Path
Hold a set of vector-drawing commands such as lines,
rectangles, and curves
Example of a circle at position x = 150, y = 150, with radius of
100 pixels.
circle = new Path();
circle.addCircle(150, 150, 100, Direction.CW);
84. Canvas
Represent a surface to draw upon
Initially, it has no contents. Use its methods to draw lines,
rectangles, circles, or other arbitrary graphics.
Activity hosts View, which in turn hosts Canvas
Override the method View.onDraw(Canvas) to draw your
contents on the canvas
Example:
private static final String QUOTE = "Now is the time for all "
+ "good men to come to the aid of their country.";
canvas.drawPath(circle, cPaint);
canvas.drawTextOnPath(QUOTE, circle, 0, 20, tPaint);
85. Drawable
An abstract class for “something that can be drawn”
Drawables can take a variety of forms:
Bitmap: the simplest drawable, a PNG or JPEG image
Nine Patch: a stretchable PNG image
Shape: vector-drawing commands, based on Path
Layers: a container for child drawables, on top of each
other
States: a container that shows one of its child drawables
based on its state (a bit mask)
Levels: a container that shows one of its child drawables
based on its level (a range of integers)
Scale: a container for one child drawable that modifies its
size based on the current level
94. Multimedia
Android provides support for encoding and decoding a variety
of common media types
Easy to integrate audio, video, and images into applications
Use the package: android.media
In particular, the MediaPlayer class
An object of this class can fetch, decode, and play both audio
and video with minimal setup
Support several media sources:
Local resources
Internal URIs
External URLs (streaming)
95. Play audio
Play from a local raw resource (in res/raw)
MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);
mp.start();
Play from a URI, available locally in the system
Uri uri = ...; // initialize Uri here
MediaPlayer mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(getApplicationContext(), uri);
mp.prepare();
mp.start();
Play from a remote URL via HTTP streaming
String url = ...; // your URL here
MediaPlayer mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(url);
mp.prepare(); // might take long! (for buffering, etc)
mp.start();
96. Asynchronous preparation
prepare() can take a long time, because it might involve
fetching and decoding media data
So, never call it from UI thread
Instead, use the convenient method prepareAsync(). It
spawns another thread to prepare MediaPlayer and notify the
main thread when done.
Use MediaPlayer.OnPreparedListener for the
notification
98. Releasing the MediaPlayer
A MediaPlayer can consume valuable system resources
So, call release() to release system resources allocated to it
For example, release it in Activity.onStop()
mp.release();
mp = null;
99. Using a Service with MediaPlayer
Use Service to play media in the background. So, It will
continue playing even the user is interacting with other
applications.
Use wake locks to guarantee that the service keeps playing
even if the phone is idle
The following will keep the CPU to remain wake
mp = new MediaPlayer();
mp.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
Acquire WifiLock, if streaming media over the network:
WifiLock wifiLock =
((WifiManager) getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
wifiLock.acquire();
To release:
wifilock.release();
101. Data Storage
Android provides several options to save persistent application
data
Shared preferences: store private primitive data in
key-value pairs
Internal storage: store private data on the device memory
External storage: store public data on the shared external
storage
SQLite database: store structured data in a private
database
Network connection: store data on the web with your own
network server
We will cover the first three today
102. Using shared preferences
The SharedPreferences class provides a general
framework for saving and retrieving persistent key-value pairs
of primitive data types
Use getSharedPreferences() to get an object
To write values:
Call edit() to get a SharedPreferences.Editor
Adds values with methods such as putBoolean() and
putString()
Commit the new values with commit()
To read values, use methods such as getBoolean() and
getString()
103. Example of shared preferences
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
@Override
protected void onCreate(Bundle state){
super.onCreate(state);
...
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
@Override
protected void onStop(){
super.onStop();
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
editor.commit();
}
}
104. Using the internal storage
You can save files directly on the device’s internal storage
By default, files saved to the internal storage are private to your
application
When the application is uninstalled, these files are removed.
To create and write a private file:
Call openFileOutput() with the name of the file and the
operating mode
Write with write()
Close with stream with close()
To read a file:
Call openFileInput() with the name of the file. It
returns FileInputStream
Read bytes with read ()
Close with stream with close()
105. Example of internal storage
Example:
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME,
Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
Some useful methods:
getFilesDir() – Gets the absolute path to the directory
where internal files are saved
getDir() – Creates (or opens an existing) directory
within your internal storage space
deleteFile() – Deletes a file saved on the internal
storage
fileList() – Returns an array of files currently saved by
your application
106. Using the external storage
Every Android device supports a shared “external storage” that
you can use to save files
This can be a removable storage media (such as an SD card)
or an internal (non-removable) storage
Files saved to the external storage are world-readable and can
be modified by the user when they enable USB mass storage to
transfer files on a computer
107. Some useful methods
Before doing any work with external storage, call
getExternalStorageState() to check whether the media
is available
Use getExternalFilesDir() to open a directory. This
directory is local to the app and will be deleted when the app is
uninstalled.
Use getExternalStoragePublicDirectory() to open a
directory. This directory is shared and will NOT be deleted
when the app is uninstalled.
In both cases, use e.g. DIRECTORY_MUSIC,
DIRECTORY_RINGTONES, or DIRECTORY_PICTURES to
specify the type of subdirectory
109. The Web
In this chapter: connect your app to the web
Two simple approaches:
Open an external web browser from your app
Embed a browser into your app
Also include:
How to connect JavaScript and Android’s Java code
Web services
110. Browsing by Intent
The simplest thing you can do: open a browser from your app
All it takes are three lines of code!
private void openBrowser() {
Uri uri = Uri.parse(urlText.getText().toString());
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
This code
pauses your app, and
starts the Browser activity with its own view
Remember the app stack: when the Back key is pressed, the
browser will go away, and your app will continue
111. Web with a View
Android provides a wrapper around the WebKit browser engine
called WebView
WebView works like any other view, except that it has a few
extra methods specific to the browser
private void openBrowser() {
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(urlText.getText().toString());
}
The loadUrl() method causes the browser engine to begin
loading and display a web page. It does not wait for the loading
to finish and returns immediately.
To access the Internet, add this line to
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
112. Some WebView’s useful methods
addJavascriptInterface(): Allows a Java object to be
accessed from JavaScript
createSnapshot(): Creates a screenshot of the current
page
getSettings(): Returns a WebSettings object used to
control the settings
loadData(): Loads the given string data into the browser
loadDataWithBaseURL(): Loads the given data using a
base URL
loadUrl(): Loads a web page from the given URL
113. Some WebView’s useful methods (cont.)
setDownloadListener(): Registers callbacks for download
events, such as when the user downloads a .zip or .apk file
setWebChromeClient(): Registers callbacks for events that
need to be done outside the WebView rectangle, such as
updating the title or progress bar or opening a JavaScript dialog
box
setWebViewClient(): Lets the application set hooks in the
browser to intercept events such as resource loads, key
presses, and authorization requests
stopLoading(): Stops the current page from loading
114. Calling JavaScript from Java
Use the WebView’s loadUrl() method, passing it a URL of
the form javascript:code-to-execute
Example: define function callJS() in assets/index.html
<script language="JavaScript">
function callJS(arg) {
document.getElementById(’replaceme’).innerHTML = arg;
}
</script>
...
<p id="replaceme"></p>
In Java, first load the index.html
webView.loadUrl("file:///android_asset/index.html");
The function callJS() can be called by
webView.loadUrl("javascript:callJS(’Hello from Android’)");
115. Calling Java from JavaScript
Use the WebView’s addJavascriptInterface() method to
define objects that JavaScript code can access
Example: define a class to be exposed to JavaScript
private class AndroidBridge {
public void callAndroid(final String arg) {
handler.post(new Runnable() {
public void run() {
textView.setText(arg);
}
});
}
}
Then, register it to JavaScript
webView.addJavascriptInterface(new AndroidBridge(), "android");
116. Calling Java from JavaScript (cont.)
For alerts or progress updates, use setWebChromeClient()
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(final WebView view,
final String url, final String message, JsResult result) {
Toast.makeText(LocalBrowser.this, message, 3000).show();
result.confirm();
return true; // I handled it
}
});
Calls from JavaScript
<a href="#"
onclick="window.alert(’Alert from JavaScript’)">
Display JavaScript alert</a>
<a href="#"
onclick="window.android.callAndroid(’Hello from Browser’)">
Call Android from JavaScript</a>
117. Using web services
Android fully supports java.net.HttpURLConnection for
making requests to a HTTP server
Example:
String q = URLEncoder.encode(original, "UTF-8" );
URL url = new URL(
"http://ajax.googleapis.com/ajax/services/language/translate"
+ "?v=1.0" + "&q=" + q + "&langpair=" + from
+ "%7C" + to);
// Creates a connection and set parameters
con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(10000 /* milliseconds */);
con.setConnectTimeout(15000 /* milliseconds */);
con.setRequestMethod("GET" );
con.addRequestProperty("Referer" ,
"http://www.pragprog.com/titles/eband3/hello-android" );
con.setDoInput(true);
// Starts the query
con.connect();
118. Using web services (cont.)
However, such calls must be made asynchronously to make
sure that your app remains responsive
Trick: use the java.util.concurrent package
Use ExecutorService to manage threads
Submit an instance of Runnable or Callable
An instance of the Future class is returned
A Future instance represents the as-yet-unknown future value
that will be returned by your task (if any)
121. GPS
The Global Positioning System (GPS) is a constellation of 27
Earth-orbiting satellites (24 in operation + 3 extras)
The US military developed it as a military navigation system,
later opened up for everybody
Each satellite circles the globe at about 19,300 km, making two
complete rotations everyday
The orbits: at any time, anywhere on Earth, there are at least
four satellites visible in the sky
GPS receivers locate at least four satellites, figure the distance
to each, and use this information to deduce its own location.
This operation is based on a simple math principle called
trilateration
122. 2D Trilateration
To simplify explanations: let’s start with two-dimensional
trilateration
Imagine that you are totally lost. You find a friendly local and
ask, “Where am I?”. He says, “You are 700 km from Bangkok”
You could be anywhere on a circle around Bangkok that has a
radius of 700 km:
Bangkok
123. Second circle
You ask somebody else, and she says, “You are 640 km from
Kuala Lumpur”
Combining with the previous information, you know that you
must be at one of the two intersection points
Bangkok
KL
124. Third circle
If a third person tells you that you are 1000 km from Yangon,
you can eliminate one of the possibilities, and know exactly
where you are (can you guess where?)
Yangon
Bangkok
KL
125. 3D Trilateration
Generalize the concept to 3D: spheres instead of circles
Imagine you are X miles from satellite A in the sky. You could
be anywhere on the surface of an imaginary sphere with X-km
radius.
126. Second sphere
If you also know you are Y miles from satellite B, you can
overlap the first sphere with this sphere
Two spheres overlap in a circle
127. Third sphere
The third satellite will give a third sphere, which intersects the
circle at two points
128. Fourth sphere
The Earth can act as a fourth sphere, i.e. only one of the two
possible points is on the surface of the planet
However, receivers generally look to four or more satellites to
improve accuracy and provide precise altitude information
129. To make the calculation, GPS receiver needs to know two
things:
The location of at least three satellites
The distance between you and each of the satellites
Idea: determine the time delays when signals travel from
satellites to the receiver
For this to work, clocks on the satellites and the receiver must
be synchronized to nanoseconds
Quite a few techniques involved. Anyway, details are beyond
the scope of this lecture
In this course: how to use GPS in your app!
130. Finding locations
To gain access to location information, both from GPS and
coarse-grained location provider such as cell tower
triangulation, add the following lines to
AndroidManifest.xml
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
Get a LocationManager from your Context
LocationManager mgr
= (LocationManager) getSystemService(LOCATION_SERVICE);
Select the best location provider. A Criteria object can be
used to select a location provider based on e.g. power or
accuracy (in this case, no restrictions).
Criteria criteria = new Criteria();
String best = mgr.getBestProvider(criteria, true);
131. Finding locations (cont)
Query the last known (possibly outdated) location
Location location = mgr.getLastKnownLocation(best);
Edit onResume and onPause to have Android updates
locations only when your app is in the foreground (assume that
your class implements LocationListener)
@Override
protected void onResume() {
super.onResume();
mgr.requestLocationUpdates(best, 15000, 1, this);
}
@Override
protected void onPause() {
super.onPause();
mgr.removeUpdates(this);
}
133. Sensors
Android SDK supports many different types of sensor devices
TYPE_ACCELEROMETER: Measures acceleration in the x-,
y-, and z-axes
TYPE_LIGHT: Tells you how bright your surrounding area
is
TYPE_MAGNETIC_FIELD: Returns magnetic attraction in
the x-, y-, and z-axes
TYPE_ORIENTATION: Measures the yaw, pitch, and roll of
the device
TYPE_PRESSURE: Senses the current atmospheric
pressure
TYPE_PROXIMITY: Provides the distance between the
sensor and some object
TYPE_TEMPERATURE: Measures the temperature of the
surrounding area
134. SensorManager
Similar to LocationManager, here we use SensorManager
SensorManager mgr
= (SensorManager) getSystemService(SENSOR_SERVICE)
Then, call registerListener() in onResume() and
unregisterListener() in onPause() to start/stop getting
updates
The sensor service will call onSensorChanged() every time a
value changes. It should look like this:
public void onSensorChanged(SensorEvent event) {
for (int i = 0; i < event.values.length; i++) {
// ...
}
}
135. Sensor readings
All sensors return an array of floating-point values. The size of
the array depends on the particular sensor.
Turning sensor readings into meaningful information can be
very tricky
Do experiments on what you want!
Most of time it is not possible to test sensor readings on the
emulator. If your application relies heavily on one of these
sensors, you will need to a real device to test
137. SQLite
A tiny but powerful database engine, created by Dr. Richard
Hipp in 2000
Widely used, e.g. in Mozilla Firefox, Skype, PHP, Adobe AIR,
Mac OS X, iPhone, and of course Android
Notable features:
Free
Small, less than 325KB
Require no setup, no server, no config file, no
administration
An SQLite database is just a file
Android stores it in /data/data/packagename/databases
138. SQL refresher
A Data Definition Language (DDL) statement to create a table
create table mytable (
_id integer primary key autoincrement,
name text,
phone text );
Note column types in SQLite are not strict. So, it’s possible to
e.g. store a string in an integer column.
Insert a record
insert into mytable values(null, ’Steven King’ , ’555-1212’ );
Query for a record
select * from mytable where(_id=3);
139. SQLiteOpenHelper
Subclass SQLiteOpenHelper to manage database creation
and versions
public class EventsData extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "events.db";
private static final int DATABASE_VERSION = 1;
public EventsData(Context ctx) {
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + _ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + TIME
+ " INTEGER," + TITLE + " TEXT NOT NULL);" );
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
140. Adding a row
Use getWritableDatabase() to get a read/write handle to
the events database, and then use insertOrThrow() to do
the actual INSERT
private void addEvents(String string) {
SQLiteDatabase db = events.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(TIME, System.currentTimeMillis());
values.put(TITLE, string);
db.insertOrThrow(TABLE_NAME, null, values);
}
141. Running a query
Use getReadableDatabase() to get a read-only handle to
the events database, and then use query() to do the actual
SELECT
private static String[] FROM = _ID, TIME, TITLE, ;
private static String ORDER_BY = TIME + " DESC" ;
private Cursor getEvents() {
SQLiteDatabase db = events.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null,
null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
The method startManagingCursor() tells the activity to
take care of managing the cursor’s life cycle based on the
activity’s life cycle. E.g., deactivate the cursor when the activity
is paused, or close it when the activity is terminated
142. Display the query results
Use Cursor to iterate through all result rows
while (cursor.moveToNext()) {
long id = cursor.getLong(0);
long time = cursor.getLong(1);
String title = cursor.getString(2);
...
}
Alternatively, instead of using 0, 1, or 2 in getXXX(), use
getColumnIndexOrThrow() to get column index numbers
143. Data binding
Android provides a convenient way to display query results:
Create a layout for items, call it e.g. item.xml
Subclass ListActivity and use SimpleCursorAdapter
private static int[] TO = { R.id.rowid, R.id.time, R.id.title };
...
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.item, cursor, FROM, TO);
setListAdapter(adapter);
Define your activity layout main.xml like this
<ListView
android:id="@android:id/list"
... />
<TextView
android:id="@android:id/empty"
... />
If the list has items, android:id/list will be displayed,
otherwise android:id/empty will be displayed
144. Content provider
Recall that one application cannot access data own by another
application
A way to share data is to use ContentProvider:
Processes register themselves to the system as providers of
certain kinds of data. When that information is requested, they
are called by Android through a fixed API to query or modify the
content
145. Content provider (cont)
Any piece of information managed by a ContentProvider is
addressed through a URI that looks like this:
content://authority/path/id
where
authority is the name of the provider, usually the package
name
path is a virtual directory within the provider
id is the primary key of the requested record. Omit this to
request all records.
Android comes with several providers built in, including
content://browser
content://contacts
content://media
content://settings
146. Using ContentProvider
Example of a valid URI:
public static final String AUTHORITY = "org.example.events" ;
public static final Uri CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/" + TABLE_NAME);
Adding a row
getContentResolver().insert(CONTENT_URI, values);
Running a query
Cursor cursor = managedQuery(CONTENT_URI, FROM, null,
null, ORDER_BY);
149. Services
A service is an application component that can perform
operations in the background and does not provide a UI
Another application component can start a service. It will
continue to run in the background, even if the user switches to
another application
Also, a component can bind to a service to interact with it and
even perform interprocess communication (IPC)
Examples: network transactions, play music, perform file I/O
150. Types of services
A service can take two forms:
Started when an application component call startService()
Once started, a service can run indefinitely, even if the
component is destroyed
Usually perform a single operation, does not return a result
Example: download or upload file over the network
When the operation is done, it should stop itself
Bound when an application component call bindService()
Offer a client-server interface that allows components to
interact with the service, send requests, get results, do IPC
Run as long as another component is bound to it
Multiple components can bind to the service at once
151. Types of services (cont.)
A service can be of both types: it can be started to run
indefinitely and also allow binding. Just implement both
onStartCommand() and onBind()
Just like an activity, a service started with an Intent
Caution: a service runs in the main thread of its hosting
processes, it does not create its own thread and does not run in
a separate process
Use a separate thread if your service can be slow
152. The basics
To create a service, subclass Service and override the
following callback methods:
onStartCommand(): the system calls this method when
another component call startService(). The service
will run indefinitely unless stopSelf() or
stopService() is called
onBind(): the system calls this method when another
component call bindService(). You must always
implement this method (simply return null if binding is not
allowed)
onCreate(): the system calls this method when the
service is first created. Use it to perform one-time setup.
onDestroy(): the system calls this method when the
service is being destroyed. Use it to clean up resources.
153. Declaring a service in the manifest
Add a <service> element as a child of the <application>
element
<manifest ... >
...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>
android:name is the only required attribute
To make a service private, set android:exported="false"
Reference:
http://developer.android.com/guide/topics/manifest/service-
element.html
154. IntentService
In most case, you can implement a service using
IntentService, a subclass of Service
It creates a worker thread to handle intents delivered to
onStartCommand(), separate from your main thread
Provides to default implementation of onStartCommand() to
send one intent at a time to onHandleIntent()
Stops the service after all start requests have been handled, so
no need to call stopSelf()
Provides default implementation of onBind() that returns null
All you need to do is implement onHandleIntent()
157. 3D with OpenGL
Android supports high performance 3D graphics with the Open
Graphics Library (OpenGL), specifically, the OpenGL ES API
OpenGL is a cross-platform graphics API that specifies a
standard software interface for 3D graphics processing
hardware
OpenGL ES is a subset of OpenGL, designed for embedded
systems
OpenGL ES 1.0 and 1.1 have been supported since
Android 1.1
Beginning with Android 2.2, OpenGL ES 2.0 is also supported
158. GLSurfaceView
Two foundational classes:
GLSurfaceView: a View you can draw and manipulate
objects through API calls
GLSurfaceView.Renderer: an interface that defines
methods required for drawing graphics in GLSurfaceView.
You must implement this interface, and attach it to
GLSurfaceView by using setRenderer().
159. GLSurfaceView.Renderer
To implement the GLSurfaceView.Renderer interface, the
following methods must be implemented:
onSurfaceCreated(): The system calls this method
once, when creating the GLSurfaceView. Use it to set up
environment or initialize graphic objects.
onDrawFrame(): The system calls this method on each
redraw of the GLSurfaceView. Use it to draw graphic
objects.
onSurfaceChanged(): The system calls this method
when the GLSurfaceView geometry changes, e.g.
screen orientation change
160. Define a triangle
OpenGL allows you to define objects using coordinates in
three-dimensional space
By default, the coordinate (0, 0, 0) is the center of the screen,
(1, 1, 0) is the top right, and (−1, −1, 0) is the bottom left
private void initShapes() {
float triangleCoords[] = { // X, Y, Z
-0.5f, -0.25f, 0, 0.5f, -0.25f, 0, 0.0f, 0.559016994f, 0
};
// initialize vertex Buffer for triangle
ByteBuffer vbb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
vbb.order(ByteOrder.nativeOrder()); // use native byte order
triangleVB = vbb.asFloatBuffer(); // create fp buffer
triangleVB.put(triangleCoords); // add coords to fp buffer
triangleVB.position(0); // set buffer to read 1st coord
}
161. Projection
Problem: OpenGL assumes a square, uniform coordinate
system. Androids monitors usually vary in size and shape.
Solution in OpenGL ES 1.0: create a projection matrix using
the geometry of the device screen
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
// make adjustments for screen ratio
float ratio = (float) width / height;
// set matrix to projection mode
gl.glMatrixMode(GL10.GL_PROJECTION);
// reset the matrix to its default state
gl.glLoadIdentity();
// apply the projection matrix
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
}
164. App Widgets
Introduced in Android 1.5 (Cupcake)
App Widgets are miniature application views embedded in
other applications (such as the Home screen) and received
periodic updates
These views are referred to as widgets
An application that is able to hold App Widgets is called an App
Widget host
Several App Widgets are shipped with Android, e.g. analog
clock, music controller, picture frame
This section is about how to create your own widgets
165. Create an App Widget
Create res/xml/widget.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/main" />
to specify a minimum size of the widget, how often it should be
updated, and a reference to its starting layout
Create a BroadcastReceiver by subclassing
AppWidgetProvider
public class Widget extends AppWidgetProvider {}
166. Create an App Widget (cont.)
Declare the broadcast receiver inside <application> in
AndroidManifest.xml
<receiver android:name=".Widget"
android:label="@string/widget_name">
<intent-filter>
<action
android:name="android.appwidget.action.APPWIDGET_UPDATE"
/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/widget" />
</receiver>
To run, select Run As > Android Application as usual
Widgets can be opened by pressing and holding your finger (or
mouse) on the Home screen
168. Update your widget
Implement onUpdate() to handle APPWIDGET_UPDATE
intent, the action we declared in AndroidManifest.xml
Example:
private SimpleDateFormat formatter = new SimpleDateFormat(
"EEEEEEEEEnd MMM yyyy");
@Override
public void onUpdate(Context context,
AppWidgetManager appWidgetManager, int[] appWidgetIds) {
String now = formatter.format(new Date());
RemoteViews updateViews = new RemoteViews(
context.getPackageName(), R.layout.main);
updateViews.setTextViewText(R.id.text, now);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
169. Explanations & tips
SimpleDateFormat is used to format the current date: day of
the week, day of the month, month name, and year
RemoteViews is used for the new view layout that the widget
will display
In this example, the same layout R.layout.main is used
The update frequency is controlled by
android:updatePeriodMillis in res/xml/widget.xml.
The value 1800000 is 30 minutes.
However, updates requested with updatePeriodMillis will
not be delivered more than once every 30 minutes
For more information, see
http://developer.android.com/guide/topics/appwidgets/index.html
172. Live wallpaper
Introduced in Android 2.1
Live wallpapers are rich, animated, interactive backgrounds on
home screens
Similar to normal app, a live wallpaper has access to all
facilities of the platform: SGL, OpenGL, GPS, accelerometers,
network access, etc
173. Implementing a live wallpaper
Similar to implementing a service, with an additional method
onCreateEngine() to create WallpaperService.Engine
The engine is responsible for handling the lifecycle and drawing
of a wallpaper
Drawing a wall paper can be expensive, so optimize your code
as much as possible
The Home application can send commands to the
onCommands method of your live wallpaper:
android.wallpaper.tap: when the user taps an empty
space on the workspace
android.home.drop: when the user drops an icon or a
widget on the workspace