Search This Blog

Wednesday, October 22, 2014

Custom Toast In Android

Hi Folks,

It has been a long gap between my last post and this one a big sorry for that!!!!

This time I decided to take something like customizing widgets and to start with those as one we use mostly in our app is nothing but TOAST. 

So to let's begin the process of customizing it. 

In this sample we are going to create our own toast message and position it to our desired location unlike traditional bottom gravity of toast.

To make things simple, we are going to show the toast on a click of button. So we place just a button on our main layout (As Simple As Possible) described as below

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".CustomToast"
    android:background="#890000">

    <Button
        android:id="@+id/click_here"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_text"
        />

</RelativeLayout>

So our next step to create a layout for our custom toast. Take the below as sample straight away...

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/toast_theme">

    <ImageView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"
        android:id="@+id/custom_alert_id"/>

    <TextView
        android:paddingLeft="10dp"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/custom_text"
        android:layout_gravity="center_vertical"
        android:id="@+id/custom_text_id"/>

</LinearLayout>

In the above layout we set background property for custom toast as a custom drawable. These will be act as theme for our custom layout. So create a new drawable file toast_theme under res/drawable folder

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke
        android:width="4dp"
        android:color="#FFFFFFFF" />
    <padding
        android:bottom="7dp"
        android:left="7dp"
        android:right="7dp"
        android:top="7dp" />
    <corners android:radius="4dp" />
</shape>

In the above code we are creating a shape with fixed stroke (border) and corners with radius property to match like toast and padding properties to set our custom toast.

Now with all set we can proceed code process for make these things on user screen.

The below module pops up custom alert on click of button 

private void showCustomAlert()
    {

        Context context = getApplicationContext();
        // Create layout inflator object to inflate toast.xml file
        LayoutInflater inflater = getLayoutInflater();

        // Call toast.xml file for toast layout
        View toastRoot = inflater.inflate(R.layout.toast, null);

        Toast toast = new Toast(context);

        // Set layout to toast
        toast.setView(toastRoot);
//        toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL,
//                0, 0);
        toast.setGravity(Gravity.TOP | Gravity.CENTER, 27, 77);// change offset value to our convenience
        toast.setDuration(Toast.LENGTH_LONG);
        toast.show();

    }

In this snippet we are inflating our custom layout and setting our gravity and offset properties to make our toast to display as our wish.

Hope this small but useful tutorial on customizing toast will help beginners who willing to create a new things on Android.. Bye for now!!!!

Tuesday, August 28, 2012

NDK in Android

The Android Native Development Kit (NDK) helps you boost an app’s performance by converting C/C++ source code (in which you write the app’s performance-critical sections) to native code libraries that run on Android devices. The NDK provides headers and libraries for building activities, handling user input, using hardware sensors, and more.

Native code is often best used with processor intensive apps, but only where performance profiling has revealed a bottleneck that could be solved by recoding that portion of the app in native code.

In this blog I am going to share how to make JNI based Application in Android

The Following are prerequisite before going to develop an NDK Application
1. C/C++ Development Tools
2. Sequoyah Plugin
3.  Installing Cygwin
4. Android-NDK

