S. Gökhan Topçu
gtopcu@gmail.com
If you have an Android app that uses Android's networking APIs, being able to trace the underlying TCP/IP requests your application makes is usually the best way to debug and solve problems, especially in the case of HTTP requests. Since HTTP requests are composed of a header with name/value pairs and a body of varying MIME types, being able to see what exactly is sent/received from your application to a remote server will make it much easier to understand the underlying communication which is usually well hidden by the APIs you use to make the calls.
In this blog I will be demonstrating how you can trace TCP/HTTP requests made by applications running in Android emulators. Tracing real devices is a bit trickier, since your device will have its own network adapter to reach the host, whereas the emulator goes through your PC to access the internet. Below is a simple activity which uses Apache HttpClient APIs to make HTTP GET requests to google.com.tr. Remember, you will need to add:
<uses-permission android:name="android.permission.INTERNET"/>
permission to your manifest to be able to access the internet from Android apps, otherwise you will run into java.net.UnknownHostException error.
MainActivity.java
package com.example.tcpip.http.tracing.android.apps;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
//public static final String URL = "http://www.google.com.tr";
public static final String URL = "http://10.0.2.2:666";
private HttpClient client;
private HttpGet get;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
client = new DefaultHttpClient();
get = new HttpGet(URL);
setContentView(R.layout.activity_main);
}
public void connect(View button) {
try {
HttpResponse response = client.execute(get);
Toast.makeText(this, "Response Code: " + response.getStatusLine().getStatusCode(), Toast.LENGTH_LONG).show();
Log.d(MainActivity.class.getName(), "Response Code: " + response.getStatusLine().getStatusCode());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the activity_main.xml is composed of a single button to initiate the request:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Send HTTP request"
android:onClick="connect"/>
</RelativeLayout>
In order to trace the HTTP GET request, the first step is to change the hostname part of the URL we're calling to the IP address 10.0.2.2, which is the Linux-based IP the emulator calls for app network requests. This maps to the old friend "localhost" which you would use instead if you were debugging a regular Java application. And for the port, it's better to use something different than the standard HTTP port 80 since our PC might already be using it to serve web pages/data.
Now that we have pointed our app within the emulator to our PC, we need to setup a "listener" on our PC to pick up the request, send it to remote server, get the response, and provide the response back to our waiting app. There are many tools/applications which provides TCP/IP and HTTP tracing, but since we're already using Eclipse to develop our Android apps, I will be using the standard TCP/IP monitor that comes packaged with Eclipse here.
In order to use it, the first step is to configure it to listen to the port we have specified in our app URL, as well as the target host. You can get to the TCP/IP monitor's preferences from Eclipse -> Window -> Preferences -> Run/Debug -> TCP/IP Monitor. Check "Show the TCP/IP monitor view when there is activity" checkbox as well as "Start monitor automatically" so that the monitor will show up automatically when we make a request, and add a new monitor as with the attributes as shown below:
![]() |
| Figure 1: Setting TCP/IP Monitor Preferences |
Now you can launch your activity, and click on the "Send HTTP request" button. You should see a Toast with response code 200 which will mean that you have successfully fetched Google data and you have setup your URL as well as the TCP/IP monitoring correctly:
![]() |
| Figure 2: Getting the HTTP response successfully |
After you click the button, Eclipse should open the TCP/IP Monitor view for you automatically. If it does not, you can always launch it from Eclipse -> Window -> Show View -> Debug -> TCP/IP Monitor:
![]() |
| Figure 3: Opening the TCP/IP Monitor View from Eclipse |
The monitor must now be showing the trace for your last request, which will be an HTML output since we actually made the request to a webpage using the 80 port:
![]() |
| Figure 4: HTTP trace in TCP/IP monitor |
If we were making a HTTP request with a body (and maybe using HTTP attachments as well), the trace output would show that too in the request section.
Other Methods
Eclipse TCP/IP monitor is pretty useful and straightforward to use, but surely there are many other ways to capture your requests in Android Emulator. As I have previously mentioned, you can use any other tracing tool located and setup on your PC. Just set it with the correct local listening port and target host/port configuration, and replace the host/port in your Android application with the IP 10.0.2.2 and the local port you've configured in your tracing app on your PC.Apache TCPMon
Another tool I frequently use which is more advanced than the Eclipse TCP/IP Monitor is the Apache TCPMon. You can set it up using the same philosophy as the Eclipse TCP/IP Monitor. Just check out the tutorial on their webpage which details how you can set it up.
Setting a Proxy for the Emulator
You can also set a global proxy for the emulator at launch so that all the TCP/IP requests made by apps running in the emulator will go through a HTTP/HTTPS proxy. To do that, launch the emulator using the http-proxy parameter:
emulator -avd <AVD_NAME> -http-proxy <PROXY_HOST>:<PROXY:PORT>
Your HTTP proxy must be setup and running on your PC to be able to launch the emulator with a proxy. Again, any HTTP proxy/tracing tool is suitable for using this method, and you don't need to change the URLs in your Android code to catch the requests since the emulator will always route the requests to the proxy.
Further Reading:
Eclipse TCP/IP Monitor Configuration
Apache TCPMon
Apache HttpClient
Android Emulator




No comments:
Post a Comment
Please leave your feedback below if you found this blog useful, thanks.