Android HTTP File Server using NanoHTTPD + Jetpack Compose

Build an HTTP server on Android to upload large files using NanoHTTPD and Jetpack Compose UI, Kotlin SDL

Android HTTP & File Server using NanoHTTPD + Jetpack Compose

In this post, weโ€™ll walk through how to build an HTTP server inside an Android app using NanoHTTPD and a modern Jetpack Compose UI, Kotlin DSL, capable of uploading large files over 10GB directly to the device's internal storage.


๐Ÿงฉ Tech Stack

  • ๐Ÿง  NanoHTTPD: Lightweight Java HTTP server
  • ๐Ÿ–ผ Jetpack Compose: Declarative Kotlin UI framework
  • ๐Ÿ—‚ ViewModel & Kotlin DSL: For clean state and UI control
  • ๐Ÿ“ Custom File Upload Logic: Efficient streaming to disk

๐Ÿ™ Source Code on GitHub https://github.com/WPSeven/Android-Http-File-Server


๐Ÿš€ Why This?

Mobile apps typically don't expose HTTP endpoints, but with custom tooling, you can:

  • Turn your phone into a local file server
  • Receive large files over Wi-Fi
  • Avoid needing ADB or USB transfers for big files (like 10GB+ videos)

๐Ÿ“ฆ Core Server Logic (NanoHTTPD)

We extend NanoHTTPD and override serve() to handle multipart/form-data uploads.

HttpServer.java

public class HttpServer extends NanoHTTPD {
    public HttpServer(int port, Context context, UploadCallback callback) {
        super(port);
        // Store context, callback
    }

    @Override
    public Response serve(IHTTPSession session) {
        // Handle file uploads using NanoFileUpload
    }
}   

This is backed by a NanoFileUpload helper that uses streaming APIs to save files directly to disk without memory overflows.


๐Ÿ’พ Streaming File Uploads

To handle large files, we stream the file upload chunk by chunk.

NanoFileUpload.java

public void handleUpload(IHTTPSession session) {
    // Parse multipart content using NanoHTTPD's TempFileManager
    // Write input stream directly to a FileOutputStream
}

๐Ÿง  Jetpack Compose UI

Your app includes a clean Kotlin DSL-based UI using Jetpack Compose to control the server.

MainScreen.kt

@Composable
fun MainScreen(viewModel: MainViewModel) {
    Column {
        Text("Android File Server")
        Button(onClick = { viewModel.toggleServer() }) {
            Text(if (viewModel.isRunning) "Stop Server" else "Start Server")
        }
        Text("Status: ${viewModel.statusText}")
    }
}

๐Ÿง  ViewModel Orchestration

MainViewModel.kt

class MainViewModel : ViewModel() {
    private var server: HttpServer? = null

    fun toggleServer() {
        if (server == null) {
            startServer()
        } else {
            stopServer()
        }
    }

    private fun startServer() {
        server = HttpServer(8080, context, uploadCallback)
        server?.start()
    }
}

The server is toggled via ViewModel, ensuring lifecycle-aware control.


โš™๏ธ Handling Large File Uploads (Up to 10GB+)

The core feature is robust large file upload support. Here's what powers it under the hood:

โœ… Multipart Upload Handling

We configure DiskFileItemFactory and NanoFileUpload to support very large uploads (10GB):

DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024); // 1MB memory buffer
factory.setRepository(mContext.getCacheDir()); // Temp storage
mFileUpload = new NanoFileUpload(factory);
mFileUpload.setFileSizeMax(10L * 1024 * 1024 * 1024); // 10GB

We also attach a ProgressListener to emit real-time upload progress back to the UI:

mFileUpload.setProgressListener((bytesRead, contentLength, items) -> {
    int progress = (int) (bytesRead * 100 / contentLength);
    mStatusUpdateListener.onUploadingProgressUpdate(progress);
});

๐Ÿง  HTML + JS File Upload UI (Web Browser)

When you visit / in a browser, the server responds with an HTML page that includes an upload form and a progress bar, using pure JS:

<form onsubmit='return uploadFile();'>
  <input type='file' id='fileInput' name='file'><br>
  <input type='submit' value='Upload File'>
</form>
<div class='progress'>
  <div id='progressBar' class='progress-bar'></div>
</div>

JavaScript handles the progress updates:

xhr.upload.onprogress = function(e) {
  var percentComplete = (e.loaded / e.total) * 100;
  document.getElementById('progressBar').style.width = percentComplete + '%';
};

๐Ÿ“Š Upload Streaming & Disk Write

To save the uploaded file in chunks:


    private static final int BUFFER_SIZE = 1024 * 1024;
    private static final int CHUNK_SIZE = 10 * 1024 * 1024;

    private void copyInputStreamToFile(InputStream input, File file, long contentLength) throws IOException {
        try (FileOutputStream output = new FileOutputStream(file)) {
            byte[] buffer = new byte[BUFFER_SIZE];
            long count = 0;
            long lastProgressUpdate = 0;
            int n;

            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
                count += n;

                // Update progress less frequently to reduce UI updates
                long currentTime = System.currentTimeMillis();
                if (currentTime - lastProgressUpdate > 500) { // Update every 500ms
                    int progress = (int)((count * 100) / contentLength);
                    if (mStatusUpdateListener != null) {
                        mStatusUpdateListener.onUploadingProgressUpdate(progress);
                    }
                    lastProgressUpdate = currentTime;
                }

                // Add small delay between large chunks to prevent buffer overflow
                if (count % CHUNK_SIZE == 0) {
                    Thread.sleep(50);
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

๐Ÿ“ก Uploading Files to Android from PC using browser or command-line Once running:

  1. Find your Android deviceโ€™s IP on Wi-Fi.
  2. Use browser or curl:

Browser 'http://192.168.1.175:8080/'

๐Ÿ“ธ Screenshot:

Command-line

curl -F "file=@bigfile.iso" http://192.168.1.x:8080

This is critical for handling large files without crashing.

With just a few files, you can turn your Android device into a full-fledged local http file server.


๐Ÿงฑ Source Code on GitHub https://github.com/WPSeven/Android-Http-File-Server


๐Ÿ’ก #Kotlin #Compose #Android #HttpServer #FileServer #DevTips