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.