Search This Blog

Thursday 29 March 2012

Android Debug Bridge (ADB)


Android Debug Bridge




he Android Debug Bridge (ADB) is a tool kit for Android developers, available for Windows, Linux, and Mac OS X. Found as part of the Android SDK Platform-tools package, it consists of both client and server-side programs[1] that communicate with one another. The ADB is typically accessed through the command-line interface.



A command-line interface (CLI) is an interface or dialog between the user and a program, or between two programs, where a line of text (a command line) is passed between the two. Many graphical interfaces, such as the OS/2 Presentation Manager and the various Windows shell use command-lines to call helper programs to open documents and programs. The commands are stored in the graphical shell or in files like the registry or the OS/2 os2user.ini file.
Command-line interfaces replaced point-and-load menus (Basic, MS-DOS Executive in Windows 2.x) and externally loaded programs (such as punched cards and game cartrages), when computers became sufficiently powerful to handle parsing of user input, and keep several programs in a runnable condition. This happened at the conversion to 16-bit computers, although text-menus continued to be supplied with computers well after this time.

Android Debug Bridge



ADB quickview

  • Manage the state of an emulator or device
  • Run shell commands on a device
  • Manage port forwarding on an emulator or device
  • Copy files to/from an emulator or device

  1. Emulator
Android Debug Bridge (adb) is a versatile command line tool that lets you communicate with an emulator instance or connected Android-powered device. It is a client-server program that includes three components:
  • A client, which runs on your development machine. You can invoke a client from a shell by issuing an adb command. Other Android tools such as the ADT plugin and DDMS also create adb clients.
  • A server, which runs as a background process on your development machine. The server manages communication between the client and the adb daemon running on an emulator or device.
  • A daemon, which runs as a background process on each emulator or device instance.
You can find the adb tool in <sdk>/platform-tools/.
When you start an adb client, the client first checks whether there is an adb server process already running. If there isn't, it starts the server process. When the server starts, it binds to local TCP port 5037 and listens for commands sent from adb clients—all adb clients use port 5037 to communicate with the adb server.
The server then sets up connections to all running emulator/device instances. It locates emulator/device instances by scanning odd-numbered ports in the range 5555 to 5585, the range used by emulators/devices. Where the server finds an adb daemon, it sets up a connection to that port. Note that each emulator/device instance acquires a pair of sequential ports — an even-numbered port for console connections and an odd-numbered port for adb connections. For example:
Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557 ...
As shown, the emulator instance connected to adb on port 5555 is the same as the instance whose console listens on port 5554.
Once the server has set up connections to all emulator instances, you can use adb commands to control and access those instances. Because the server manages connections to emulator/device instances and handles commands from multiple adb clients, you can control any emulator/device instance from any client (or from a script).
The sections below describe the commands that you can use to access adb capabilities and manage the state of an emulator/device. Note that if you are developing Android applications in Eclipse and have installed the ADT plugin, you do not need to access adb from the command line. The ADT plugin provides a transparent integration of adb into the Eclipse IDE. However, you can still use adb directly as necessary, such as for debugging.

Issuing adb Commands

You can issue adb commands from a command line on your development machine or from a script. The usage is:
adb [-d|-e|-s <serialNumber>] <command> 
When you issue a command, the program invokes an adb client. The client is not specifically associated with any emulator instance, so if multiple emulators/devices are running, you need to use the -d option to specify the target instance to which the command should be directed. For more information about using this option, see Directing Commands to a Specific Emulator/Device Instance.

Querying for Emulator/Device Instances

Before issuing adb commands, it is helpful to know what emulator/device instances are connected to the adb server. You can generate a list of attached emulators/devices using the devices command:
adb devices
In response, adb prints this status information for each instance:
  • Serial number — A string created by adb to uniquely identify an emulator/device instance by its console port number. The format of the serial number is <type>-<consolePort>. Here's an example serial number: emulator-5554
  • State — The connection state of the instance. Three states are supported:
    • offline — the instance is not connected to adb or is not responding.
    • device — the instance is now connected to the adb server. Note that this state does not imply that the Android system is fully booted and operational, since the instance connects to adb while the system is still booting. However, after boot-up, this is the normal operational state of an emulator/device instance.
The output for each instance is formatted like this:
[serialNumber] [state]
Here's an example showing the devices command and its output:
$ adb devices
List of devices attached 
emulator-5554  device
emulator-5556  device
emulator-5558  device
If there is no emulator/device running, adb returns no device.

Directing Commands to a Specific Emulator/Device Instance

If multiple emulator/device instances are running, you need to specify a target instance when issuing adb commands. To so so, use the -s option in the commands. The usage for the -s option is:
adb -s <serialNumber> <command> 
As shown, you specify the target instance for a command using its adb-assigned serial number. You can use the devices command to obtain the serial numbers of running emulator/device instances.
Here is an example:
adb -s emulator-5556 install helloWorld.apk
Note that, if you issue a command without specifying a target emulator/device instance using -s, adb generates an error.

Installing an Application

You can use adb to copy an application from your development computer and install it on an emulator/device instance. To do so, use the install command. With the command, you must specify the path to the .apk file that you want to install:
adb install <path_to_apk>
For more information about how to create an .apk file that you can install on an emulator/device instance, see Building and Running
Note that, if you are using the Eclipse IDE and have the ADT plugin installed, you do not need to use adb (or aapt) directly to install your application on the emulator/device. Instead, the ADT plugin handles the packaging and installation of the application for you.

Forwarding Ports

You can use the forward command to set up arbitrary port forwarding — forwarding of requests on a specific host port to a different port on an emulator/device instance. Here's how you would set up forwarding of host port 6100 to emulator/device port 7100:
adb forward tcp:6100 tcp:7100
You can also use adb to set up forwarding to named abstract UNIX domain sockets, as illustrated here:
adb forward tcp:6100 local:logd 

Copying Files to or from an Emulator/Device Instance

You can use the adb commands pull and push to copy files to and from an emulator/device instance's data file. Unlike the install command, which only copies an .apk file to a specific location, the pull and push commands let you copy arbitrary directories and files to any location in an emulator/device instance.
To copy a file or directory (recursively) from the emulator or device, use
adb pull <remote> <local>
To copy a file or directory (recursively) to the emulator or device, use
adb push <local> <remote>
In the commands, <local> and <remote> refer to the paths to the target files/directory on your development machine (local) and on the emulator/device instance (remote).
Here's an example:
adb push foo.txt /sdcard/foo.txt

Listing of adb Commands

