Archive

Posts Tagged ‘Android development’

Android Application Lifecycle

January 14th, 2009 No comments

In Android, the applications are run as a separate Linux process. So the application lifecycle is closely related to the process lifecycle. The application process lifecycle is handled by the system depending on the current system memory state.

In case of low memory, the Android system kills some less important process. The process importance is decided depending on the state of the process components.

The process types depending on the importance are as follows (from most important to least important):

1. Foreground process: A foreground process is the application process with which the user is currently interacting. The process is considered to be foreground if its Activity is at the top of the Activity stack (its onResume() has been called) or BroadcastReceiver is currently running (onReceive() method is currently getting executed) or its Service is executing callback functions like onCreate(), onStart() or onDestroy() methods.

2. Visible Process: A visible process is the process which has an Activity visible to the user (its onPause() method has been called).

3. Service Process: Service process contains a Service for which startService method is called and the service is running.

4. Background Process: The background process does not have any visible activities to the user. (Activity onStop() method has been called).

5. Empty Process: Empty process is the one that does not have any active application components. These processes are kept on for caching purpose.

It is important that application developers understand lifecycle of the application process. Not using these correctly can result in the system killing the application’s process while it is doing important work.

Setting up Android Application Development With Eclipse

January 12th, 2009 3 comments

We will see how to setup Android development environment on a Windows machine.

To develop Android applications Android SDK is required. Currently released SDK version is 1.0r2. The latest SDK can be downloaded from this URL

Download the android-sdk-windows-1.0_r2.zip file.

Unzip the downloaded archive file to say c drive in C:\android-sdk-windows-1.0_r2 folder on your disk.

We are going to use Eclipse for developing Android applications. So let’s see how to configure the Eclipse to use Android SDK.

To develop Android application in Eclipse an eclipse plug-in ‘Android Development Tools’ (ADT) is required. Let’s see how to install the ADT plug-in for eclipse 3.3:

Steps to install ADT plug-in:

1. Start eclipse. Go to Help > Software Update > Find and install

2. Choose option Search for new feature to install.

3. Click on the button as New Remote Site. Add the name of the remote site as ‘Android Plug-in’ and put the URL, as shown in the image:

https://dl-ssl.google.com/android/eclipse/

01_addremotesite1

4. Check the newly added Remote Site also check the Discovery Site option, as shown in the image. Also select the Automatically select mirrors option.

02_updateoptions

Selecting the Discovery site is useful incase your eclipse environment does not have required plug-ins for the ADT plug-in.

5. Click on Finish.

6. The update window will show Android Plugin and Discovery site option.

7. Expand the Discovery site option so that content of the discovery site will be loaded.

8. Select (check) the android plug-in option. Sometimes this may show error as
‘ Android Editors (0.8.0.v200809220836-110569) requires plug-in “org.eclipse.wst.sse.ui”‘

9. Click on the ‘Select Required’ button. The required plug-ins will be selected from the Discovery site. Click next.

selectrequired

10. License agreement will be shown. To install plug-in select Accept terms and click Next.

11. Click Finish.

12. A warning message will be shown as plug-in is not signed. But you can safely install the plug-in by clicking Install All option.

13. Restart Eclipse.

Now your plug-in is installed. You have to initialize the plug-in to use the Android SDK that we downloaded earlier.

1. Go to the android Windows > Preferences menu. Eclipse Preference window will be opened.
2. Select Android from the left hand size menu (you can use the filter box to search quickly).
3. Click on the Browse button and select the location of the SDK in our case C:\android-sdk-windows-1.0_r2.
4. Click Apply and then Ok.

Now the plug-in is completely installed and you can start with the application development.

Creating an Android Project
Following are the steps to create Android project in eclipse

1. Select File > New > Android Project.

2. Select ‘Create a new Project in workspace’ option to create a new project. Provide the project name, base Package name, application main Launcher activity and Application Name as shown.
04_createandroidproject2

3. A new Eclipse Android project will be created. The project will have main activity class and Resource (R) class defined. A res folder containing application resources and AndroidManifest.xml file will also be generated.

