Wifi hotspot has always been one of the dark areas of Android since it lacks official support. I’ve developed a library called SpotServe for the save.
In Android, most of the wifi hotspot 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");
}
}