The table below lists all of the supported adb commands and explains their meaning and usage.
Category Command Description Comments
Options -d Direct an adb command to the only attached USB device. Returns an error if more than one USB device is attached.
-e Direct an adb command to the only running emulator instance. Returns an error if more than one emulator instance is running.
-s <serialNumber> Direct an adb command a specific emulator/device instance, referred to by its adb-assigned serial number (such as "emulator-5556"). If not specified, adb generates an error.
General devices Prints a list of all attached emulator/device instances. See Querying for Emulator/Device Instances for more information.
help Prints a list of supported adb commands.
version Prints the adb version number.
Debug logcat [<option>] [<filter-specs>] Prints log data to the screen.
bugreport Prints dumpsys, dumpstate, and logcat data to the screen, for the purposes of bug reporting.
jdwp Prints a list of available JDWP processes on a given device. You can use the forward jdwp:<pid> port-forwarding specification to connect to a specific JDWP process. For example:
adb forward tcp:8000 jdwp:472
jdb -attach localhost:8000
Data install <path-to-apk> Pushes an Android application (specified as a full path to an .apk file) to the data file of an emulator/device.
pull <remote> <local> Copies a specified file from an emulator/device instance to your development computer.
push <local> <remote> Copies a specified file from your development computer to an emulator/device instance.
Ports and Networking forward <local> <remote> Forwards socket connections from a specified local port to a specified remote port on the emulator/device instance.
Port specifications can use these schemes:
  • tcp:<portnum>
  • local:<UNIX domain socket name>
  • dev:<character device name>
  • jdwp:<pid>
ppp <tty> [parm]...
Run PPP over USB.
  • <tty> — the tty for PPP stream. For example dev:/dev/omap_csmi_ttyl.
  • [parm]... — zero or more PPP/PPPD options, such as defaultroute, local, notty, etc.
Note that you should not automatically start a PPP connection.
Scripting get-serialno Prints the adb instance serial number string. See Querying for Emulator/Device Instances for more information.
get-state Prints the adb state of an emulator/device instance.
wait-for-device Blocks execution until the device is online — that is, until the instance state is device.
You can prepend this command to other adb commands, in which case adb will wait until the emulator/device instance is connected before issuing the other commands. Here's an example:
adb wait-for-device shell getprop
Note that this command does not cause adb to wait until the entire system is fully booted. For that reason, you should not prepend it to other commands that require a fully booted system. As an example, the install requires the Android package manager, which is available only after the system is fully booted. A command such as
adb wait-for-device install <app>.apk
would issue the install command as soon as the emulator or device instance connected to the adb server, but before the Android system was fully booted, so it would result in an error.
Server start-server Checks whether the adb server process is running and starts it, if not.
kill-server Terminates the adb server process.
Shell shell Starts a remote shell in the target emulator/device instance. See Issuing Shell Commands for more information.
shell [<shellCommand>] Issues a shell command in the target emulator/device instance and then exits the remote shell.

Issuing Shell Commands

Adb provides an ash shell that you can use to run a variety of commands on an emulator or device. The command binaries are stored in the file system of the emulator or device, in this location:
/system/bin/...
You can use the shell command to issue commands, with or without entering the adb remote shell on the emulator/device.
To issue a single command without entering a remote shell, use the shell command like this:
adb [-d|-e|-s {<serialNumber>}] shell <shellCommand>
To drop into a remote shell on a emulator/device instance, use the shell command like this:
adb [-d|-e|-s {<serialNumber>}] shell
When you are ready to exit the remote shell, use CTRL+D or exit to end the shell session.
The sections below provide more information about shell commands that you can use.

Examining sqlite3 Databases from a Remote Shell

From an adb remote shell, you can use the sqlite3 command-line program to manage SQLite databases created by Android applications. The sqlite3 tool includes many useful commands, such as .dump to print out the contents of a table and .schema to print the SQL CREATE statement for an existing table. The tool also gives you the ability to execute SQLite commands on the fly.
To use sqlite3, enter a remote shell on the emulator instance, as described above, then invoke the tool using the sqlite3 command. Optionally, when invoking sqlite3 you can specify the full path to the database you want to explore. Emulator/device instances store SQLite3 databases in the folder /data/data/<package_name>/databases/.
Here's an example:
$ adb -s emulator-5554 shell
# sqlite3 /data/data/com.example.google.rss.rssexample/databases/rssitems.db
SQLite version 3.3.12
Enter ".help" for instructions
.... enter commands, then quit...
sqlite> .exit 
Once you've invoked sqlite3, you can issue sqlite3 commands in the shell. To exit and return to the adb remote shell, use exit or CTRL+D.

UI/Application Exerciser Monkey

The Monkey is a program that runs on your emulator or device and generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner.
The simplest way to use the monkey is with the following command, which will launch your application and send 500 pseudo-random events to it.
$ adb shell monkey -v -p your.package.name 500
For more information about command options for Monkey, see the complete UI/Application Exerciser Monkey documentation page.

Other Shell Commands

The table below lists several of the adb shell commands available. For a complete list of commands and programs, start an emulator instance and use the adb -help command.
adb shell ls /system/bin
Help is available for most of the commands.
Shell Command Description Comments
dumpsys Dumps system data to the screen. The Dalvik Debug Monitor Server (DDMS) tool offers integrated debug environment that you may find easier to use.
dumpstate Dumps state to a file.
logcat [<option>]... [<filter-spec>]... Enables radio logging and prints output to the screen.
dmesg Prints kernel debugging messages to the screen.
start Starts (restarts) an emulator/device instance.
stop Stops execution of an emulator/device instance.

Enabling logcat Logging

The Android logging system provides a mechanism for collecting and viewing system debug output. Logs from various applications and portions of the system are collected in a series of circular buffers, which then can be viewed and filtered by the logcat command.

Using logcat Commands

You can use the logcat command to view and follow the contents of the system's log buffers. The general usage is:
[adb] logcat [<option>] ... [<filter-spec>] ...
The sections below explain filter specifications and the command options. See Listing of logcat Command Options for a summary of options.
You can use the logcat command from your development computer or from a remote adb shell in an emulator/device instance. To view log output in your development computer, you use
$ adb logcat
and from a remote adb shell you use
# logcat

Filtering Log Output

Every Android log message has a tag and a priority associated with it.
  • The tag of a log message is a short string indicating the system component from which the message originates (for example, "View" for the view system).
  • The priority is one of the following character values, ordered from lowest to highest priority:
    • V — Verbose (lowest priority)
    • D — Debug
    • I — Info (default priority)
    • W — Warning
    • E — Error
    • F — Fatal
    • S — Silent (highest priority, on which nothing is ever printed)