Running the application:
To run the application Open the Run dialog. In the Run dialog select the Android Application and click on New Configuration.
Provide the configuration name and project name as follows (use default values for rest of the fields).

05_createlauchconf

Click on apply and click run.

The emulator will be started and the application’s main activity will call.

Debugging the application
To run the application in debug mode, choose eclipse Debug button and select the application launch configuration.
The application will go into the debug mode when the application reaches any breakpoints.

Using Logcat:
ADT provide a window called LogCat. The window can be opened from Window > Show view > LogCat. (You may have to click on others to see the complete list of available views).
The logcat view show system log messages as shown,

06_androidlogcatview

The application can also log message that will be shown in the Logcat view. The application can Log message with ‘Log’ class. Use methods Log.v (verbose), Log.d (debug), Log.i (info), Log.w (warning) and Log.e (error) as per the required log levels.

DDMS Perspective:
ADT come with an eclipse perspective called as DDMS perspective. Go to Windows > Open Perspective > DDMS.
The DDMS perspective shows windows like Devices, Emulator Control, File Explorer, Heap Status, and Thread Status.

07_eclipseddms-perspective

Devices window shows the currently running emulator instance. The window also shows the information about the application processes running on the emulator along with their pids. The window also provide options like ‘Debug Selected Process’, Update Process Thread and Heap status, Stop process and Capture Emulator screen. When Update Thread and Heap status option is selected the process Thread and Heap status can be seen in Head and Thread windows.

The Emulator Control Window provide functionality like sending SMS or Voice message to the emulator, Setting the emulator location co-ordinates etc.

The File Explorer shows the files and folders present on the emulator. The window also provides functionality to push a file on Device (emulator), Pull file from Emulator, Delete Selected files. The controls are present at the upper right corner.

The Logcat window is also shown as part of the DDMS perspective.

Now your Android development environment is all set and you also how to use the android tools. So now start developing Android Applications!

Basics of Android : Part IV – Android Content Providers

January 9th, 2009 31 comments

The last post in the series, which talks about basic Android development concepts. Android application can use a file or SqlLite database to store data. Content provider provides the way by which you can share the data between multiple applications. For example contact data is used by multiple applications and must be stored in Content Provider to have common access. A content provider is a class that implements a standard set of methods to let other applications store and retrieve the type of data that is handled by that content provider. If you want your data to be public and handle by many applications create your own content provider. Application can perform following operations on content provider -

  1. Querying data
  2. Modifying records
  3. Adding records
  4. Deleting records

Standard Content Provider: Android provide some standard content provider, which are already implemented in Android e.g. contacts, images on device etc. Using these content providers the application can access contact information, images available on the device etc. Querying data: The query string in content provider is different than standard sql query. For any operation like select, add, delete, modify we required content provider URI. The URI consist of three parts, the string “content://”, segment representing kind of data to retrieve and optional ID of specific item of the specified content provider. Here are some examples of query string:

content://media/internal/images URI return the list of all internal images on the device.

content://contacts/people/ URI return the list of all contact names on the device.

content://contacts/people/45 URI return the single result row, the contact with ID=45.

Although this is the general form of the query, query URIs are somewhat arbitrary and confusing. For this android provide list of helper classes in android.provider package that define these query strings so you should not need to know the actual URI value for different data types. So it will be easy to query data. Above URIs can be represented as:

MediaStore.Images.Media.INTERNAL_CONTENT_URI
Contacts.People.CONTENT_URI

To query about specific record we have to use same CONTENT_URI, but must append specific ID. So third URI becomes

Uri person = ContentUris.withAppendedId(People.CONTENT_URI, 23);

Here is how we can query for data:

Cursor cur = managedQuery(person, null, null, null);

This query returns the cursor which contains the fields, we can iterate through cursor to retrieve all data. Let’s see an example now, which will make concept clearer:

package com.wissen.testApp;