Installing C/C++ Development Tools

  To install C/C++ Development tools in eclipse IDE choose Help->InstallNewSoftware...  menu item and select update site ( since I am using helios my CDT link will be http://download.eclipse.org/tools/cdt/releases/helios) select every C/C++ Development tools and follow on-screen instructions then click on restart prompt to make eclipse to update with CDT.


Installing Sequoyah Plugin

Sequoyah Plugin will enable a large range of changes into an Eclipse Android SDK project to give simultaneous support to the NDK. To install this plugin choose Help->InstallNewSoftware...  menu item and add the following site http://download.eclipse.org/sequoyah/updates/2.0/ and follow on-screen instructions to enable sequoyah plugin in eclipse.

 Installing Cygwin

Cygwin is a set of software that stimulates unix environment on windows. Download setup.exe from Cygwin setup at time of running this file a huge list appears where you can select the components to download. Search for “make” and “shell”and press next to download. After installing cygwin open it and type make-v which confirms cygwin is installed properly.

Downloading Android NDK 

 Download Android NDK form Android Official Site
Note: The NDK version used in below sample is from android-ndk-r7b

Developing Sample Application

In the below sample I tried to handle exception, return values from JNI and using log util of android SDK. So go into code the JNI module add the below code to return data from JNI to your Activity and do log action. Create a Project named NDKSample and create a folder named jni and create file name MyNativeCode.c and add the below module

#include <jni.h>
#include <string.h>
#include <android/log.h>
#include <stdio.h>

JNIEXPORT jstring JNICALL Java_org_ndk_sample_MyNativeCode_nativeCall
  (JNIEnv * env, jobject obj,jstring str)
{
    __android_log_print(ANDROID_LOG_INFO,
            "SampleJNI",
            " FIRST NDK METHOD CALL");
    return str;
}
In the above snippet explains how to define a native method JNIEXPORT means the method is exported as JNI function followed by return type and JNICALL means the class which is going to access the native method.
Note: The name of the Native Java class should be same as Native C file

To access this method we now define the Native Java class as shown below
public class MyNativeCode {
    public native String nativeCall(String data);
   }
 So to access the same from your activity create a object to this native class and call this method. Before that we need to compile the Native C to get the code as library, So we need to compile it using cygwin.

Create a make file under jni folder and add the following snippets into it

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := firstndk
LOCAL_SRC_FILES := MyNativeCode.c
LOCAL_LDLIBS    := -llog
include $(BUILD_SHARED_LIBRARY)
Here I am adding an external library called -llog which means to perform log handling in native code need to add this external library file. LOCAL_MODULE holds the name to used to call this library file from application. To know more on make file tags refer Make File tags

After this step follow the below screen to get compilation of native C.








In case of Linux there is no need of cygwin and the compilation can done as shown in screen shot below



At the end of this step library file is generated at libs folder of your project directory.

To call the library from following create Activity and add below snippet
static {
        System.loadLibrary("firstndk");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        MyNativeCode nativeCode = new MyNativeCode();
        String str = nativeCode.nativeCall("Hello Android JNI");
        Log.d("Test", str);
}
When we run this application we can notice the string Hello Android JNI is logged with two different tags namely Test and SampleJNI.

Now to handle exception I defined the method in Native C which converts String to Hex So refer below snippet for the same
JNIEXPORT jstring JNICALL Java_org_ndk_sample_MyNativeCode_string2Hex(JNIEnv *env, jobject obj, jstring str) {

    if (str==NULL) {
        (*env)->ThrowNew(env, (*env)->FindClass(env,"java/lang/Exception"), "thrown from C code");
    } else {
        const char* data= (*env)->GetStringUTFChars(env,str,NULL);
            const char *retval=convert2Hex(data);
                return (*env)->NewStringUTF(env,retval);
    }
}
 const char* convert2Hex(const char *val) {
    int len = strlen(val);
    char *tmp=(char *)malloc(len*2);
    int i = 0;
    while(*val) {
            sprintf(&tmp[i*2],"%2X", *val++);
            i++;
    }
    return (const char*)tmp;
}
 and in Native java class we declare the above method as native function as shown below
public native String string2Hex(String str) throws Exception;
and in our activity class calling the native method as shown below
try {
            retval = nativeCode.string2Hex("Testing JNI");
            Toast.makeText(getApplicationContext(),
                    "HEX value for Testing JNI is ->>> " + retval, Toast.LENGTH_LONG)
                    .show();
            nativeCode.string2Hex(null);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Toast.makeText(getApplicationContext(), e.getMessage(),Toast.LENGTH_LONG).show();
        }
Since we made changes in Native C we need to compile the code once again as specified above to reflect it in our activity and once done we will get an toast message thrown from C Code.

So this makes us to learn what is JNI, NDK and how to use it from application prespective

Thursday, July 19, 2012

Web View in Android

Webview is a view that displays webpages from online or load active web content within your activity.
It is important to add the following permission into manifest for your Activity to access the Internet and load web pages in a WebView, you must add the INTERNET permissions to your Android Manifest file:
 
<uses-permission android:name="android.permission.INTERNET" />
In this blog I am going to share my experience on Webview with a sample example.

By default, a WebView provides no browser-like widgets, does not enable JavaScript and web page errors are ignored. If your goal is only to display some HTML as a part of your UI, this is probably fine; the user won't need to interact with the web page beyond reading it, and the web page won't need to interact with the user. If you actually want a full-blown web browser, then you probably want to invoke the Browser application with a URL Intent rather than show it with a WebView. These can be achieved by adding below line to your activity's onCreate() method


protected WebView browser;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
       setContentView(R.layout.webapp);

       browser = (WebView) findViewById(R.id.webview);
       browser.loadUrl("http://www.google.com"); 
    }