You can obtain a list of tags used in the system, together with priorities, by running logcat and observing the first two columns of each message, given as <priority>/<tag>.
Here's an example of logcat output that shows that the message relates to priority level "I" and tag "ActivityManager":
I/ActivityManager(  585): Starting activity: Intent { action=android.intent.action...}
To reduce the log output to a manageable level, you can restrict log output using filter expressions. Filter expressions let you indicate to the system the tags-priority combinations that you are interested in — the system suppresses other messages for the specified tags.
A filter expression follows this format tag:priority ..., where tag indicates the tag of interest and priority indicates the minimum level of priority to report for that tag. Messages for that tag at or above the specified priority are written to the log. You can supply any number of tag:priority specifications in a single filter expression. The series of specifications is whitespace-delimited. The default output is to show all log messages with the Info priority (*:I).
Here's an example of a filter expression that suppresses all log messages except those with the tag "ActivityManager", at priority "Info" or above, and all log messages with tag "MyApp", with priority "Debug" or above:
adb logcat ActivityManager:I MyApp:D *:S
The final element in the above expression, *:S, sets the priority level for all tags to "silent", thus ensuring only log messages with "View" and "MyApp" are displayed. Using *:S is an excellent way to ensure that log output is restricted to the filters that you have explicitly specified — it lets your filters serve as a "whitelist" for log output.
The following filter expression displays all log messages with priority level "warning" and higher, on all tags:
adb logcat *:W
If you're running logcat from your development computer (versus running it on a remote adb shell), you can also set a default filter expression by exporting a value for the environment variable ANDROID_LOG_TAGS:
export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"
Note that ANDROID_LOG_TAGS filter is not exported to the emulator/device instance, if you are running logcat from a remote shell or using adb shell logcat.

Controlling Log Output Format

Log messages contain a number of metadata fields, in addition to the tag and priority. You can modify the output format for messages so that they display a specific metadata field. To do so, you use the -v option and specify one of the supported output formats listed below.
  • brief — Display priority/tag and the PID of process issuing the message (the default format).
  • process — Display PID only.
  • tag — Display the priority/tag only.
  • raw — Display the raw log message, with no other metadata fields.
  • time — Display the date, invocation time, priority/tag, and PID of the process issuing the message.
  • threadtime — Display the date, invocation time, priority, tag, and the PID and TID of the thread issuing the message.
  • long — Display all metadata fields and separate messages with a blank lines.
When starting logcat, you can specify the output format you want by using the -v option:
[adb] logcat [-v <format>]
Here's an example that shows how to generate messages in thread output format:
adb logcat -v thread
Note that you can only specify one output format with the -v option.

Viewing Alternative Log Buffers

The Android logging system keeps multiple circular buffers for log messages, and not all of the log messages are sent to the default circular buffer. To see additional log messages, you can start logcat with the -b option, to request viewing of an alternate circular buffer. You can view any of these alternate buffers:
  • radio — View the buffer that contains radio/telephony related messages.
  • events — View the buffer containing events-related messages.
  • main — View the main log buffer (default)
The usage of the -b option is:
[adb] logcat [-b <buffer>]
Here's an example of how to view a log buffer containing radio and telephony messages:
adb logcat -b radio

Viewing stdout and stderr

By default, the Android system sends stdout and stderr (System.out and System.err) output to /dev/null. In processes that run the Dalvik VM, you can have the system write a copy of the output to the log file. In this case, the system writes the messages to the log using the log tags stdout and stderr, both with priority I.
To route the output in this way, you stop a running emulator/device instance and then use the shell command setprop to enable the redirection of output. Here's how you do it:
$ adb shell stop
$ adb shell setprop log.redirect-stdio true
$ adb shell start
The system retains this setting until you terminate the emulator/device instance. To use the setting as a default on the emulator/device instance, you can add an entry to /data/local.prop on the device.

Listing of logcat Command Options

Option Description
-b <buffer> Loads an alternate log buffer for viewing, such as event or radio. The main buffer is used by default. See Viewing Alternative Log Buffers.
-c Clears (flushes) the entire log and exits.
-d Dumps the log to the screen and exits.
-f <filename> Writes log message output to <filename>. The default is stdout.
-g Prints the size of the specified log buffer and exits.
-n <count> Sets the maximum number of rotated logs to <count>. The default value is 4. Requires the -r option.
-r <kbytes> Rotates the log file every <kbytes> of output. The default value is 16. Requires the -f option.
-s Sets the default filter spec to silent.
-v <format> Sets the output format for log messages. The default is brief format. For a list of supported formats, see Controlling Log Output Format.

Stopping the adb Server

In some cases, you might need to terminate the adb server process and then restart it. For example, if adb does not respond to a command, you can terminate the server and restart it and that may resolve the problem.
To stop the adb server, use the kill-server. You can then restart the server by issuing any adb command.


http://forum.xda-developers.com/showthread.php?t=1474956

Wednesday 28 March 2012

Lita ? and How to access a Android database by using a command line


What is Lita ?
Lita is an administration interface for SQLite databases. It lets you edit your databases structure and data in a dedicated environment.
Lita is a free and open source SQLite database administration tool for Windows, MacOSX and Linux.
Important It is strongly recommended to make backups of your databases on a regular basis. Always assume that Lita can break your database

What is Adobe AIR?

The Adobe® AIR® runtime enables developers to deploy standalone applications built with HTML, JavaScript, ActionScript®, Flex, Adobe Flash® Professional, and Adobe Flash Builder® across platforms and devices — including Android™, BlackBerry®, iOS devices, personal computers, and televisions.
Can I use Lita with non-AIR SQLite databases ?
While most of its features are compatible with any sqlite database, it was primarily designed to administrate AIR application databases. Some field types and features, such as encryption, are AIR only.

Examining sqlite3 Databases from a Remote Shell

From an adb remote shell, you can use the sqlite3 command-line program to manage SQLite databases created by Android applications. The sqlite3 tool includes many useful commands, such as .dump to print out the contents of a table and .schema to print the SQL CREATE statement for an existing table. The tool also gives you the ability to execute SQLite commands on the fly.
To use sqlite3, enter a remote shell on the emulator instance, as described above, then invoke the tool using the sqlite3 command. Optionally, when invoking sqlite3 you can specify the full path to the database you want to explore. Emulator/device instances store SQLite3 databases in the folder /data/data/<package_name>/databases/.
Here's an example:
$ adb -s emulator-5554 shell
# sqlite3 /data/data/com.example.google.rss.rssexample/databases/rssitems.db
SQLite version 3.3.12
Enter ".help" for instructions
.... enter commands, then quit...
sqlite> .exit 
Once you've invoked sqlite3, you can issue sqlite3 commands in the shell. To exit and return to the adb remote shell, use exit or CTRL+D.

