Anda di halaman 1dari 12

Android Application Development Training Tutorial

For more info visit http://www.zybotech.in

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

1.1. Service
A service is a component which runs in the background, without interacting with the user. The Android platform provides a lot of pre-defined services, usually exposed via a Manager class. In your activity you access services via the method getSystemService(). Own Services must be declared via the "AndroidManifest.xml". They run the main thread of their hosting process. Therefore you should run performance intensive tasks in the background .

1.2. Own Services


You can declare your own service to perform long running operations without user interaction or to supply functionality to other applications. A activity can start a service via the startService() method and stop the service via the stopService() method. If the activity want to interact with the service it can use the bindService() method of the service. This requires an "ServiceConnection" object which allows to connect to the service and which return a IBinder object. This IBinder object can be used by the activity to communicate with the service. Once a service is started its onCreate() method is called. Afterwards the onStartCommand() is called with the Intent data provided by the activity. startService also allows to provide a flag with determines the lifecycle behavior of the services. START_STICKY is used for services which are explicit started or stopped. Services started with START_NOT_STICKY will end automatically after the onStartCommand() method is done. A service is started within the main thread of the application therefore all long running tasks should be performed in the background . A Services needs to be declared in the "AndroidManifest.xml" via a <service android:name="yourclasss"> </service> and the implementing class must extend the class "Service" or one of its subclasses. One common case is that the service and the activity are very closely related. In this case class just case the IBinder to the class the service provides. See Local Service Example for an example. Another example would be the usage of Remote Messenger Service. In this case activities can send messages to the service and receive messages as well if they register for them.

1.3. Broadcast Receiver


A broadcast receiver is a class which extends "BroadcastReceiver" and which is registered as a receiver in an Android Application via the AndroidManifest.xml (or via code). This class will be able to receive intents via the sendBroadcast() method. "BroadCastReceiver" defines the method "onReceive()". Only during this method your broadcast receiver object will be valid, afterwards the Android system will consider your object as no longer active. Therefore you cannot perform any asynchronous operation.

1.4. Pending Intent


This tutorial will also use a PendingIntent. A PendingIntent is a token that you give to another application (e.g. Notification Manager, Alarm Manager or other 3rd party applications), which allows this other application to use the permissions of your application to execute a predefined piece of code. To perform a broadcast via a pending intent so get a PendingIntent via PendingIntent.getBroadcast(). To perform an activity via an pending intent you receive the activity via PendingIntent.getActivity().
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

2. Broadcast Receiver Example


We will define a broadcast receiver which listens to telephone state changes. If the phone receives a phone call then our receiver will be notified and log a message. Create a new project "de.vogella.android.receiver.phone". We do not need an activity. Create the following "AndroidManifest.xml".
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.vogella.android.receiver.phone" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <receiver android:name="MyPhoneReceiver"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE"></action> </intent-filter> </receiver> </application> <uses-sdk android:minSdkVersion="9" /> <uses-permission android:name="android.permission.READ_PHONE_STATE"></usespermission> </manifest>

Create the following class "MyPhoneReceiver".


package de.vogella.android.receiver.phone; import import import import import import android.content.BroadcastReceiver; android.content.Context; android.content.Intent; android.os.Bundle; android.telephony.TelephonyManager; android.util.Log;

public class MyPhoneReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); if (extras != null) { String state = extras.getString(TelephonyManager.EXTRA_STATE); Log.w("DEBUG", state); if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { String phoneNumber = extras .getString(TelephonyManager.EXTRA_INCOMING_NUMBER); Log.w("DEBUG", phoneNumber); } }

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

} }

If you install your application and receive a call, e.g simulated by the DDMS perspective in Eclipse, then your receiver will be called and lot a message to the console.

3. System Services and Broadcast Receiver


In this chapter we will use the AlertManager and VibratorManager. The VibratorManager will be called by the broadcast receiver which will be called by the AlertManager. Create a new project "de.vogella.android.alarm" with the activity "AlarmActivity". Create the following layout.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <EditText android:layout_height="wrap_content" android:id="@+id/time" android:layout_width="wrap_content" android:hint="Number of seconds" android:inputType="numberDecimal">></EditText> <Button android:text="Start Counter" android:id="@+id/ok" android:onClick="startAlert" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> </LinearLayout>