public class ContentProviderDemo extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        displayRecords();
    }

    private void displayRecords() {
        // An array specifying which columns to return.

        String columns[] = new String[] { People.NAME, People.NUMBER };
        Uri mContacts = People.CONTENT_URI;
        Cursor cur = managedQuery(mContacts, columns, // Which columns to return
                null, // WHERE clause; which rows to return(all rows)
                null, // WHERE clause selection arguments (none)
                null // Order-by clause (ascending by name)

        );
        if (cur.moveToFirst()) {
            String name = null;
            String phoneNo = null;
            do {
                // Get the field values
                name = cur.getString(cur.getColumnIndex(People.NAME));
                phoneNo = cur.getString(cur.getColumnIndex(People.NUMBER));
                Toast.makeText(this, name + " " + phoneNo, Toast.LENGTH_LONG).show();
            } while (cur.moveToNext());
        }
    }
}

In above example we are retrieving only specific columns contact name, number and displaying the contact records one by one. Modifying Records: To modify the set of records call the method ContentResolver.update() with columns and value to be changed. You can select the columns to be updated in Content query string or in method itself. Here is how it can be done:

private void updateRecord(int recNo, String name) {
        //appending recNo, record to be updated
        Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, recNo);
        ContentValues values = new ContentValues();
        values.put(People.NAME, name);
        getContentResolver().update(uri, values, null, null);
    }

You can call above method to modify any record by specifying record number and name.

updateRecord(10,"XYZ");

This will change the name to “XYZ” of record number 10. Adding Records: To add a new record, call ContentResolver.insert() with the URI of the type of item to add, and a Map of any values you want to set immediately on the new record. This will return the full URI of the new record, including record number, which you can then use to query and get a Cursor over the new record. In above example what we have used is standard Content Provider, Contacts. We can add records in contacts also. Continuing our previous example, let us create insertRecord() method that will do the work of insertion.

private void insertRecords(String name, String phoneNo) {
        ContentValues values = new ContentValues();
        values.put(People.NAME, name);
        Uri uri = getContentResolver().insert(People.CONTENT_URI, values);
        Log.d("ANDROID", uri.toString());
        Uri numberUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);
        values.clear();
        values.put(Contacts.Phones.TYPE, People.Phones.TYPE_MOBILE);
        values.put(People.NUMBER, phoneNo);
        getContentResolver().insert(numberUri, values);
    }

To insert record in contacts just call insertRecords(name, phoneNo). Deleting records: To delete record/records from content provider use getContextResolver.delete(). Following example deletes all contacts from device as no where condition is specified.

 private void deleteRecords() {
        Uri uri = People.CONTENT_URI;
        getContentResolver().delete(uri, null, null);
    }

You can delete specific records by specifying where condition in method as parameter. This will give you an idea, how to delete specific records:

getContentResolver().delete(uri, "NAME=" + "'XYZ XYZ'", null);

This will delete records whose name is ‘XYZ XYZ’. Creating Content Provider: We now know how to use the content Provider; let’s now see how to create a content provider. To create own Content Provider in android following steps needs to be followed: 1. Create a class that will extend ContentProvider. 2. Define a public static final Uri named CONTENT_URI. This is the string that represents the full “content://” URI that your content provider handles. You must define a unique string for this value; the best solution is to use the fully-qualified class name of your content provider (lowercase). So, for example:

public static final Uri CONTENT_URI = Uri.parse( "content://com.google.android.MyContentProvider");

3. Create your system for storing data. Most content providers store their data using Android’s file storage methods or SQLite databases, but you can store your data any way you want, so long as you follow the calling and return value conventions. 4. Define column names that you will return to client. If you are using android database the column will be same as database. But you database must include one column call as _id, which identify each record in database uniquely. 5. If you are exposing byte data, such as a bitmap file, the field that stores this data should actually be a string field with a content:// URI for that specific file. This is the field that clients will call to retrieve this data. The content provider for that content type (it can be the same content provider or another content provider – for example, if you’re storing a photo you would use the media content provider) should implement a field named _data for that record. The _data field lists the exact file path on the device for that file. This field is not intended to be read by the client, but by the ContentResolver. The client will call ContentResolver.openOutputStream() on the user-facing field holding the URI for the item (for example, the column named photo might have value content://media/images/4453). The ContentResolver will request the _data field for that record, and because it has higher permissions than a client, it should be able to access that file directly and return a read wrapper for that file to the client. 6. Declare public static String for client to specify which column to return or to specify field value from cursor. 7. Return a Cursor object in response to query. This means write down all the overridden methods such as insert(), update() and delete() those will perform operations on underlying database. We may notify the listeners about updated information by using ContentResover().notifyChange(). 8. Add <provider> tag to AndroidMenifest.xml and set its authorities to define the authority part of the content type it should handle. 9. If you are handling a new data type, you must define a new MIME type to return for your implementation of android.ContentProvider.geType(url). This type corresponds to the content:// URI submitted to getType(), which will be one of the content types handled by the provider. The MIME type for each content type has two forms: one for a specific record, and one for multiple records. Use the Uri methods to help determine what is being requested. Here is the general format for each:

vnd.android.cursor.item/vnd.yourcompanyname.contenttype for a single row.

For example, a request for train record 122 using content://com.example.transportationprovider/trains/122 might return the MIME type vnd.android.cursor.item/vnd.example.rail

vnd.android.cursor.dir/vnd.yourcompanyname.contenttype for multiple rows.

For example, a request for all train records using content://com.example.transportationprovider/trains might return the MIME type vnd.android.cursor.dir/vnd.example.rail Here is the code that creates a content provider. The example just store user name and display the user names of all the users. SQLLite database is used to store the user data.

package com.wissen.testApp;

public class MyUsers {

    public static final String AUTHORITY = "com.wissen.MyContentProvider";

    // BaseColumn contains _id.
    public static final class User implements BaseColumns {

        public static final Uri    CONTENT_URI = Uri.parse("content://com.wissen.MyContentProvider");

        // Table column
        public static final String USER_NAME   = "USER_NAME";
    }
}

The above class defines the CONTENT_URI of the content provider, it also defines the columns of the content provider. Next we will define the actual content provider class that will use the above defined class.

package com.wissen.testApp.android;

public class MyContentProvider extends ContentProvider {

    private SQLiteDatabase      sqlDB;

    private DatabaseHelper      dbHelper;

    private static final String DATABASE_NAME    = "Users.db";

    private static final int    DATABASE_VERSION = 1;

    private static final String TABLE_NAME       = "User";

    private static final String TAG              = "MyContentProvider";

    private static class DatabaseHelper extends SQLiteOpenHelper {

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

        @Override
        public void onCreate(SQLiteDatabase db) {
            //create table to store user names
            db.execSQL("Create table " + TABLE_NAME + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);
        }
    }

    @Override
    public int delete(Uri uri, String s, String[] as) {
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues contentvalues) {
        // get database to insert records
        sqlDB = dbHelper.getWritableDatabase();
        // insert record in user table and get the row number of recently inserted record
        long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues);
        if (rowId > 0) {
            Uri rowUri = ContentUris.appendId(MyUsers.User.CONTENT_URI.buildUpon(), rowId).build();
            getContext().getContentResolver().notifyChange(rowUri, null);
            return rowUri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public boolean onCreate() {
        dbHelper = new DatabaseHelper(getContext());
        return (dbHelper == null) ? false : true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        qb.setTables(TABLE_NAME);
        Cursor c = qb.query(db, projection, selection, null, null, null, sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Override
    public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
        return 0;
    }
}

So we created a content Provider class as MyContentProvider and wrote code for insertion and retrieving records from Sqlite database. The content provider entry has to be added in the AndroidManifest.xml file as follows:

<provider android:name="MyContentProvider" android:authorities="com.wissen.MyContentProvider" />

Now Lets use the above defined content provider:

package com.wissen.testApp;

public class MyContentDemo extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        insertRecord("MyUser");
        displayRecords();
    }

    private void insertRecord(String userName) {
        ContentValues values = new ContentValues();
        values.put(MyUsers.User.USER_NAME, userName);
        getContentResolver().insert(MyUsers.User.CONTENT_URI, values);
    }