Tutorial : How to access a Android database by using a command line.

When your start dealing with a database in your program, it is really important and useful to be able to access it directly, outside your program, to check what the program has just done, and to debug.

And it is important also on Android.

Here is how to do that :

1) Launch the emulator (or connect your real device to your PC ). I usually launch one of my program from Eclipse for this.
2) Launch a command prompt in the android tools directory.
3) type adb shell.
This will launch an unix shell on your emulator / connected device.
4) go to the directory where your database is :
cd data/data
here you have the list of all the applications on your device
Go in your application directory ( beware, Unix is case sensitive !! )
cd com.alocaly.LetterGame
and descend in your databases directory :
cd databases
Here you can find all your databases. In my case, there is only one ( now ) : SCORE_DB
5) Launch sqlite on the database you want to check / change :
sqlite3 SCORE_DB
From here, you can check what tables are present :
.tables
6) enter any SQL instruction you want :
select * from Score;

DOS and Linux Command for checking databaase and table
comments


->cd Desktop //the place were your program is present
->cd android_sdk_Linux_x86
->cd platform_tools
->./adb
->./adb -s emulator-5554 shell //name of the emulator
->#sqlite3 /data /data/mina.android Database Demo/databases/demoDB
->.table

//to ilist table
-> select * from tablename;

------------------------------------------------------------------------------------------------------------------------

http://androidblogger.blogspot.in/2009/06/tutorial-how-to-access-android-database.html

Tuesday 27 March 2012

Chapter 28:Accessing Data With Android Cursors- Transactions


Accessing Data With Android Cursors

Transactions

SQLite also supports transactions when you need to perform a series of queries that either all complete or all fail. When a SQLite transaction fails an exception will be thrown. The transaction methods are all part of the database object. Start a transaction by calling the beginTransaction() method. Perform the queries and then call the setTransactionSuccessful() when you wish to commit the transaction. Once the transaction is complete call the endTransaction() function.
         db.beginTransaction();
         Cursor cur = null;
         try {
                cur = db.query("tbl_countries", 
                        null, null, null, null, null, null);
                cur.moveToPosition(0);
                ContentValues values = new ContentValues();
                values.put("state_name", "Georgia");
                values.put("country_id", cur.getString(0));
                long stateId = db.insert("tbl_states", null, values);
                db.setTransactionSuccessful();
                view.append("n" + Long.toString(stateId));
         } catch (Exception e) {
                Log.e("Error in transaction", e.toString());
         } finally {
                db.endTransaction();
                cur.close();
         }



Start off with a call to beginTransaction() to tell SQLite to perform the queries in transaction mode. Initiate a try/catch block to handle exceptions thrown by a transaction failure. Perform the queries and then call setTransactionSuccessful() to tell SQLite that our transaction is complete. If an error isn't thrown then endTransaction() can be called to commit the transaction. Finally close the cursor when we're finished with it.

Built in android databases

The Android Operating-System provides several built-in databases to store and manage core phone application data. Before external applications may access some of these data sources access must be granted in the AndroidManifest.xml file in the root of the project. Some of the data applications can access are the bookmarks, media player data, call log, and contact data. Contact data not covered due to changes in the API between 1.x and 2.0 version of Android. See the Android Working With Contacts Tutorial. Android provides built in variables to make working with the internal SQLite databases easy.

Access permissions

Before a program accesses any of the internal Android databases the application must be granted access. This access is granted in the AndroidManifest.xml file. Before the application is installed from the market the user will be prompted to allow the program to access this data.
        <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
        <uses-permission android:name="com.android.broswer.permission.WRITE_HISTORY_BOOKMARKS" />
        <uses-permission android:name="android.permission.READ_CONTACTS" />
These are some sample uses-permission statements to grant access to internal Android databases. These are normally placed below the uses-sdk statement in the AndroidManifest.xml file. The first 2 grant read and write access to the browser history and bookmarks. The third grants read access to the contacts. We'll need to grant READ access to the bookmarks and contacts for the rest of the code samples to work.

Managed Query

Managed queries delegate control of the Cursor to the parent activity automatically. This is handy as it allows the activity to control when to destroy and recreate the Cursor as the application changes state.
package higherpass.TestingData;

import android.app.Activity;
import android.os.Bundle;
import android.provider.Browser;
import android.widget.TextView;
import android.database.Cursor;

public class TestingData extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView view = (TextView) findViewById(R.id.hello);
        Cursor mCur = managedQuery(android.provider.Browser.BOOKMARKS_URI,
                        null, null, null, null
                        );
        mCur.moveToFirst();
        int index = mCur.getColumnIndex(Browser.BookmarkColumns.TITLE);
        while (mCur.isAfterLast() == false) {
                view.append("n" + mCur.getString(index));
                mCur.moveToNext();
        }
      
    }
}



The managed query functions very similar to the query function we used before. When accessing Android built in databases you should reference them by calling the associated SDK variable containing the correct database URI. In this case the browser bookmarks are being accessed by pointing the managedQuery() statement at android.provider.Browser.BOOKMARKS_URI. We left the rest of the parameters null to pull all results from the table. Then we iterate through the cursor records. Each time through the loop we append the title of the bookmark to the TextView element. If you know the name of a column, but not it's index in the results use the getColumnIndex() method to get the correct index. To get the value of a field use the getString() method passing the index of the field to return.

Bookmarks

The first Android database we're going to explore is the browser bookmarks. When accessing the internal Android databases use the managedQuery() method. Android includes some helper variables in Browser.BookmarkColumns to designate column names. They are Browser.BookmarkColumns.TITLE, BOOKMARK, FAVICON, CREATED, URL, DATE, VISITS. These contain the table column names for the bookmarks SQLite table.
package higherpass.TestingData;

import android.app.Activity;
import android.os.Bundle;
import android.provider.Browser;
import android.widget.TextView;
import android.database.Cursor;

