Archive

Posts Tagged ‘Activity’

Tutorial – How to start a new Activity

March 31st, 2009

For starting a new Activity we need to use intent, which is an abstract description of an operation to be performed.

http://developer.android.com/reference/android/content/Intent.html

Suppose we are on Activity named ‘CurrentActivity‘ and on certain event (like button click..) we want to start a new Activity named ‘NextActivity’

We can create a new activity as follows.

public class NextActivity extends Activity {

//Your member variable declaration here

// Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState) {
//Your code here
}
}

After we have created the new Activity, we have to register it in file ‘AndroidManifest.xml’.
For registering we have to create an entry in ‘AndroidManifest.xml’ as

<activity android:name=".NextActivity"
android:label="@string/app_name">

</activity>

Note that here we have not used intent filter , since we are going to use an explicit intent, the syntax of intent filter is

<intent-filter>

<action android:name="<action here>"/>

<category android:name="<category here>"/>

</intent-filter>

Here,
action — The general action to be performed

category — Gives additional information about the action to execute. For example, CATEGORY_LAUNCHER means it should appear in the Launcher as a top-level application, while CATEGORY_ALTERNATIVE means it should be included in a list of alternative actions the user can perform on a piece of data.

Note: you can also use application tab below the ‘AndroidManifest.xml’ file, and in ‘Application Nodes’ section click
‘Add’ button as shown in figure below and select the activity .

Application Node-Add Activity

Application Node-Add Activity

Next you can start this activity on any event as follows

Intent myIntent = new Intent(CurrentActivity.this, NextActivity.class);
CurrentActivity.this.startActivity(myIntent);

Here, you have to create and intent with CurrentActivity.this as first parameter
and the the next activity as second parameter.

After you have created the intent, you can start the new activity by calling
startActivity, on current Activity, with the created intent as parameter.

Android , ,

Basics of Android : Part III – Android Services

January 8th, 2009

Many a times the application needs to do some tasks in the background for which user interventions is not required (or very less intervention is required). These background processes keeps working even if user is using some other application on the phone.

To define such background processes android has a concept of Services. Service in android is long lived application component. Service doesn’t implement any User Interface. Common example of service is Media Player application that keeps playing song in the background, file download application that can download the file in the background.

Let’s see how to create a service.

Creating a service

Android has defined a base class for all services as ‘Service’. All the services have to extend from this Service class. Service class defines service lifecycle methods like onCreate(), onStart(), onDestroy(). Here is the example a service class

package com.wissen.testApp.service;
public class MyService extends Service {
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	@Override
	public void onCreate() {
		super.onCreate();
		Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
	}
}

The above service is notifying the user when the service is created and service is destroyed.

Like every thing else in android, Service in android are also associated with the intents. This intent is required while using the service.

The service entry has to be done in the AndroidManifest.xml file along with the service intent as shown below:

<service class=".service.MyService">
<intent-filter>
<action android:value="com.wissen.testApp.service.MY_SERVICE" />
</intent-filter>
</service>

Now our service is created and can be used by the application code.

Using the service:

The application can start the service with the help of Context.startService method. The method will call the onCreate method of the service if service is not already created; else onStart method will be called. Here is the code to start the MyService

..

Intent serviceIntent = new Intent();
serviceIntent.setAction("com.wissen.testApp.service.MY_SERVICE");
startService(serviceIntent);

The service started with startService method will keep on running until stopService() is called or stopSelf() method is called.

Another way to use service is to bind to the service. The service contented this way will be considered required by the system only for as long as the calling context exists. To bind to the service a service connection object need to be created. The service connection object tell the application when the service is connected or disconnected. Here is how you can bind to the service.

ServiceConnection conn = new ServiceConnection() {
	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
	Log.i("INFO", "Service bound ");
	@Override
	public void onServiceDisconnected(ComponentName arg0) {
	Log.i("INFO", "Service Unbound ");
	}
	}

	bindService(new Intent("com.wissen.testApp.service.MY_SERVICE"), conn, Context.BIND_AUTO_CREATE);
}

The application can communicate with the service when application is connected with the service. Generally the service communicate is done with the help of Service Interface. Service interface defines methods for which service can provider implementation. For example here is some interface:

package com.wissen.testApp;
public interface IMyService {
public int getStatusCode();
}

Using this interface the application can ask the Service about its status. Lets see how the service can support this interface. Previously we saw a method called onBind which return IBinder object, the method gets called when some client of the service binds to the service. This is the same object that is passed to the onServiceConnected method. The application can communicate with the service using this IBinder object. Here is how this can be done:

 

public class MyService extends Service {
	private int statusCode;
	private MyServiceBinder myServiceBinder = new MyServiceBinder();
	@Override
	public IBinder onBind(Intent intent) {
		return myServiceBinder; // object of the class that implements Service
								// interface.
	}
	public class MyServiceBinder extends Binder implements IMyService {

		public int getStatusCode() {
			return statusCode;
		}
	}
	// .......
}

 

And here is how application can call getStatusCode method:

 

	ServiceConnection conn = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			IMyService myService = (IMyService) service;
			statusCode = myService.getStatusCode();
			Log.i("INFO", "Service bound ");
		}
		// ........
	};