Create the following broadcast receiver class. This class will get the Vibrator service.
package de.vogella.android.alarm; import import import import import android.content.BroadcastReceiver; android.content.Context; android.content.Intent; android.os.Vibrator; android.widget.Toast;

public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Don't panik but your time is up!!!!.", Toast.LENGTH_LONG).show(); // Vibrate the mobile phone Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(2000); } }

Maintain this class as broadcast receiver in "AndroidManifest.xml" and allow the vibrate authorization.
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.vogella.android.alarm" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="9" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".AlarmActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name="MyBroadcastReceiver"></receiver> </application> <uses-permission android:name="android.permission.VIBRATE"></uses-permission> </manifest>

Change the code of your Activity "AlarmActivity" to the following. This activity will create an Intent for the Broadcast receiver and get the AlarmManager service.
package de.vogella.android.alarm; import import import import import import import import android.app.Activity; android.app.AlarmManager; android.app.PendingIntent; android.content.Intent; android.os.Bundle; android.view.View; android.widget.EditText; android.widget.Toast;

public class AlarmActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void startAlert(View view) { EditText text = (EditText) findViewById(R.id.time); int i = Integer.parseInt(text.getText().toString()); Intent intent = new Intent(this, MyBroadcastReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast( this.getApplicationContext(), 234324243, intent, 0); AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (i * 1000), pendingIntent); Toast.makeText(this, "Alarm set in " + i + " seconds", Toast.LENGTH_LONG).show(); } }

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

Run your application on the device. Set your time and start the alarm. After the defined number of seconds a Toast should be displayed. The vibrator alarm does not work on the simulator.

4. Define and consume your own service


The following will demonstrate how to create and consume a service from an activity. The service will periodically fetch data. The service will used by an activity which bind itself to the service. The activity will allow to request the latest data from the service. Create a new project "de.vogella.android.ownservice" with the activity "ServiceConsumer". Create a service "WordService" by create the class and the entry in "AndroidManifest.xml".
package de.vogella.android.ownservice; import import import import java.util.ArrayList; java.util.List; java.util.Timer; java.util.TimerTask;

import android.app.Service; import android.content.Intent;

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