public class TestingData extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView view = (TextView) findViewById(R.id.hello);
        String[] projection = new String[] {
                Browser.BookmarkColumns.TITLE
                , Browser.BookmarkColumns.URL
        };
        Cursor mCur = managedQuery(android.provider.Browser.BOOKMARKS_URI,
                projection, null, null, null
                );
        mCur.moveToFirst();
        int titleIdx = mCur.getColumnIndex(Browser.BookmarkColumns.TITLE);
        int urlIdx = mCur.getColumnIndex(Browser.BookmarkColumns.URL);
        while (mCur.isAfterLast() == false) {
                view.append("n" + mCur.getString(titleIdx));
                view.append("n" + mCur.getString(urlIdx));
                mCur.moveToNext();
        }
      
    }
}



Chapter 27:Using the Contacts API


Reading and updating Contacts


Using the Contacts API

Starting from Android 2.0 (API Level 5), the Android platform provides an improved Contacts API for managing and integrating contacts from multiple accounts and from other data sources. To handle overlapping data from multiple sources, the contacts content provider aggregates similar contacts and presents them to users as a single entity. This article describes how to use the new API to manage contacts.
The new Contacts API is defined in the android.provider.ContactsContract and related classes. The older API is still supported, although deprecated. If you have an existing application that uses the older API, see Considerations for legacy apps, below, for ideas on how to support the Contacts API in your app.
If you'd like to look at an applied example of how to use the new Contacts API, including how to support both the new and older API in a single app, please see the Business Card sample application.

Data structure of Contacts

In the new Contacts API, data is laid out in three primary tables: contacts, raw contacts, and data, a structure that is slightly different from that used in the older API. The new structure allows the system to more easily store and manage information for a specific contact from multiple contacts sources.

  • Data is a generic table that stores all of the data points associated with a raw contact. Each row stores data of a specific kind — for example name, photo, email addresses, phone numbers, and group memberships. Each row is tagged with a MIME type to identify what type of data it can contain, across the entire column. Columns are generic and the type of data they contain is determined by the kind of data stored in each row. For example, if a row's data kind is Phone.CONTENT_ITEM_TYPE, then the first column stores the phone number, but if the data kind is Email.CONTENT_ITEM_TYPE, then the column stores the email address.
    The ContactsContract.CommonDataKinds class provides subclasses corresponding to common MIME types for contacts data. If needed, your application or other contacts sources can define additional MIME types for data rows. For more information about the Data table and examples of how to use it, see android.provider.ContactsContract.Data.
  • A row in the RawContacts table represents the set of Data and other information describing a person and associated with a single contacts source. For example, a row might define the data associated with a person's Google or Exchange account or Facebook friend. For more information, see ContactsContract.RawContacts.
  • A row in the Contacts table represents an aggregate of one or more RawContacts describing the same person (or entity).
    As mentioned above, the Contacts content provider automatically aggregates Raw Contacts into a single Contact entry, where possible, since common data fields (such as name or email address) are likely to be stored in each raw contact. Since the aggregation logic maintains the entries in the Contact rows, the entries can be read but should not be modified. See the section Aggregation of contacts, below, for more details, including and information on how to control aggregation.
When displaying contacts to users, applications should typically operate on the Contacts level, since it provides a unified, aggregated view of contacts from various underlying sources.

Example: Inserting a Phone Number

To insert a phone number using the new APIs you'll need the ID of the Raw Contact to attach the phone number to, then you'll need to create a Data row:
import android.provider.ContactsContract.CommonDataKinds.Phone;
...
ContentValues values = new ContentValues();
values.put(Phone.RAW_CONTACT_ID, rawContactId);
values.put(Phone.NUMBER, phoneNumber);
values.put(Phone.TYPE, Phone.TYPE_MOBILE);
Uri uri = getContentResolver().insert(Phone.CONTENT_URI, values);

Aggregation of contacts

When users sync contacts from multiple sources, several contacts might refer to the same person or entity, but with slightly different (or overlapping) data. For example, "Bob Parr" might be a user's co-worker and also his personal friend, so the user might have his contact information stored in both a corporate email account and a personal account. To provide a simplified view for the user, the system locates such overlapping contacts and combines them into a single, aggregate contact.
The system automatically aggregates contacts by default. However, if needed, your application can control how the system handles aggregation or it can disable aggregation altogether, as described in the sections below.

Automatic aggregation

When a raw contact is added or modified, the system looks for matching (overlapping) raw contacts with which to aggregate it. It may not find any matching raw contacts, in which case it will create an aggregate contact that contains just the original raw contact. If it finds a single match, it creates a new contact that contains the two raw contacts. And it may even find multiple similar raw contacts, in which case it chooses the closest match.
Two raw contacts are considered to be a match if at least one of these conditions is met:
  • They have matching names.
  • Their names consist of the same words but in different order (for example, "Bob Parr" and "Parr, Bob")
  • One of them has a common short name for the other (for example, "Bob Parr" and "Robert Parr")
  • One of them has just a first or last name and it matches the other raw contact. This rule is less reliable, so it only applies if the two raw contacts are also sharing some other data like a phone number, an email address or a nickname (for example, Helen ["elastigirl"] = Helen Parr ["elastigirl"])
  • At least one of the two raw contacts is missing the name altogether and they are sharing a phone number, an email address or a nickname (for example, Bob Parr [incredible@android.com] = incredible@android.com).
When comparing names, the system ignores upper/lower case differences (Bob=BOB=bob) and diacritical marks (Hélène=Helene). When comparing two phone numbers the system ignores special characters such as "*", "#", "(", ")", and whitespace. Also if the only difference between two numbers is that one has a country code and the other does not, then the system considers those to be a match (except for numbers in the Japan country code).
Automatic aggregation is not permanent; any change of a constituent raw contact may create a new aggregate or break up an existing one.

Explicit aggregation

In some cases, the system's automatic aggregation may not meet the requirements of your application or sync adapter. There are two sets of APIs you can use to control aggregation explicitly: aggregation modes allow you to control automatic aggregation behaviors and aggregation exceptions allow you to override automated aggregation entirely.
Aggregation modes
You can set an aggregation mode for each raw contact individually. To do so, add a mode constant as the value of the AGGREGATION_MODE column in the RawContact row. The mode constants available include:
  • AGGREGATION_MODE_DEFAULT — normal mode, automatic aggregation is allowed.
  • AGGREGATION_MODE_DISABLED — automatic aggregation is not allowed. The raw contact will not be aggregated.
  • AGGREGATION_MODE_SUSPENDED — automatic aggregation is deactivated. If the raw contact is already a part of an aggregated contact when aggregation mode changes to suspended, it will remain in the aggregate, even if it changes in such a way that it no longer matches the other raw contacts in the aggregate.
Aggregation exceptions
To keep two raw contacts unconditionally together or unconditionally apart, you can add a row to the ContactsContract.AggregationExceptions table. Exceptions defined in the table override all automatic aggregation rules.

