Android Web Server – Receiving Get Requests on Android

An Android web server can be used as the brain of an IoT environment. In this tutorial, I will show you how to create a basic Android web server that accepts GET requests. This will come in handy when accepting information from IoT devices such as the ESP32.

With the Android OS now running on the Raspberry Pi 3 and Odroid, it makes sense that it can be the heart of an IoT ecosystem. You could however run it from your phone but your devices would be lost when you leave the house.

Let’s Build the Android Web Server

First we’ll start with an empty activity project, similar to the past tutorials. The project name in my case is WebServer and the main activity is WebActivity.

Next we’ll need a new class for our server. Right-click the directory in the project window directly above the WebActivity class and select New > Java Class. I’ve named this class DumbServer because it’s really not going to do much.

Unlike the example given on the Android Developer website, we will not implement the class as Runnable. We will however model it like a “runnable” class, because I like how it’s designed.

Enough chit chat, here’s the source, i’ll provide a quick explanation.

public class DumbServer {

    private final int mPort;
    private boolean mIsRunning;
    private ServerSocket mServerSocket;

    public DumbServer(int port){
        mPort = port;
    }

    public void start() {
        mIsRunning = true;
    }

    public void stop() {
        try {
            mIsRunning = false;
            if (null != mServerSocket) {
                mServerSocket.close();
                mServerSocket = null;
            }
        } catch (IOException e) {
            //catch error for closing the socket
        }
    }

    public void run() {
        try {
            mServerSocket = new ServerSocket(mPort);
            while (mIsRunning) {
                Socket socket = mServerSocket.accept();
                handle(socket);
                socket.close();
            }
        } catch (SocketException e) {
            // The server was stopped; ignore.
        } catch (IOException e) {
        }
    }

    private void handle(Socket socket) {
        BufferedReader reader = null;
        PrintStream output = null;
        try {
            String route = null;

            // Read HTTP headers and parse out the route.
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line;
            while (!TextUtils.isEmpty(line = reader.readLine())) {
                if (line.startsWith("GET /")) {
                    int start = line.indexOf('/') + 1;
                    int end = line.indexOf(' ', start);
                    route = line.substring(start, end);
                    break;
                }
            }

            // Output stream that we send the response to
            output = new PrintStream(socket.getOutputStream());

            // Prepare the content to send.
            if (null == route) {
                return;
            }

            // Send out the content.
            output.println("HTTP/1.0 200 OK");
            output.println("Content-Type: text/html");
            output.println();
            output.println("Testing!");
            output.flush();
        }
        catch(IOException e){

        }
        finally {
            if (null != output) {
                output.close();
            }
            if (null != reader) {
                try
                {
                    reader.close();
                }
                catch(IOException e){
                }
            }
        }
    }
}

For any dependency issues just hover you mouse over the problem and press Alt + Enter.

For the most part this class is self explanatory. Line 31 is where you may get some issues because that is where your socket is set up.

The handle() function  on line 41 is a point of interest because this is where the server request is parsed. As you can imagine, we can parse different types of messages besides GET but that exceeds the scope of this tutorial.

The route variable will get you any text after the domain:port. This will allow you to further parse values sent to your new Android Web Server.

The content block starting on line 68 is also important. This block returns content to the client. Included in the content is the status code notifying the client the request completed successfully.

Run the Android Web Server Asynchronously

Now that the class is created, there needs to be a way to start it. This can be a challenge because an exception is thrown when network processing is done on the UI thread. The proper way to accomplish this is through AsyncTask’s.

private class ServerTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... nada) {

        mServer = new DumbServer(8080);
        mServer.start();
        mServer.run();

        return null;
    }
}

Notice line 5, you’ll need declare an instance of DumbServer globally. This is so it can be used in the private ServerTask class and stopped

This will start the server socket asynchronously. Run the task be calling the following statement:

new ServerTask().execute();

Finally you’ll need to add the permission for the application. Add the following line within the manifest tag of the AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />

Run the application and see what you get!

…Nothing

Until you access your application through a web browser. This is what is looks like from my laptop.

Android Web Server Get Request Result

This is only the beginning. We’ve completed a GET request, but there are a few more to develop a complete REST API.

Let me know if there are any problems with the tutorial or something that needs more explaining.

Leave a Reply

Your email address will not be published. Required fields are marked *