import android.os.Binder; import android.os.IBinder; import android.util.Log; public class WordService extends Service { private Timer timer = new Timer(); private static final long UPDATE_INTERVAL = 5000; private final IBinder mBinder = new MyBinder(); private ArrayList<String> list = new ArrayList<String>(); private String[] fixedList = { "Linux", "Android", "iPhone", "vogella.de", "helpful", "stuff" }; private int index = 0; public void onCreate() { super.onCreate(); pollForUpdates(); } private void pollForUpdates() { timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { // Imagine here a freaking cool web access ;-) if (list.size() >= 6) { list.remove(0); } list.add(fixedList[index++]); if (index >= fixedList.length) { index = 0; } } }, 0, UPDATE_INTERVAL); Log.i(getClass().getSimpleName(), "Timer started."); } @Override public void onDestroy() { super.onDestroy(); if (timer != null) { timer.cancel(); } Log.i(getClass().getSimpleName(), "Timer stopped."); } // We return the binder class upon a call of bindService @Override public IBinder onBind(Intent arg0) { return mBinder; } public class MyBinder extends Binder { WordService getService() { return WordService.this; } } public List<String> getWordList() { return list; }

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.vogella.android.ownservice" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ServiceConsumer" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="WordService"></service> </application> </manifest>

Change the layout "main.xml" to the following.


<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Reload Data" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="showServiceData"></Button> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> </LinearLayout>

Change the activity ServiceConsumer to the following.


package de.vogella.android.ownservice; import java.util.ArrayList; import java.util.List; import import import import import import import import import import android.app.Activity; android.content.ComponentName; android.content.Context; android.content.Intent; android.content.ServiceConnection; android.os.Bundle; android.os.IBinder; android.view.View; android.widget.ArrayAdapter; android.widget.ListView;

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

import android.widget.Toast; public class ServiceConsumer extends Activity { private WordService s; private ArrayList<String> values; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); doBindService(); values = new ArrayList<String>(); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, values); ListView list = (ListView) findViewById(R.id.list); list.setAdapter(adapter); // List<String> wordList = s.getWordList(); // Toast.makeText(this, wordList.get(0), Toast.LENGTH_LONG).show(); } private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder binder) { s = ((WordService.MyBinder) binder).getService(); Toast.makeText(ServiceConsumer.this, "Connected", Toast.LENGTH_SHORT).show(); } public void onServiceDisconnected(ComponentName className) { s = null; } }; private ArrayAdapter<String> adapter; void doBindService() { bindService(new Intent(this, WordService.class), mConnection, Context.BIND_AUTO_CREATE); } public void showServiceData(View view) { if (s != null) { List<String> wordList = s.getWordList(); values.clear(); values.addAll(wordList); adapter.notifyDataSetChanged(); } } }

Android Service Lifecycle


The lifecycle for a service is similar to that for an activity, but different in a few important details:

onCreate and onStart differences


A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

Services can be started when a client calls the Context.startService(Intent) method. If the service isn't already running, Android starts it and calls its onCreate method followed by the onStart method. If the service is already running, its onStart method is invoked again with the new intent. So it's quite possible and normal for a service's onStart method to be called repeatedly in a single run of the service. onResume, onPause, and onStop are not needed Recall that a service generally has no user interface, so there isn't any need for the onPause, onResume, or onStop methods. Whenever a service is running, it is always in the background. onBind If a client needs a persistent connection to a service, it can call the Context.bindService method. This creates the service if it is not running, and calls onCreate but not onStart. Instead, the onBind method is called with the client's intent, and it returns an IBind object that the client can use to make further calls to the service. It's quite normal for a service to have clients starting it and clients bound to it at the same time. onDestroy As with an activity, the onDestroy method is called when the service is about to be terminated. Android will terminate a service when there are no more clients starting or bound to it. As with activities, Android may also terminate a service when memory is getting low. If that happens, Android will attempt to restart the service when the memory pressure passes, so if your service needs to store persistent information for that restart, it's best to do so in the onStart method.

1.5. Android Activity Lifecycle


Android is designed around the unique requirements of mobile applications. In particular, Android recognizes that resources (memory and battery, for example) are limited on most mobile devices, and provides mechanisms to conserve those resources. The mechanisms are evident in the Android Activity Lifecycle, which defines the states or events that an activity goes through from the time it is created until it finishes running. The lifecycle is shown diagrammatically in
Figure 1-1. Android Activity lifecycle

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

Your activity monitors and reacts to these events by instantiating methods that override the Activity class methods for each event: onCreate Called when your activity is first created. This is the place you normally create your views, open any persistent datafiles your activity needs to use, and in general initialize your activity. When calling onCreate, the Android framework is passed a Bundle object that contains any activity state saved from when the activity ran before. onStart Called just before your activity becomes visible on the screen. Once onStart completes, if your activity can become the foreground activity on the screen, control will transfer to onResume. If the activity
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

cannot become the foreground activity for some reason, control transfers to the onStop method. onResume Called right after onStart if your activity is the foreground activity on the screen. At this point your activity is running and interacting with the user. You are receiving keyboard and touch inputs, and the screen is displaying your user interface. onResume is also called if your activity loses the foreground to another activity, and that activity eventually exits, popping your activity back to the foreground. This is where your activity would start (or resume) doing things that are needed to update the user interface (receiving location updates or running an animation, for example). onPause Called when Android is just about to resume a different activity, giving that activity the foreground. At this point your activity will no longer have access to the screen, so you should stop doing things that consume battery and CPU cycles unnecessarily. If you are running an animation, no one is going to be able to see it, so you might as well suspend it until you get the screen back. Your activity needs to take advantage of this method to store any state that you will need in case your activity gains the foreground againand it is not guaranteed that your activity will resume. If the mobile device you are running on runs out of memory, there is no virtual memory on disk to use for expansion, so your activity may have to make way for a system process that needs memory. Once you exit this method, Android may kill your activity at any time without returning control to you. onStop Called when your activity is no longer visible, either because another activity has taken the foreground or because your activity is being destroyed. onDestroy The last chance for your activity to do any processing before it is destroyed. Normally you'd get to this point because the activity is done and the framework called its finish method. But as mentioned earlier, the method might be called because Android has decided it needs the resources your activity is consuming. It is important to take advantage of these methods to provide the best user experience possible. This is the first place in this book we've discussed how programming for mobile devices is different from programming for desktop devices, and there will be many more such places as you go through later chapters. Your users will appreciate it if you write your activities with the activity lifecycle in mind, and you will ultimately benefit.

A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi

Anda mungkin juga menyukai