Loookup URI

The new Contacts API introduces the notion of a lookup key for a contact. If your application needs to maintain references to contacts, you should use lookup keys instead of the traditional row ids. You can acquire a lookup key from the contact itself, it is a column on the ContactsContract.Contacts table. Once you have a lookup key, you can construct a URI in this way:
Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey)
and use it like you would use a traditional content URI, for example:
Cursor c = getContentResolver().query(lookupUri, new String[]{Contacts.DISPLAY_NAME}, ...);
try {
    c.moveToFirst();
    String displayName = c.getString(0);
} finally {
    c.close();
}
The reason for this complication is that regular contact row IDs are inherently volatile. Let's say your app stored a long ID of a contact. Then the user goes and manually joins the contact with some other contact. Now there is a single contact where there used to be two, and the stored long contact ID points nowhere.
The lookup key helps resolve the contact in this case. The key is a string that concatenates the server-side identities of the raw contacts. Your application can use that string to find a contact, regardless whether the raw contact is aggregated with others or not.
If performance is a concern for your application, you might want to store both the lookup and the long ID of a contact and construct a lookup URI out of both IDs, as shown here:
Uri lookupUri = getLookupUri(contactId, lookupKey)
When both IDs are present in the URI, the system will try to use the long ID first. That is a very quick query. If the contact is not found, or if the one that is found has the wrong lookup key, the content provider will parse the lookup key and track down the constituent raw contacts. If your app bulk-processes contacts, you should maintain both IDs. If your app works with a single contact per user action, you probably don't need to bother with storing the long ID.
Android itself uses lookup URIs whenever there is a need to reference a contact, such as with shortcuts or Quick Contact, and also during editing or even viewing a contact. The latter case is less obvious — why would a contact ID change while we are simply viewing the contact? It could change because there might be a sync going in the background, and the contact might get automatically aggregated with another while being viewed.
In summary: whenever you need to reference a contact, we recommend that you do so by its lookup URI.

Considerations for legacy applications

If you have an existing application that uses the older Contacts API, you should consider upgrading it to use the new API. You have four options:
  • Leave it as-is and rely on the Contacts compatibility mode.
  • Upgrade the app and discontinue support of pre-Android 2.0 platforms.
  • Build a new version of the app for the new API, while keeping the old version available.
  • Make the app use the right set of APIs depending on the platform where it is deployed.
Let's consider these options one by one.

Using compatibility mode

Compatibility mode is the easiest option because you just leave the application as is, and it should run on Android 2.0 as long as it only uses public APIs. A couple examples of the use of non-public API include the use of explicit table names in nested queries and the use of columns that were not declared as public constants in the Contacts class.
Even if the application currently runs, you don't want to leave it like this for long. The main reason is that it will only have access to contacts from one account, namely the first Google account on the device. If the user opens other accounts in addition to or instead of a Google account, your application will not be able to access those contacts.

Upgrading to the new API and dropping support for older platforms

If your application will no longer target platforms older than Android 2.0, you can upgrade to the new API in this way:
  • Replace all usages of Contacts with calls to new API. After you are done, you should not see any deprecation warnings during application build. The new application will be able to take full advantage of multiple accounts and other new features of Android 2.0.
  • In the application's manifest, update (or add) the android:minSdkVersion attribute to the <uses-sdk> element. To use the new Contacts API, you should set the value of the attribute to "5" (or higher, as appropriate). For more information about android:minSdkVersion, see the documentation for the <uses-sdk> element. For more information about the value of the minSdkVersion, see API Levels.

Maintaining two applications

You may decide to have two different applications: one for pre-Android 2.0 platforms and one for Android 2.0 and beyond. If so, here's what you'll need to do:
  • Clone your existing app.
  • Change the old application:
    • At launch time, check the version of the SDK. The version of the SDK is available as android.os.Build.VERSION.SDK.
    • If the SDK version is greater or equal to 5 (Android 2.0), show a dialog suggesting to the user that it's time to go to Google Play and find a new version of the app. You can even provide a link to the new app on Google Play (see Using Intents to Launch Google Play).
  • Change the new application:
    • Replace all usages of the older Contacts API with calls to new API. The new application will be able to take full advantage of multiple accounts and other new features of Android 2.0.
    • Modify that application's AndroidManifest.xml file:
      • Give the application a new name and a new package name. Currently Google Play does not allow you to have two applications with the same name/package.
      • Update (or add) the android:minSdkVersion attribute to the <uses-sdk> element. To use the new Contacts API, you should set the value of the attribute to "5" (or higher, as appropriate).
  • Publish both apps on Google Play, the old app one as an upgrade and the other as new. Make sure to explain the difference between the apps in their descriptions.
This plan has its disadvantages:
  • The new application will not be able to read the old application's data. Application data can only be accessed by code living in the same package. So databases, shared preferences, and so on, will need to be populated from scratch.
  • The upgrade process is too clunky for the user. Some users may choose to either stay with the crippled old version or uninstall altogether.

Supporting the old and new APIs in the same application

This is a bit tricky, but the result is worth the effort. You can build a single package that will work on any platform:
Go through the existing application and factor out all access to Contacts into one class, such as ContactAccessorOldApi. For example, if you have code like this:
    protected void pickContact() {
        startActivityForResult(new Intent(Intent.ACTION_PICK, People.CONTENT_URI), 0);
    }
it will change to:
    private final ContactAccessorOldApi mContactAccessor = new ContactAccessorOldApi();
    void pickContact() {
        startActivityForResult(mContactAccessor.getContactPickerIntent(), 0);
    }
The corresponding method on ContactAccessorOldApi will look like this:
    public Intent getContactPickerIntent() {
        return new Intent(Intent.ACTION_PICK, People.CONTENT_URI);
    }
Once you are done, you should see deprecation warnings coming only from ContactAccessorOldApi.
Create a new abstract class ContactAccessor, make sure the abstract class has all method signatures from ContactAccessorOldApi. Make ContactAccessorOldApi extend ContactAccessor:
    public abstract class ContactAccessor {
        public abstract Intent getContactPickerIntent();
        ...
    }
Create a new subclass of ContactAccessor, ContactAccessorNewApi and implement all methods using the new API:
    public class ContactAccessorNewApi extends ContactAccessor {    
        @Override
        public Intent getContactPickerIntent() {
            return new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
        }
        ...
    }