To achieve these we also required to define WebView properties in webapp.xml

<?xml version="1.0" encoding="utf-8"?>
<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>
In the above file I am not specifying any layout since I am going to handle only WebView.
Now If we compile and run this app it displays Google page in browser window. After running this application if you take a look on task manager you can see that our default browser is also running alongside with our app, so in order to make the page to be displayed within our activity we need extend WebViewClient as given below
browser.setWebViewClient(new WebClient());
Now we need to extend WebViewClient

public class WebClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // TODO Auto-generated method stub
            view.loadUrl(url);
            return true;
        }
    }
After adding the above mentioned line if you try to run the application you can't able to view the webpage. This is due to WebView does not enable JavaScript by default ,so page errors are ignored so we need to add the settings to enable java script for our WebView as shown below
browser.getSettings().setJavaScriptEnabled(true); 
No you can see the page loading properly.

The next phase involves handling orientation in WebView, These condition can be identified when you try to rotate the screen your activity gets destroyed and recreated and so your page will be reloaded, In order to avoid this situation we need to save the state of our WebView and need to override onConfigurationChanged method as shown below

// To save the current WebView state we need to override this method
@Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        browser.saveState(outState);
        super.onSaveInstanceState(outState);
    }
@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        browser.restoreState(savedInstanceState);
        super.onRestoreInstanceState(savedInstanceState);
    }
@Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub
        super.onConfigurationChanged(newConfig);
    }
 The purpose of onConfigurationChange method is, it will inform android OS that the orientation will be handled manually and we need to add the following lines under Androidmanifest.xml file
<activity android:name="WebViewTest"
    android:label="@string/app_name"
    android:configChanges="keyboardHidden|orientation">
     </activity>
 After adding this you can run your application in target device and orientation will work properly and also page won't get reloaded, but if your target device is of Android ICS then we need to add two more options in order to make orientation to work properly

android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"
The below are the options which can be added as value for configChanges tag

android:configChanges=["mcc", "mnc", "locale",
                                 "touchscreen", "keyboard", "keyboardHidden",
                                 "navigation", "screenLayout", "fontScale", "uiMode",
                                 "orientation", "screenSize", "smallestScreenSize"]
The full details for this command are found at the link  ConfigChanges

The final phase is to decorate your activity by showing progress bar adding zoom control options etc. which are discussed below,
There are two types of progress feature are available to added as window component for an activity, Feature Progress, Feature Indeterminate Progress. Feature Progress displays like a normal progress bar with variable bounds whereas Indeterminate Progress works for the case which has no bounds to stop unless until the task has been completed.
Here we are going to add both types of progress bar to window activity, So to do that add the below lines before setting content view to your activity.

this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.webapp);
Now to make the progress visible in activity we need to add the below line,

getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
                Window.PROGRESS_VISIBILITY_ON);
setProgressBarIndeterminateVisibility(true); 
To handle progress bar bound limit we need to extend WebChromeClient  as described below

browser.setWebChromeClient(new ChromeClient());
public class ChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            // TODO Auto-generated method stub
            activity.setTitle(browser.getUrl());
            activity.setProgress(newProgress * 100);
            if (newProgress == 100)
                activity.setTitle(R.string.app_name);
        }
    }
Now if you run the app the progress bar will display with the name of URL inside the progress bar and showing indeterminate progress to the right side of the activity window.

The Zoom controls can be added by using below line

browser.getSettings().setBuiltInZoomControls(true);
In order to complete our application we can add a condition that our application needs to open if network connection is present. To check that add below lines before loading your desired URL.


  if (hasInternet(getApplicationContext())) {
                browser.loadUrl("Load URL String");
            } else {
                setProgressBarIndeterminateVisibility(false);
                //Show Alert Messages
            }

        public boolean hasInternet(Context con) {
            NetworkInfo info = (NetworkInfo) ((ConnectivityManager) con
                    .getSystemService(CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
            if (info == null || !info.isConnected())
                return false;
            return true;
        } 
                     
 The above method will check the status of network connectivity so we need to add permission to access network state

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
All type of built-in Android permissions can be found at the link Android Permissions

So now we can handle some basic operations on WebView with concepts defined.

Tuesday, June 26, 2012

Role of AIDL

In this post I am going to share the use of AIDL ( Android Interface Definition Language) with an example
AIDL can be implemented using parcels and also by normal java interfaces. So the below example will be a combination of both these ways, Please forgive me for my bad English.....
The main need of AIDL is to achieve RPC in android

The basic concept of RPCs in Android

 In Android a Service can export multiple remote interfaces. These remote Interfaces offer functionality which can be used from client.
In order to bind to a remote interface we need to define the following parameters
  • Intent service – this parameter is the intent which will be used to locate the service
  • ServiceConnection conn – the service connection manages the connection to the remote interface. The ServiceConnection class contains callbacks for an established connection and an unexpectedly closed connection:
    • public void onServiceConnected (ComponentName name, IBinder service)
    • public void onServiceDisconnected (ComponentName name)
    It is important to understand that the onServiceDisconnected method will only be called if the connection was closed unexpectedly and not if the connection was closed by the client. So while disconnecting from service it is must to nullify service instance
     
  • int flags – this parameter defines options which will be used during the bind process there are four possible parameters which can be combined (OR):
    • 0 – no options
    • BIND_AUTO_CREATE – this flag will automatically create the service if it is not yet running
    • BIND_DEBUG_UNBIND – this flag will result in additional debug output when errors occur during the unbinding of the service. This flag should only be used during debugging
    • BIND_NOT_FOREGROUND – this flag will limit the service process priority so that the service won’t run at the foreground process priority.

    A call to the bindService method will establish a connection to the service asynchronously and the callback within the ServiceConnection will be called once the remote interface was returned by the Service. This interface provides all methods of the remote service and it can be used by the client like a local object. This allows the client to easily call multiple methods in the service without the need of always rethinking about the fact that it is a remote service.
    The only point where additional attention is required is during the bind procedure because this is done asynchronously by the Android system. So after binding the Service you can’t just directly call remote methods but you have to wait for a callback which notifies your client that the connection was established.

    Fundamentals of Parcels and Parcelables

     In Android, Parcels are used to transmit messages. Unlike to the java serialization, the Parcels are implanted as high-performance containers for the Android inter process communication. By implementing the Parcelable interface you declare that it’s possible to transform (marshall) your class into a Parcel and back (demarshall). Because the Parcels are designed for performance you should always use Parcelables instead of using the java serialization (which would also be possible) when doing IPC in android. Even when you are communicating with Intents you can still use Parcels to pass data within the intent instead of serialized data which is most likely not as efficient as Parcels.

    Create Parcelable Interface

    Let us jump into some bit of code... Create a file named MyParcelableMessage.aidl and do the following code in it..
    /* The package where the aidl file is located */
    package com.test.aidlparcel;

    /* Declare our message as a class which implements the Parcelable interface */
    parcelable MyParcelableMessage;
    After defining .aidl file we define corresponding java class that is need to parceled to activity. So we need to implement our java class using Parcelable Interface, The android.os.Parcelable interface defines two methods which have to be implemented:
    int describeContents()   
    This method can be used to give additional hints on how to process the received parcel. I am not much aware of need of this method So just implementing it as follows
    /**
         * Method which will give additional hints how to process
         * the parcel. For example there could be multiple
         * implementations of an Interface which extends the Parcelable
         * Interface. When such a parcel is received you can use
         * this to determine which object you need to instantiate.
         */
        public int describeContents() {
            return 0;            // nothing special about our content
        }
     void writeToParcel(Parcel dest, int flags)

    This is the core method which is called when this object is to be marshalled to a parcel object. In this method all required data fields should be added to the “dest” Parcel so that it’s possible to restore the state of the object within the receiver during the demarshalling.
    /**
         * Method which will be called when this object should be
         * marshalled to a Parcelable object.
         * Add all required data fields to the parcel in this
         * method.
         */
        public void writeToParcel(Parcel outParcel, int flags) {
            outParcel.writeString(message);
            outParcel.writeInt(textSize);
            outParcel.writeInt(textColor);
            outParcel.writeInt(textTypeface.getStyle());
        }
     
    Furthermore it is necessary to provide a static CREATOR field in any implementation of the Parcelable interface. The type of this CREATOR must be of Parcelable.Creator<T>. This CREATOR will act as a factory to create objects during the demarshalling of the parcel. This interface defines two methods and T specifies object which is need to be parceled.
    /**
         * Factory for creating instances of the Parcelable class.
         */
        public static final Parcelable.Creator<MyParcelableMessage> CREATOR = new Parcelable.Creator<MyParcelableMessage>() {
           
            /**
             * This method will be called to instantiate a MyParcelableMessage
             * when a Parcel is received.
             * All data fields which where written during the writeToParcel
             * method should be read in the correct sequence during this method.
             */
            @Override
            public MyParcelableMessage createFromParcel(Parcel in) {
                String message = in.readString();
                int fontSize = in.readInt();
                int textColor = in.readInt();
                Typeface typeface = Typeface.defaultFromStyle(in.readInt());
                return new MyParcelableMessage(message, fontSize, textColor, typeface);
            }

            /**
             * Creates an array of our Parcelable object.
             */
            @Override
            public MyParcelableMessage[] newArray(int size) {
                return new MyParcelableMessage[size];
            }
        };

    Implementing Remote Interface

    As I mentioned above these example does RPC using Interfacing of Java objects and here I am going to define an another .adil file which transfers Parcelable object through java interface

    /* Import our Parcelable message */
    import com.test.aidlparcel.MyParcelableMessage;

    /* The name of the remote service */
    interface IRemoteParcelableMessageService {

        /* A simple Method which will return a message
         * The message object implements the Parcelable interface
         */
        MyParcelableMessage getMessage();

    }
    After creating this aidl file it will generate a java file in gen directory on your project folder. So we will use of the stub to add details to be parceled to main activity
    Create Java file and do the following
    import android.graphics.Typeface;
    import android.os.RemoteException;

    public class TimeParcelableMessageService extends IRemoteParcelableMessageService.Stub {
        private final static int MAX_FONT_SIZE_INCREASE = 40;
        private final static int MIN_FONT_SIZE = 10;
       
        private final AIDLParcelableMessageService service;

        public TimeParcelableMessageService(AIDLParcelableMessageService service) {
            this.service = service;
        }
       
        @Override
        public MyParcelableMessage getMessage() throws RemoteException {
            String message = service.getStringForRemoteService();
            int fontSize = (int)(Math.random()*MAX_FONT_SIZE_INCREASE) + MIN_FONT_SIZE;
            int textColor = (int)(Math.random()*Integer.MAX_VALUE);
          
            int randomTextStyleSelector = (int)(Math.random()*3);
            int textStyle;
            switch (randomTextStyleSelector) {
            case 0:
                textStyle = Typeface.BOLD;
                break;
            case 1:
                textStyle = Typeface.BOLD_ITALIC;
                break;
            case 2:
                textStyle = Typeface.ITALIC;
                break;
            default:
                textStyle = Typeface.NORMAL;
                break;
            }
          
            return new MyParcelableMessage(message, fontSize, textColor, Typeface.defaultFromStyle(textStyle));
        }

    }
    The above class will provide informations like Text to be displayed with its font size color and text style. In this class we get the message to be provided to parcelable class is obtained from another class that invokes during bind process.

    Implementing the Service

     Create a Java class as shown below
    import java.text.SimpleDateFormat;


    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.util.Log;

    public class AIDLParcelableMessageService extends Service {
        private static final String AIDL_INTENT_ACTION_BIND_MESSAGE_SERVICE = "aidl.intent.action.bindParcelableMessageService";
        private final static String LOG_TAG = AIDLParcelableMessageService.class.getCanonicalName();

        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(LOG_TAG,"The AIDLParcelableMessageService was created.");
        }

        @Override
        public void onDestroy() {
            Log.d(LOG_TAG,"The AIDLParcelableMessageService was destroyed.");
            super.onDestroy();
        }


        @Override
        public IBinder onBind(Intent intent) {
            if(AIDL_INTENT_ACTION_BIND_MESSAGE_SERVICE.equals(intent.getAction())) {
                Log.d(LOG_TAG,"The AIDLParcelableMessageService was binded.");
                return new TimeParcelableMessageService(this);
            }
            return null;
        }

        String getStringForRemoteService() {
            return getString(R.string.time_message) + (new SimpleDateFormat(" hh:mm:ss").format(System.currentTimeMillis()));
        }

    }
    The above class handles service binding operation from remote client and provides the current system time to the parcleable interface.

    Implementing the Client

     Before Implementing client we define a remote class that implements ServiceConnection. The main objective of this class is that you won’t have to publish any code if third-party applications want to extend your own app.
    The following are the core methods of ServiceConnection Class

     The onServiceConnected Method

     The first is the onServiceConnected method. Retrieval of the remote interface is done by the .Stub.asInterface method which will cast the IBinder object to the remote interface.
    /* Called when a connection to the Service has been established,
         * with the IBinder of the communication channel to the Service. */
       
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(LOG_TAG, "The service is now connected!");
            // Retrive Remote Interface
            this.service = IRemoteParcelableMessageService.Stub.asInterface(service);
            Log.d(LOG_TAG, "Querying the message...");
            try {
                /*
                 * This call is required because the connect is an asynchronous call
                 * so the activity has to be notified that the connection is now
                 * established and that the message was queried.
                 */
                parent.theMessageWasReceivedAsynchronously(this.service.getMessage());
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "An error occured during the call.");
            }
        }

    The onServiceDisconnected Method

     The second core method is the onServiceDisconnected. When this callback is called something went wrong with the connection so we need to remove the remote interface from the field variable.
    //Called when a connection to the Service has been lost.

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(LOG_TAG, "The connection to the service got disconnected unexpectedly!");
            service = null;
        }
    Now to connect and disconnect from the service we are not directly accessing the above defined methods and defining that with the following methods

    safelyConnectTheService Method

    This method encapsulates the bindService process for the Activity. It will avoid multiple bindService calls by checking if the connection is currently established. After that an Intent is generated with the appropriate action for the IRemoteMessageService remote interface. Furthermore the package and class name for the receiving service are set to our Service. This intent will be used in the bindService call which is executed on the Activity. The ServiceConnection parameter of this call is our own ServiceConnection – this. And because we want the Service to be created if it is currently not running we set the flag to Context.BIND_AUTO_CREATE.
    /**
         * Method to connect the Service.
         */
        public void safelyConnectTheService() {
            if(service == null) {
                Intent bindIntent = new Intent(AIDL_INTENT_ACTION_BIND_MESSAGE_SERVICE);
                bindIntent.setClassName(AIDL_MESSAGE_SERVICE_PACKAGE, AIDL_MESSAGE_SERVICE_PACKAGE + AIDL_MESSAGE_SERVICE_CLASS);
                parent.bindService(bindIntent, this, Context.BIND_AUTO_CREATE);
                Log.d(LOG_TAG, "The Service will be connected soon (asynchronus call)!");
            }
        }
    /**
         * Method to safely query the message from the remote service
         */
        public void safelyQueryMessage() {
            Log.d(LOG_TAG, "Trying to query the message from the Service.");
            if(service == null) {    // if the service is null the connection is not established.
                Log.d(LOG_TAG, "The service was not connected -> connecting.");
                safelyConnectTheService();
            } else {
                Log.d(LOG_TAG, "The Service is already connected -> querying the message.");
                try {
                    parent.theMessageWasReceivedAsynchronously(service.getMessage());
                } catch (RemoteException e) {
                    Log.e(LOG_TAG, "An error occured during the call.");
                }
            }

    safelyDisconnectTheService Method

     Because the onServiceDisconnected will only be called when something unexpected closed the connection I’ve added this method to the ServiceConnection. This method handles the unbinding for the Activity. First it checks whether a connection is currently established by checking if the remote interface is not null. Then it will remove the reference for the remote interface which will indicate that the connection is closed. Finally the unbindService method in the Activity can be called which will disconnect the Activity from the remote service.
    /**
         * Method to disconnect the Service.
         * This method is required because the onServiceDisconnected
         * is only called when the connection got closed unexpectedly
         * and not if the user requests to disconnect the service.
         */
        public void safelyDisconnectTheService() {
            if(service != null) {
                service = null;
                parent.unbindService(this);
                Log.d(LOG_TAG, "The connection to the service was closed.!");
            }
        }

    Implementing Client

     Because our RemoteMessageServiceServiceConnection class handles all aspects of the connection the activity is reduced to bare GUI code. Our GUI contains two buttons: one to update the message and another one to disconnect the remote service. The disconnect button is used to demonstrate that our ServiceConnection handles everything for us.
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;

    public class DisplayRemoteParcelableMessage extends Activity {
        private Button disconnectButton;
        private Button queryButton;
        private TextView messageTextView;
        private RemoteParcelableMessageServiceServiceConnection remoteServiceConnection;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            remoteServiceConnection = new RemoteParcelableMessageServiceServiceConnection(this);
            disconnectButton = (Button)findViewById(R.id.disconnectButton);
            queryButton = (Button)findViewById(R.id.queryButton);
            messageTextView = (TextView)findViewById(R.id.parcelableMessageTextView);
          
            disconnectButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    remoteServiceConnection.safelyDisconnectTheService();
                }
            });
           
            queryButton.setOnClickListener(new OnClickListener() {
               
                @Override
                public void onClick(View v) {
                    remoteServiceConnection.safelyQueryMessage();
                }
            });
        }
       
        void theMessageWasReceivedAsynchronously(MyParcelableMessage message) {
            message.applyMessageToTextView(messageTextView);
        }
    }

    Summary

    The Android RPC mechanism is a powerful tool which can be used to realize inter process communication (IPC) in Android. In larger Apps the overhead which is required to define the remote interface and the service connection on the client-side will be much smaller than a permanent communication with intents and the code will be less error-prone.