You can also define ServiceListener interface which the client of the service has to be implemented to gets update from the service. In that case the service interface will have to define methods to register and unregister the ServiceListener objects.

Communication with Remote Service:

The services that we defined until now run in the application processes, you can define service that can run in their own process. For two processes to communicate with each other they need to marshal the object to sent to other process.

Android provide an AIDL tool (Android Interface definition Language) to handle all marshalling and communication part.

 

The service has to provide the Service interface as an aidl file. The AIDL tool will create a java interface corresponding for the aidl Service Interface. The AIDL tool also defines a stub class in the generated service interface, which implements the Service Interface (as abstract methods) and also provides some other required functionality. The service interface implementation class has to extend this stub class and define the service interface methods. The service onBind method will return object of this implementation class so that the client application can use the service methods. Here is the how the communication can be done:

Create a file as IMyRemoteService.aidl as follows:

 

package com.wissen.testApp;

interface IMyRemoteService {
int getStatusCode();
}

The eclipse android plug-in will create a Java interface for the aidl file created above as the part of build process.

The interface generated above will have a Stub inner class. Define a class that extends this stub class. Here is the code for the RemoteService class:

package com.wissen.testApp;
class RemoteService implements Service {
	int statusCode;

	@Override
	public IBinder onBind(Intent arg0) {
		return myRemoteServiceStub;
	}
	private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
		public int getStatusCode() throws RemoteException {
			return 0;
		}
	};
	// ........
}

When the client application connect to the service the onServiceConnected method will be called and client will get the IBinder object of the service. The Stub class also provides a method to obtain the Service Interface object from the IBinder object. Here is the client onServiceConnected code

 

	ServiceConnection conn = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			IMyRemoteService myRemoteService = IMyRemoteService.Stub
					.asInterface(service);

			try {

				statusCode = myRemoteService.getStatusCode();
			} catch (RemoteException e) {

				// handle exception

			}

			Log.i("INFO", "Service bound ");
		}
		// .........
	};

Permissions:

Service may specify required user permissions in the AndroidManifest.xml in <service> tag like this,

<service class=".service.MyService" android:permission="com.wissen.permission.MY_SERVICE_PERMISSION">
<intent-filter>
<action android:value="com.wissen.testApp.service.MY_SERVICE" />
</intent-filter>
</service>

Then to use above service the application has to ask for permission with the help of <user-permission> tag as follows:

<uses-permission android:name="com.wissen.permission.MY_SERVICE_PERMISSION"></uses-permission>

So in today’s post we saw how to create service and use it. In the next post we will see how to use ContentProviders. 

Android Basics , ,

Basics of Android : Part I – Android Activities

January 4th, 2009

There are four basic building blocks of an Android Application -

1. Activity

2. Intent Receivers

3. Service

4. Content Providers

In this post we will go in details of the activity. Activities represent the application screens in Android. Android platform define a class ‘Activity’, all the activities have to extend from Activity class.

Android platform is designed in such way that all applications can expose interfaces using above mentioned 4 building blocks through which they can interact with each other. There fore defining screens in XML is major feature required in developing such no-boundary application.

Designing user screen in XML:

The activity (screen) consists of views and viewgroups. Views are the standard screen components like TextView (Label), Buttons, CheckBox, EditText (textbox) etc. The viewgroups are special views that can contain other views and thus viewgroups can be used as panels to arrange the views on the screen. Viewgroups examples are LinearLayout, RelativeLayout, AbsoluteLayout etc.

Android supports XML syntax for designing application screens. Let’s develop an xml layout of screen which takes user’s first name and last name.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/widget28"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/firstNameLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First Name:">
</TextView>
<EditText
android:id="@+id/firstName"
android:layout_width="319px"
android:layout_height="wrap_content"
android:textSize="18sp">
</EditText>
<TextView
android:id="@+id/lastNameLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Last Name:">
</TextView>
<EditText
android:id="@+id/lastName"
android:layout_width="320px"
android:layout_height="wrap_content"
android:textSize="18sp">
</EditText>
<Button
android:id="@+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:layout_gravity="center_horizontal">
</Button>
</LinearLayout>

There are visual tools available for creating android XML screen layout. Try out droiddraw.

The above activity layout shows two textboxes for user’s first Name and last Name. Each view controls is assigned an id to identify and access the control. Activity layouts are stored under resources directory as layouts (in res/layout dir).

Activity intents:

Each activity is associated with intents which specify what the Activity can do. Activity intent consists of action and data required by the activity. The activity intents are specified in the application AndroidManifest.xml file as intent filters. Activity can support multiple actions. See the example below:

<activity class=".SomeActivity" android:label="@string/activityTitle">
<intent-filter>
<action android:value="android.intent.action.VIEW" />
<category android:value="android.intent.category.DEFAULT" />
<type android:value="content://contacts" />
</intent-filter>
</activity>

The above activity supports the view action for contact data. That means the activity display the phone contacts. There are some standard intent actions defined by the android platform like VIEW, EDIT, MAIN etc. But custom intent actions can also be specified as shown below:

<activity class=".TestActivity" android:label="@string/activityTitle">
<intent-filter>
<action android:value="com.wissen.testApp.activities.TEST_ACTIVITY" />
<category android:value="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

This activity can be used by using the TEST_ACTIVITY intent. We will see how to create activity with intents in following part of post.

Application Launcher Activity:

Every android application has a Launcher activity. The launcher activity is the activity that gets control when the application starts.

Launcher activity must support predefined intent ‘android.intent.action.MAIN’ and has category ‘android.intent.category.LAUNCHER’.

The launcher activity can be specified in the AndroidManifest.xml as follows:

<activity class=".WelcomeActivity" android:label="@string/app_name">
<intent-filter>
<action android:value="android.intent.action.MAIN" />
<category android:value="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Creating an Activity:

All the activity must extend android ‘Activity’ class. onCreate() method gets called when an activity is created.

Let create an activity for the layout we defined earlier. Here is the code…

package com.wissen.testApp;

public class UserInfoActivity extends Activity {

		private EditText firstName;

		private EditText lastName;

		/** Called when the activity is first created. */

		@Override

		public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);

		setContentView(R.layout.main);

		firstName = (EditText) findViewById(R.id.firstName);<

		lastName = (EditText) findViewById(R.id.lastName);

		submitButton = (Button) findViewById(R.id.saveButton);

		}
	}

The above activity class overrides the onCreate method. The onCreate is the activity lifecycle method and as name suggests it gets call when activity is created. So the onCreate method is the entry point for an activity.

Activity calls the setContentView method to assign the layout that we defined earlier. The Resource class is used to refer to the xml layout main (the xml file name is main.xml).

As we saw in the xml layout all the view controls as assigned id's to them. The activity can refer to the view with the help of these defined ids by using the findViewById method.

So now our activity is using layout that we defined and also has access to the firstName, lastName and button controls.

Lets define an onClick event handler for the submit button. The event handler will just show user provide firstName and LastName in a notification.

public class UserInfoActivity extends Activity implements View.OnClickListener {

		private EditText firstName;

		private EditText lastName;

		/** Called when the activity is first created. */

		@Override

		public void onCreate(Bundle savedInstanceState) {
		 //.......
		}<

		public void onClick(View view) {

		if(view.getId() == R.id.submitButton) {

		Toast.makeText(context, "Hi " + firstName.getText() + " " + lastName.getText().toString(), Toast.LENGTH_LONG).show();

		}
		}
		}

Define the above activity as the launcher activity in the AndroidManifest.xml file and the activity will be called when the application will start.

Activity Lifecycle:

Let see what the lifecycle of the android activity is. Activity class supports following lifecycle methods,

onCreate(): Called when the activity is first created. This is where setting up views is done. This method also provides you with a Bundle containing the activity's previous state (if any).

onRestart(): Called just before activity is being started after it has been stopped.

onStart(): Called when the activity is becoming visible to the user. Followed by onResume() if the activity is at the top of the activity stack.

onResume(): Called when the activity will start interacting with the user, i.e. activity is at the top of the activity stack.

onPause(): Called just before some other activity become active and user start interacting with the new activity. This method can be used to save unsaved changes.

onStop(): Called when the activity is no longer visible to the user. This may happen either because a new activity become visible, or this one is being destroyed.

onDestroy(): This method is called just before the activity is destroyed. The activity can be destroyed by calling finish() method.

Starting an Activity:

We have seen how to create and show a launcher activity. To show other activities in the application the activities has to be started.

Support you have defined an as activity as follows:

package com.wissen.testApp;

public class TestActivity extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// ........
	}
}

AndroidManifest.xml contains:


<activity class=".TestActivity" android:label="@string/activityTitle">

<intent-filter>

<action android:value="com.wissen.testApp.activities.TEST_ACTIVITY" />

<category android:value="android.intent.category.DEFAULT" />

</intent-filter>

</activity>

To show this activity to the user, the activity must be started (this can happen on some event). Here is show the activity can be started

Intent testActivityIntent = new Intent();

testActivityIntent.setAction("com.wissen.testApp.activities.TEST_ACTIVITY");

startActivity(myProfileIntent);

The activity can also be started by setting the Activity class name in the intent. Like

intent.setClass(context, TestActivity.class);

Sometimes the caller activity need some return value from the called activity. In that case the caller will start the activity with the help of startActivityForResult() method. The caller will get the result onActivityResult() method as follows:

public class MyActivity extends Activity {

	// ...

	static final int REQUEST_CODE = 0;

	protected boolean onKeyDown(int keyCode, KeyEvent event) {

		startActivityForResult(

		new Intent("activity.Action"),

		REQUEST_CODE);

		return true;

	}

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

		if (requestCode == REQUEST_CODE) {

			if (resultCode == RESULT_OK) {

				// .. do something with the result

			}

		}

	}

}

The REQUEST_CODE will be return back by the called activity to identify the request.

This is all on the activities. In subsequent posts we will see other building blocks of the android platform.

Android Basics , , ,