At this point, you have two implementations of the same API, one using the old API and another using the new API. Let's plug them in. Add this code to the ContactAccessor class:
    private static ContactAccessor sInstance;
    public static ContactAccessor getInstance() {
        if (sInstance == null) {
            String className;
            int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
            if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
                className = "ContactAccessorOldApi";
            } else {
                className = "ContactAccessorNewApi";
            }
            try {
                Class<? extends ContactAccessor> clazz =
                        Class.forName(ContactAccessor.class.getPackage() + "." + className)
                                .asSubclass(ContactAccessor.class);
                sInstance = clazz.newInstance();
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }
        return sInstance;
    }
Now replace references to ContactsAccessorOldApi with references to ContactsAccessor:
    private final ContactAccessor mContactAccessor = ContactAccessor.getInstance();
public final class

ContactsContract

extends Object



java.lang.Object
   ↳
android.provider.ContactsContract

Class Overview

The contract between the contacts provider and applications. Contains definitions for the supported URIs and columns. These APIs supersede ContactsContract.Contacts.

Overview

ContactsContract defines an extensible database of contact-related information. Contact information is stored in a three-tier data model:
  • A row in the ContactsContract.Data table can store any kind of personal data, such as a phone number or email addresses. The set of data kinds that can be stored in this table is open-ended. There is a predefined set of common kinds, but any application can add its own data kinds.
  • A row in the ContactsContract.RawContacts table represents a set of data describing a person and associated with a single account (for example, one of the user's Gmail accounts).
  • A row in the ContactsContract.Contacts table represents an aggregate of one or more RawContacts presumably describing the same person. When data in or associated with the RawContacts table is changed, the affected aggregate contacts are updated as necessary.

Constants

public static final String AUTHORITY

Since: API Level 5
The authority for the contacts provider
Constant Value: "com.android.contacts"

public static final String CALLER_IS_SYNCADAPTER

Since: API Level 5
An optional URI parameter for insert, update, or delete queries that allows the caller to specify that it is a sync adapter. The default value is false. If true DIRTY is not automatically set and the "syncToNetwork" parameter is set to false when calling notifyChange(android.net.Uri, android.database.ContentObserver, boolean). This prevents an unnecessary extra synchronization, see the discussion of the delete operation in ContactsContract.RawContacts.
Constant Value: "caller_is_syncadapter"

public static final String DIRECTORY_PARAM_KEY

Since: API Level 11
Query parameter that should be used by the client to access a specific ContactsContract.Directory. The parameter value should be the _ID of the corresponding directory, e.g. content://com.android.contacts/data/emails/filter/acme?directory=3
Constant Value: "directory"

public static final String LIMIT_PARAM_KEY

Since: API Level 11
A query parameter that limits the number of results returned. The parameter value should be an integer.
Constant Value: "limit"

public static final String PRIMARY_ACCOUNT_NAME

Since: API Level 14
A query parameter specifing a primary account. This parameter should be used with PRIMARY_ACCOUNT_TYPE. The contacts provider handling a query may rely on this information to optimize its query results. For example, in an email composition screen, its implementation can specify an account when obtaining possible recipients, letting the provider know which account is selected during the composition. The provider may use the "primary account" information to optimize the search result.
Constant Value: "name_for_primary_account"

public static final String PRIMARY_ACCOUNT_TYPE

Since: API Level 14
A query parameter specifing a primary account. This parameter should be used with PRIMARY_ACCOUNT_NAME. See the doc in PRIMARY_ACCOUNT_NAME.
Constant Value: "type_for_primary_account"

Fields

public static final Uri AUTHORITY_URI

Since: API Level 5
A content:// style uri to the authority for the contacts provider

Public Constructors

public ContactsContract ()

Since: API Level 5

Public Methods

public static boolean isProfileId (long id)

Since: API Level 14
This method can be used to identify whether the given ID is associated with profile data. It does not necessarily indicate that the ID is tied to valid data, merely that accessing data using this ID will result in profile access checks and will only return data from the profile.
Parameters
id
The ID to check.
Returns
  • Whether the ID is associated with profile data.

Using SQLite Database


Android provides several ways to store user and app data. SQLite is one way of storing user data. SQLite is a very light weight database which comes with Android OS. In this tutorial I’ll be discussing how to write classes to handle all SQLite operations.
In this tutorial I am taking an example of storing user contacts in SQLite database. I am using a table called Contacts to store user contacts. This table contains three columns id (INT), name (TEXT), phone_number(TEXT).
Following is the structure of contacts table.

Writing Contact Class
Before you go further you need to write your Contact class with all getter and setter methods to maintain single contact as an object.
Contact.java
package com.androidhive.androidsqlite;

public class Contact {

    //private variables
    int _id;
    String _name;
    String _phone_number;

    // Empty constructor
    public Contact(){

    }
    // constructor
    public Contact(int id, String name, String _phone_number){
        this._id = id;
        this._name = name;
        this._phone_number = _phone_number;
    }

    // constructor
    public Contact(String name, String _phone_number){
        this._name = name;
        this._phone_number = _phone_number;
    }
    // getting ID
    public int getID(){
        return this._id;
    }

    // setting id
    public void setID(int id){
        this._id = id;
    }

    // getting name
    public String getName(){
        return this._name;
    }

    // setting name
    public void setName(String name){
        this._name = name;
    }

    // getting phone number
    public String getPhoneNumber(){
        return this._phone_number;
    }

    // setting phone number
    public void setPhoneNumber(String phone_number){
        this._phone_number = phone_number;
    }
}
Writing SQLite Database Handler Class
  We need to write our own class to handle all database CRUD(Create, Read, Update and Delete) operations.
1. Create a new project by going to File ⇒ New Android Project.
2. Once the project is created, create a new class in your project src directory and name it as DatabaseHandler.java ( Right Click on src/package ⇒ New ⇒ Class)
3. Now extend your DatabaseHandler.java class from SQLiteOpenHelper.
public class DatabaseHandler extends SQLiteOpenHelper {
4. After extending your class from SQLiteOpenHelper you need to override two methods onCreate() and onUpgrage()
onCreate() – These is where we need to write create table statements. This is called when database is created.
onUpgrade() – This method is called when database is upgraded like modifying the table structure, adding constraints to database etc.,
public class DatabaseHandler extends SQLiteOpenHelper {

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "contactsManager";

    // Contacts table name
    private static final String TABLE_CONTACTS = "contacts";

    // Contacts Table Columns names
    private static final String KEY_ID = "id";
    private static final String KEY_NAME = "name";
    private static final String KEY_PH_NO = "phone_number";

    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
                + KEY_PH_NO + " TEXT" + ")";
        db.execSQL(CREATE_CONTACTS_TABLE);
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);

        // Create tables again
        onCreate(db);
    }
⇒All CRUD Operations (Create, Read, Update and Delete)
Now we need to write methods for handling all database read and write operations. Here we are implementing following methods for our contacts table.
// Adding new contact
public void addContact(Contact contact) {}

// Getting single contact
public Contact getContact(int id) {}

// Getting All Contacts
public List<Contact> getAllContacts() {}

// Getting contacts Count
public int getContactsCount() {}
// Updating single contact
public int updateContact(Contact contact) {}

// Deleting single contact
public void deleteContact(Contact contact) {}
⇒Inserting new Record
The addContact() method accepts Contact object as parameter. We need to build ContentValues parameters using Contact object. Once we inserted data in database we need to close the database connection.
addContact()
    // Adding new contact
public void addContact(Contact contact) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_NAME, contact.getName()); // Contact Name
    values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone Number

    // Inserting Row
    db.insert(TABLE_CONTACTS, null, values);
    db.close(); // Closing database connection
}
⇒Reading Row(s)
The following method getContact() will read single contact row. It accepts id as parameter and will return the matched row from the database.
getContact()
    // Getting single contact
