Daytime Client One of the stated objectives for this chapter is to connect the Java UI to our Daytime
13.4 Daytime Client One of the stated objectives for this chapter is to connect the Java UI to our Daytime
Server application. This section demonstrates the construction of a Daytime Client application, which communicates with our Daytime Server via TCP sockets.
13.4.1 Activity The Daytime Client application has a single
Activity , which presents a single Button and
a TextView, as shown in figure 13.10. When the Button is clicked, the Activity initiates the Daytime Server query and replaces the text of the TextView with the information received from the Daytime Server. Not much to it really, but that is fine, as all we are after in this sample is to demonstrate connectivity between the two applications. Listing 13.11 shows the onCreate method for this Activity.
Figure 13.10 The Daytime Client app
Listing 13.11 UI elements of DaytimeClient.java
Handler h;
Declare and
@Override
B implement a Handler
public void onCreate(Bundle icicle) { super.onCreate(icicle);
Daytime Client
setContentView(R.layout.main); final TextView statuslabel = (TextView) findViewById(R.id.statuslabel);
h = new Handler() { @Override public void handleMessage(Message msg) {
B Declare and
switch (msg.what) {
implement a Handler
case 0: Log.d("CH13","data [" + (String) msg.obj + "]"); statuslabel.setText((String) msg.obj); break;
} super.handleMessage(msg);
Button test = (Button) findViewById(R.id.testit);
C Implement
test.setOnClickListener(new Button.OnClickListener() {
click listener
public void onClick(View v) { try {
Requester r = new Requester();
D Create a Requester instance
r.start(); } catch (Exception e) { Log.d("CH13 exception caught : ",e.getMessage()) } } }); }
This application is all about detecting the selection of a button C and initiating an
action based on that click. The action is the creation of an instance of the Requester
class D , which we discuss in the next section. We handle the response from the socket server with the assistance of a Handler B . The Handler has a single role, which is to
update the UI with textual data stored in the obj member of a Message object. While the UI of this application is very simple, the more interesting side of this Activity is the interaction with the Daytime Server, which takes place in the Requester class, discussed in the next section.
13.4.2 Socket client The Daytime Server application listens on a TCP port for incoming connections. In
order to request the date and time, the Daytime Client must establish a client socket connection to the Daytime Server. It is hard to imagine a simpler TCP service than this—open a socket to the server and read data until the socket connection is closed. There is no additional requirement. Most of the networking examples in this book have focused on a higher-level protocol, HTTP, where the request and response are clearly defined with headers and a specific protocol to observe. In this example, the communications involve a lower-level socket connection, essentially raw, if you will, because there is no protocol associated with it beyond being a TCP stream (as opposed to UDP). Listing 13.12 demonstrates this lower-level socket communication.
C HAPTER 13 Hacking Android
Listing 13.12 Requester class implementation
public class Requester extends Thread {
Requester class extends
Socket requestSocket;
B the Thread class
String message; StringBuilder returnStringBuffer = new StringBuilder(); Message lmsg; int ch;
public void run() {
try {
C Socket
requestSocket = new Socket("localhost", 1024);
communications
InputStreamReader isr = new InputStreamReader(requestSocket.getInputStream(),"ISO-8859-1");
while ((ch = isr.read()) != -1) { returnStringBuffer.append((char) ch);
} message = returnStringBuffer.toString();
D Create a
lmsg = new Message();
Message object
lmsg.obj = (Object) message; lmsg.what = 0;
E Send the Message
h.sendMessage(lmsg);
to main thread
requestSocket.close(); } catch (Exception ee) { Log.d("CH13","failed to read data" + ee.getMessage()); } } }
The Requestor B class extends the Thread class by implementing the run method. Communications take place via an instance of the Socket class C , which is found in
the java.net package. Note the port number being used—1024, just like our socket
server! A Message D is used to communicate back to the UI thread. Once the Message
object is initialized, it is sent back to the calling thread E .
With the Daytime Client now coded, it’s time to test the application. In order for the Daytime Client to access a TCP socket, a special permission entry is required in the AndroidManifest.xml file: <uses-permission android:name="android.permission.
INTERNET"></uses-permission> .
13.4.3 Testing Daytime Client The first step in testing the Daytime Client is to ensure that the Daytime Server appli-
cation is running, as described in section 13.3.4. Once you know the Daytime Server is running, you can run the Daytime Client.
NOTE If you are unclear on how to build and run the Daytime Client, refer to
chapter 2 for information on properly setting up the Android develop- ment environment in Eclipse.
Figure 13.11 demonstrates the Daytime Client running, alongside a view of the Day- time Server. Note how the TextView of the Android application is updated to reflect the date and time sent by the Daytime Server.
Summary
Figure 13.11 Testing the Daytime Client
The Daytime Server is exercising both TCP socket functionality and SQLite database record insertions, all running in the Android Emulator. A production-ready Android/ Linux application would need to be converted to run as a daemon, which is beyond our aim for this chapter.