    private void displayRecords() {
        // An array specifying which columns to return.
        String columns[] = new String[] { MyUsers.User._ID, MyUsers.User.USER_NAME };
        Uri myUri = MyUsers.User.CONTENT_URI;
        Cursor cur = managedQuery(myUri, columns, // Which columns to return
                null, // WHERE clause; which rows to return(all rows)
                null, // WHERE clause selection arguments (none)
                null // Order-by clause (ascending by name)
        );
        if (cur.moveToFirst()) {
            String id = null;
            String userName = null;
            do {
                // Get the field values
                id = cur.getString(cur.getColumnIndex(MyUsers.User._ID));
                userName = cur.getString(cur.getColumnIndex(MyUsers.User.USER_NAME));
                Toast.makeText(this, id + " " + userName, Toast.LENGTH_LONG).show();
            } while (cur.moveToNext());
        }
    }
}

The above class first adds a user entry in the database and then displays all the usernames available in the db. So we saw how to user the content providers and how to create our own content provider. From this post on wards we will be diving deep into specific APIs like Android Media API, Android Communications API, Accelarometer and lots of other stuff.

Android API – SMS handling

December 29th, 2008 53 comments

Many new application will use SMS as data delivery platform. Reality shows, on-demand movies etc request users to send predefined formatted SMS. Similarly some applications are coming up which sends data to user using SMS. Let’s see how such an application can be built using Android platform.

Android API support developing applications that can send and receive SMS messages. The android emulator does not support sending of the SMS currently. But the emulator can receive SMS. Lets explore the android SMS support and develop a small program that listens to the SMSes received on the device (on emulator) and will show that message as notification.

The event handling on Android is done with the help of intents and intent receivers. The intents  announce (or broadcast) the event and intent receivers respond to the event. Intent receivers act as the event handlers.

Let’s define an intent receiver that can handle the SMS received event:

package com.wissen.sms.receiver;
/**
* The class is called when SMS is received.
*/
public class SMSReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO
}
}

We need to configure this intent receiver to receive SMS receive event. For SMS receive event android has defined an intent as ‘ android.provider.Telephony.SMS_RECEIVED ‘. The receiver can be configured in AndroidManifest.xml as follows:

<receiver android:name=".receiver.SMSReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>

To receive SMS, application also needs to specify permission for receiving SMS. The permission can be set in AndroidManifest.xml as follows:

<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>

Now our intent receiver is all set to be called when the android device will receive SMS. Now we only need to retrieve the received SMS and show the SMS text in a notification.

Here is the code of intent receiver that will read the SMS from intent received and show the first message (pdu).

public void onReceive(Context context, Intent intent) {
		Bundle bundle = intent.getExtras();

		Object messages[] = (Object[]) bundle.get("pdus");
		SmsMessage smsMessage[] = new SmsMessage[messages.length];
		for (int n = 0; n &lt; messages.length; n++) {
		smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
		}

		// show first message
		Toast toast = Toast.makeText(context,
		"Received SMS: " + smsMessage[0].getMessageBody(), Toast.LENGTH_LONG);
		toast.show();
		}

The SMS received by the Android device is in the form of pdus (protocol description unit). Class SmsMessage, defined in android.telephony.gsm package, can store information about the SMS. The class can also be used to create SmsMessage object from received pdus. Toast widget is used to show the SMS body as an notification.

Running the Program:
Only remaining thing now is running the application and sending the SMS message to the emulator. An SMS message can be sent to the emulator in the DDMS eclipse perspective (Dalvik Debug Monitor Service). ‘Emulator Control’ window can be used to send SMS message (an incoming number has to be provided which can be anything).

Here is the application screen shot in action,

Android SMS receiver application

Android SMS receiver application

Download the sample code here

Hello Android

December 29th, 2008 No comments

Finally Google decides to enter mobile market. Big time.

Recently all the big companies have realized potential of the mobile market and users. Everyone who has funds available at disposal is looking at mobile market. We have big players now and with Google’s entry things are going to get really competitive. Users are going to be the people who win in all this competition.

This blog and this competency center for people who are -

  • Users of Android phones
  • Android application developers
  • Experts on mobile markets
  • Android evangelists and enthusiasts

We will be talking here about new developments in the world of Android and over all mobile markets. We will be providing in depth analysis of Android as commercial platform for mobile application delivery. We will provide hands on instructions, help, work arounds for Android application developers. Keep reading.

Categories: Android Tags: ,