public Contact getContact(int id) {
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
            KEY_NAME, KEY_PH_NO }, KEY_ID + "=?",
            new String[] { String.valueOf(id) }, null, null, null, null);
    if (cursor != null)
        cursor.moveToFirst();

    Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
            cursor.getString(1), cursor.getString(2));
    // return contact
    return contact;
}
getAllContacts() will return all contacts from database in array list format of Contact class type. You need to write a for loop to go through each contact.
getAllContacts()
    // Getting All Contacts
 public List<Contact> getAllContacts() {
    List<Contact> contactList = new ArrayList<Contact>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_CONTACTS;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Contact contact = new Contact();
            contact.setID(Integer.parseInt(cursor.getString(0)));
            contact.setName(cursor.getString(1));
            contact.setPhoneNumber(cursor.getString(2));
            // Adding contact to list
            contactList.add(contact);
        } while (cursor.moveToNext());
    }

    // return contact list
    return contactList;
}
getContactsCount() will return total number of contacts in SQLite database.
getContactsCount()
// Getting contacts Count
    public int getContactsCount() {
        String countQuery = "SELECT  * FROM " + TABLE_CONTACTS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        cursor.close();

        // return count
        return cursor.getCount();
    }
⇒Updating Record
updateContact() will update single contact in database. This method accepts Contact class object as parameter.
updateContact()
    // Updating single contact
public int updateContact(Contact contact) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_NAME, contact.getName());
    values.put(KEY_PH_NO, contact.getPhoneNumber());

    // updating row
    return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
            new String[] { String.valueOf(contact.getID()) });
}
⇒Deleting Record
deleteContact() will delete single contact from database.
deleteContact()
    // Deleting single contact
public void deleteContact(Contact contact) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
            new String[] { String.valueOf(contact.getID()) });
    db.close();
}
Complete DatabaseHandler.java Code:
DatabaseHandler.java
package com.androidhive.androidsqlite;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHandler extends SQLiteOpenHelper {

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "contactsManager";

    // Contacts table name
    private static final String TABLE_CONTACTS = "contacts";

    // Contacts Table Columns names
    private static final String KEY_ID = "id";
    private static final String KEY_NAME = "name";
    private static final String KEY_PH_NO = "phone_number";

    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
                + KEY_PH_NO + " TEXT" + ")";
        db.execSQL(CREATE_CONTACTS_TABLE);
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);

        // Create tables again
        onCreate(db);
    }

    /**
     * All CRUD(Create, Read, Update, Delete) Operations
     */

    // Adding new contact
    void addContact(Contact contact) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, contact.getName()); // Contact Name
        values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone

        // Inserting Row
        db.insert(TABLE_CONTACTS, null, values);
        db.close(); // Closing database connection
    }

    // Getting single contact
    Contact getContact(int id) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
                KEY_NAME, KEY_PH_NO }, KEY_ID + "=?",
                new String[] { String.valueOf(id) }, null, null, null, null);
        if (cursor != null)
            cursor.moveToFirst();

        Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
                cursor.getString(1), cursor.getString(2));
        // return contact
        return contact;
    }

    // Getting All Contacts
    public List<Contact> getAllContacts() {
        List<Contact> contactList = new ArrayList<Contact>();
        // Select All Query
        String selectQuery = "SELECT  * FROM " + TABLE_CONTACTS;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Contact contact = new Contact();
                contact.setID(Integer.parseInt(cursor.getString(0)));
                contact.setName(cursor.getString(1));
                contact.setPhoneNumber(cursor.getString(2));
                // Adding contact to list
                contactList.add(contact);
            } while (cursor.moveToNext());
        }

        // return contact list
        return contactList;
    }

    // Updating single contact
    public int updateContact(Contact contact) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, contact.getName());
        values.put(KEY_PH_NO, contact.getPhoneNumber());

        // updating row
        return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
                new String[] { String.valueOf(contact.getID()) });
    }

    // Deleting single contact
    public void deleteContact(Contact contact) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
                new String[] { String.valueOf(contact.getID()) });
        db.close();
    }

    // Getting contacts Count
    public int getContactsCount() {
        String countQuery = "SELECT  * FROM " + TABLE_CONTACTS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        cursor.close();

        // return count
        return cursor.getCount();
    }

}
Usage:
AndroidSQLiteTutorialActivity
package com.androidhive.androidsqlite;

import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class AndroidSQLiteTutorialActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DatabaseHandler db = new DatabaseHandler(this);

        /**
         * CRUD Operations
         * */
        // Inserting Contacts
        Log.d("Insert: ", "Inserting ..");
        db.addContact(new Contact("Ravi", "9100000000"));
        db.addContact(new Contact("Srinivas", "9199999999"));
        db.addContact(new Contact("Tommy", "9522222222"));
        db.addContact(new Contact("Karthik", "9533333333"));

        // Reading all contacts
        Log.d("Reading: ", "Reading all contacts..");
        List<Contact> contacts = db.getAllContacts();      

        for (Contact cn : contacts) {
            String log = "Id: "+cn.getID()+" ,Name: " + cn.getName() + " ,Phone: " + cn.getPhoneNumber();
                // Writing Contacts to log
        Log.d("Name: ", log);
    }
    }
}
Android Log Cat Report:
I am writing output to Log report. You can see your log report by going to Windows ⇒ Show View ⇒ Other.. ⇒ Android ⇒ Log Cat.