Developed SpotServe: A library to host web server on your Android wifi hotspot

Ever tried hosting a web server on your mobile hotspot access point? Seems like a lot of work, right? Wifi hotspot has always been one of the dark areas of Android since it lacks official support. I’ve developed a library called SpotServe to help you host an HTTP web server on your android wifi access point within a few seconds.

Most of the functionalities can only be achieved via reflection which is not a very reliable way.

Prerequisites for the Web Server

There are a few prerequisites that this web server requires.

IP address for the Wifi Hotspot access point

Once you have turned on your wifi hotspot access point, the next we’d need to do is finding out the ip address of it. After tons of research, I found out there’s this class in Java called Network Interface that is extension from the Enumeration itself.

I have written this method that can help us get the ip address.

  private String getIpAddress() {
    String ip = "";
    try {
      Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
          .getNetworkInterfaces();
      while (enumNetworkInterfaces.hasMoreElements()) {
        NetworkInterface networkInterface = enumNetworkInterfaces
            .nextElement();
        Enumeration<InetAddress> enumInetAddress = networkInterface
            .getInetAddresses();
        while (enumInetAddress.hasMoreElements()) {
          InetAddress inetAddress = enumInetAddress.nextElement();

          if (inetAddress.isSiteLocalAddress()) {
            ip += inetAddress.getHostAddress();
          }
        }
      }
    } catch (SocketException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      ip += "Something Wrong! " + e.toString() + "\n";
    }
    return  "http://"+ip;
  }

Port

Although, we’ll be using 8080 by default, more information on this below but still there’s an option where the user is allowed to write ports between 1000 to 9999.

About the Web Server

With this library, I have worked with different sample web servers. The web servers have been built using the NanoHTTPD library. It is a tiny, easily embeddable HTTP server in Java.

Ports being used

I have modeled the web server to use port 8080. Its use in a URL requires an explicit “default port override” to request a web browser to connect to port 8080 rather than the http default of port 80.

In fact, 8080 is often used as a default HTTP port for software providing HTTP services that is not a core HTTP Server (e.g. Apache HTTP Server). So after a while this port is sometimes taken from software that runs on the system in a background.

A. Simple ‘Hello World’

I started off by working on a simple ‘hello world’ server.

B. Hosting files on the server

The next step was to try hosting different file types on the web server. For this, I worked on two things:

1. Selecting the file from phone storage.

SpotServe currently supports files such as mp3, mp4, pdf, txt, jpg, png, etc. First, we will implement a File Chooser.

  //chooses file
  private void showFileChooser() {
    Log.v("DANG", "Coming 7");
    Intent intent = new Intent();
    //sets the select file to all types of files
    intent.setType("file/*");
    //allows to select data and return it
    intent.setAction(Intent.ACTION_GET_CONTENT);
    //starts new activity to select file and return data
    startActivityForResult(Intent.createChooser(intent, "Choose File to Upload.."),
        PICK_FILE_REQUEST);
  }

To evaluate the FilePath, I have worked on this class called FilePath. We start by checking if the document’s URI is an external storage document.

      // ExternalStorageProvider
      if (isExternalStorageDocument(uri)) {
        final String docId = DocumentsContract.getDocumentId(uri);
        final String[] split = docId.split(":");
        final String type = split[0];

        if ("primary".equalsIgnoreCase(type)) {
          return Environment.getExternalStorageDirectory() + "/"
              + split[1];
        }
      }

Similarly, we can continue writing the cases according to the different types of documents. For example, here’s what we can do for a media document.

      else if (isMediaDocument(uri)) {
        final String docId = DocumentsContract.getDocumentId(uri);
        final String[] split = docId.split(":");
        final String type = split[0];

        Uri contentUri = null;
        if ("image".equals(type)) {
          contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        } else if ("video".equals(type)) {
          contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        } else if ("audio".equals(type)) {
          contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        }

        final String selection = "_id=?";
        final String[] selectionArgs = new String[] { split[1] };

        return getDataColumn(context, contentUri, selection,
            selectionArgs);
      }
    }

2. Forwarding the MIME type to NanoHTTPD

In the WebServer.java class, We can use the selectedFilePath to help us find the MIME type. I have wrote down this simple method to help us figure out the MIME type.

  private void findMimeType() {
    String extension = MimeTypeMap.getFileExtensionFromUrl(selectedFilePath);
    if (extension != null) {
      type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
      Log.v("DANG", "The type is : " + type);
    } else {
      Log.v("DANG", "In else");
    }
  }

Leave a Reply

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

Google Summer of Code Internship Offer
Up Next:

I got an internship offer from Google Summer of Code

I got an internship offer from Google Summer of Code