Ch_Two
Ch_Two
Data Management
editor.putString("chosenColor", "RED");
editor.putInt("chosenNumber", 7 );
editor.commit();
}
123
Cont’d
If you’re targeting devices that run at least API Level 9 (Android 2.3 and
higher), you would benefit from using the apply() method instead of the
commit() method in the preceding code.
However, if you need to support legacy versions of Android, you’ll want
to stick with the commit() method, or check at runtime before calling the
most appropriate method.
Even when you are writing as little as one preference, using apply() could
smooth out the operation because any call to the file system may block for
a noticeable (and therefore unacceptable) length of time.
Cont’d
1) The method getSharedPreferences(…) creates (retrieves) a table called
my_preferred_choices file, using the default MODE_PRIVATE access. Under this
access mode only the calling application can operate on the file.
2) A SharedPreferences editor is needed to make any changes on the file. For
instance editor.putString("chosenColor", "RED") creates(updates) the key
“chosenColor” and assigns to it the value “RED”. All editing actions must be
explicitly committed for the file to be updated.
3) The method getXXX(…) is used to extract a value for a given key. If no key
exists for the supplied name, the method uses the designated default value. For
instance myPrefs.getString("chosenColor", "BLACK") looks into the file
myPrefs for the key “chosenColor” to return its value, however if the key is not
found it returns the default value “BLACK”.
Cont’d
SharedPreference containers are saved as XML files in the application’s internal memory
space. The path to a preference files is
/data/data/packageName/shared_prefs/filename.
If you pull the file from the device, you will see the following
File Storage – Internal and External Storage
In Android, a file-based storage option allows data to be written to an actual file
structure
This storage method requires more control regarding read and write permissions
Internal storage allows data to be stored directly onto the device’s memory
This storage is always available, assuming there is space
External storage may not always be obtainable on a device.
There are significant differences in how external and internal storage is utilized in
an application
Internal storage files can be configured to be readable and writeable by the
application
Typically, internal storage is utilized when processing an image, video and audio
elements, and large data files
By default, files saved to internal storage are private to the application
Cont’d
External storage is publicly shared storage, which means that it can be made
available to external applications
Unlike internal storage, once an application is uninstalled, external storage files
will continue to exist
Cont’d
You don't need any permissions to save files on the internal storage. Your
application always has permission to read and write files in its internal storage
directory.
You can create files in two different directories:
Permanent storage: getFilesDir()
Temporary storage: getCacheDir(). Recommended for small, temporary
files totaling less than 1MB.
Note that the system may delete temporary files if it runs low on memory
To create a new file in one of these directories, you can use the File()
constructor, passing the File provided by one of the above methods that specifies
your internal storage directory. For example:
File file = new File(context.getFilesDir(), filename);
Write a File to Internal Storage
Alternatively, you can call openFileOutput() to get a FileOutputStream that
writes to a file in your internal directory. For example, here's how to write some
text to a file:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Cont’d
MODE_PRIVATE (the default) is used to create a file that can be accessed only
by the “owner” application itself. From a Linux perspective, this means the
specific user identifier.
The constant value of MODE_PRIVATE is 0, so you may see this used in legacy
code.
MODE_APPEND is used to append data to the end of an existing file.
The constant value of MODE_APPEND is 32768.
Up until API Level 17, MODE_WORLD_READABLE and
MODE_WORLD_WRITEABLE constants were viable options for exposing data
to other applications, but they have now been deprecated.
Using these constants in your applications may present security vulnerabilities
when exposing data to other applications.
Read a File from Internal Storage
In order to read from the file you just created , call the openFileInput() method with
the name of the file. It returns an instance of FileInputStream. Its syntax is given
below
FileInputStream fin = openFileInput(file);
int c; String temp="";
while( (c = fin.read()) != -1){
temp = temp + Character.toString((char)c); //string temp
contains all the data of the file.
}
fin.close();
Grant Access to External Storage
To read or write files on the external storage, our app must acquire the
WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE
system permissions.
We need to add following permissions in android manifest file like as shown
below.
Checking External Storage Availability
Before we do any work with external storage, first we need to check whether the
media is available or not by calling getExternalStorageState().
The media might be mounted to a computer, missing, read-only or in some other
state.
To get the media status, we need to write the code like as shown below.
Cont’d
By using getExternalStoragePublicDirectory() method we can access the files
from appropriate public directory by passing the type of directory we want, such as
DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONS, etc.
based on our requirements.
If we save our files to corresponding media-type public directory, the system's media
scanner can properly categorize our files in the system.
Following is the example to create a directory for new photo album in the public
pictures directory.
Write a File to External Storage
In case, if we are handling the files that are not intended for other apps to use, then
we should use a private storage directory on the external storage by calling
getExternalFilesDir().
By using android FileOutputStream object and
getExternalStoragePublicDirectory method, we can easily create and write a
data to the file in external storage public folders.
Following is the code snippet to create and write a public file in device Downloads
folder.
Read a File from External Storage
By using android FileInputStream object and
getExternalStoragePublicDirectory method, we can easily read the
file from external storage.
Following is the code snippet to read a data from file which is in
downloads folder.
Android Database with SQLite
SQLite provides the foundation for managing private and embedded databases in
an Android application
The Android SDK includes the SQLite software library that implements the SQL
(Structured Query Language) database engine
This library is used for defining the database structure and adding and managing
the database content as required by the application
The Android SDK also includes an SQLite database tool for explicit database
debugging purposes
As a condensed version of SQL, SQLite supports the standard SQL syntax and
database transactions
Though SQLite is not a full-featured database, it supports a large set of the SQL
standard and is sufficient for Android developers needing a simple database
engine to plug into their applications
Cont’d
An SQLite database file is a collection of data organized in a table
The SQLite database table is structured by a set of rows and columns
A row represents a single record, the implicitly structured data entry in the
table
A column represents a data field, an attribute of a data record
A field is a single item that exists at the intersection between one row and
one column
The possible data types for an individual field of data consist of NULL, INTEGER,
REAL,TEXT, and BLOB
BLOB is a data type used to store a large array of binary data (bytes)
SQLite does not provide specific data storage classes for values that need to be
represented as Boolean, date, or time
Instead, these values can be stored as an INTEGER or TEXT
An outline for a students database table schema
SQLiteOpenHelper
The Android SDK provides a set of classes for working with SQLite
databases
SQLiteOpenHelper is essential for the creation and management of
database content, as well as database versioning
In an Android SQLite application, SQLiteOpenHelper must be subclassed
It must contain the implementation of onCreate() and onUpgrade()
Create Database and Tables using SQLite Helper
By using SQLiteOpenHelper class we can easily create required
database and tables for our application.
To use SQLiteOpenHelper, we need to create a subclass that overrides
the onCreate() and onUpgrade() call-back methods.
Insert Data into SQLite Database
In android, we can insert data into SQLite database by passing
ContentValues to insert() method.
Cont’d
long insert(String table, String nullColumnHack, ContentValues values)
String table:
name of the table on which to perform the insert operation
name needs to be the same as the name given to the table when it was
created.
String nullColumnHack:
Specifies a column that will be set to null if the ContentValues argument
contains no data.
ContentValues values:
Contains the data that will be inserted into the table
Content Values
An instance of ContentValues stores data as key-value pairs, where
key is the name of the column and
value is the value for the cell
One instance of ContentValues represents one row of a table.
The insert() method for the database requires that the values to fill a row are
passed as an instance of ContentValues.
ContentValues values = new ContentValues();
// Insert one row. Use a loop to insert multiple rows.
values.put(KEY_WORD, "Android");
values.put(KEY_DEFINITION, "Mobile operating system.");
db.insert(WORD_LIST_TABLE, null, values);
Read the Data from SQLite Database
we can read the data from SQLite database using query()
Cursor
The SQLiteDatabase always presents the results as a Cursor in a table format that
resembles that of a SQL database
You can think of the data as an array of rows. A cursor is a pointer into one row of that
structured data
The Cursor class provides methods for moving the cursor through the data structure,
and methods to get the data from the fields in each row
Some common operations on cursor are:
getCount() returns the number of rows in the cursor
getColumnNames() returns a string array holding the names of all of the columns in
the result set in the order in which they were listed in the result
getPosition() returns the current position of the cursor in the row set
Getters are available for specific data types, such as getString(int column) and
getInt(int column).
Operations such as moveToFirst(), moveToLast() and moveToNext() move the cursor
close() releases all resources and makes the cursor completely invalid. Remember to
call close() to free resources!
Cont’d
The Cursor class has a number of subclasses that implement cursors for specific
types of data.
SQLiteCursor
MatrixCursor
// Perform a query and store the result in a Cursor
Cursor cursor = db.rawQuery(...);
try {
while (cursor.moveToNext()) {
Intents
Services
Service Lifecycle
Foreground Service
Providers
Receivers
Application context
Application Components
Are the essential building blocks of an Android application.
Are loosely coupled by the application manifest file AndroidManifest.xml that describes each
4 Main Components
Additional Components
There are additional components which will be used in the construction of above
interact.
An application typically has multiple activities, and the user flips back and forth among
them.
Intents are messages that are sent among the major building blocks.
They trigger an activity to start up, tell a service to start, stop, or bind to, or
Intents are asynchronous, meaning the code that sends them doesn’t have to
Explicit intents
You can also define your own action strings for activating the components in your
application.
The action largely determines how the rest of the intent is structured particularly
the data and extras fields - much as a method name determines a set of arguments
and a return value.
Intent Actions
Data Field
The URI of the data to be acted on and the MIME (Multipurpose Internet Mail
Extensions) type of that data.
Different actions are paired with different kinds of data specifications.
If the action field is ACTION_EDIT, the data field would contain the URI of the
document to be displayed for editing.
If the action is ACTION_CALL, the data field would be a tel: URI with the number to
call.
If the action is ACTION_VIEW and the data field is an http: URI, the receiving activity
would be called upon to download and display whatever data the URI refers to.
Examples of Action/Data Pairs
Example of Activity Actions
Starting Activity:
Launch new activity (without receiving a result)
void startActivity (Intent intent)
The Android system populates the application launcher by finding all the activities
with intent filters that specify the “android.intent.action.MAIN” action and
“android.intent.category.LAUNCHER” category. It then displays the icons and
labels of those activities in the launcher.
Example - Explicit Intent
For example, if you built a service in your app, named DownloadService,
designed to download a file from the web, you can start it with the following
code:
Example - Implicit Intent
For example, if you have content you want the user to share with other people,
create an intent with the ACTION_SEND action and add extras that specify the
content to share. When you call startActivity() with that intent, the user can pick
an app through which to share the content.
Explicit Intent example
Implicit Intent example
Cont’d
Resources
When the application is compiled, Android generates the R class, which contains
resource IDs for all the resources in your res/ directory.
For each type of resource, there is an R subclass (e.g., R.drawable for all
drawable resources). For each resource of that type, there is a static integer
(e.g., R.drawable.icon).
A resource ID is always composed of:
The resource type: Examples: string, drawable, and layout.
The resource name: Either: the filename, excluding the extension; or the value
in the XML android:name attribute, if the resource is a simple value (such as
a string).
Accessing a resource:
In code: Using a static integer from a sub-class of your R class, such as:
R.string.hello
In XML: Using a special XML syntax that also corresponds to the resource ID
defined in your R class, such as: @string/hello
Services
Services run in the background and don’t have any user interface
components.
They can perform the same actions as activities, but without any user
interface.
Services are useful for actions that you want to perform for a while,
regardless of what is on the screen.
Faceless components that typically run in the background
Music player, network download ,etc.
Services have a much simpler life cycle than activities (see figure below).
You either start a service or stop it. Also, the service life cycle is more or
less controlled by the developer, and not so much by the system.
Consequently, developers have to be mindful to run services so that they
don’t consume shared resources unnecessarily, such as the CPU and
battery.
Service lifecycle
Cont’d
Just because a service runs in the background doesn’t necessarily mean it
runs on a separate thread.
By default, services and activities run on the same main application
thread, often called the UI thread.
If a service is doing some processing that takes a while to complete (such
as performing network calls), you would typically invoke a separate
thread to run it. Otherwise, your user interface will run noticeably
slower.
Cont’d
Steps to creating a service are:
1. Create the Java class representing your service.
2. Register the service in the AndroidManifest.xml file.
3. Start the service.
public class RefreshService extends Service {…}
onStartCommand()
Called each time the service is started
onDestroy()
Called when the service is terminated
To do that, you can use the Eclipse or Android Studio tool
Source→Override/Implement Methods and select those three methods.
Service example
Content Providers
Content providers are interfaces for sharing data between applications
Enables sharing of data across applications
Address book, photo gallery, etc.
Provides API for CRUD operations
The methods that content providers use to implement the four critical
operations are
Example
Figure: Contacts application using the Content
Figure: Content provider Provider to get the data
Broadcast Receivers
Components designed to respond to broadcast messages called Intents
Can receive broadcast messages from the system. For example when
A new phone call comes in
There is change in battery level or cell ID
Can receive messages broadcast by Applications
Apps can also define new broadcast Messages
The receiver is simply dormant code that gets activated by the occurrence of an
event to which the receiver is subscribed.
The “event” takes the form of an intent.
The system itself broadcasts events all the time. For example, when an SMS arrives,
a call comes in, the battery runs low, or the system completes booting up, all those
events are broadcast, and any number of receivers could be triggered by them.
Broadcast receivers themselves do not have any visual representation, nor are they
actively running in memory.
But when triggered, they get to execute some code, such as starting an activity, a
service, or something else.
Cont’d
That action is in the form of an intent broadcast.
When the right intent is fired, the receiver wakes up and executes.
The “wakeup” happens in the form of an onReceive() callback method.
Application Context
So far you have seen activities, services, content providers, and broadcast
receivers. Together, they make up an application. They are the basic building
blocks, loosely coupled, of an Android app.
Think of an application in Android as a container to hold together your blocks.
Your activities, services, providers, and receivers do the actual work.
The container that they work in is the shared Linux process with common Dalvik
VM, private file system, shared resources, and similar things.
To use our website analogy, an app would be the website domain.
Users never really go to Amazon.com (the domain), but rather visit a web page
(which you could compare to an Android activity) within that domain, or
consume a web service (an Android service). So web pages and web services are
building blocks for a website, and the website itself is just a container to hold
them all together under one roof.
This is very similar to what an Android application does for its components.
Cont’d
Cont’d
The application context is uniquely identified on a device based on the package name of that
There cannot be another app with the same package name (unless it comes from us, and we
or Activity.getApplication().
Keep in mind that activities and services are already subclasses of the context, and therefore
Activities and Services are also subclasses of the Context class, which is different from the