In the world of modern mobile development, inter-app communication is evolving rapidly. Whether you're working on modular apps on a single device or syncing data between devices, a lightweight and scalable communication layer can make a big difference.
In this post, I'll walk you through an innovative concept - using Ktor to enable seamless data exchange between Android apps, both on the same device and across multiple devices.
💡 The Concept
What if:
- App Bwants to send data (text, files, events) to App A?
- App A is either: - Installed on the same device - Or running on another device in the same network (or even remotely)?
Ktor makes this not only possible but lightweight, flexible, and secure - all using pure Kotlin.
🔧 Why Ktor?
Ktor, developed by JetBrains, is an asynchronous framework for connected applications - from HTTP clients/servers to WebSockets. Its coroutine-based architecture makes it ideal for mobile-first scenarios.
Concept
Imagine a world where two Android apps - on the same or different devices - can communicate offline over a local network (like a hotspot) without relying on the internet. Sounds cool, right?
In this blog, I'll walk you through an open-source project I built that enables secure, offline data transfer between App A (Server) and App B (Client) using Ktor, QR codes, and Kotlin - all while maintaining a clean and modular architecture.
⚙️ Tech Stack:
Ktor, Kotlin Coroutines, QR Code (ZXing), Jetpack Lifecycle, Content Negotiation, Android Networking (CIO Engine)
🌟 Use Case
Let's say App A wants to receive an image from App B. Instead of using Firebase or REST APIs over the internet, we:
Spin up a local Ktor server on App A.
Encode the server's IP address, port, and a secure token into a QR code.
App B scans this QR code, picks an image, and sends it directly to App A over a local Wi-Fi connection or hotspot.
💡 Great for offline apps, peer-to-peer sharing, or isolated environments like field operations, clinics, etc.
💪 App A: Ktor Server + QR Code Generator
This app:
Gets the device's local IP address.
Generates a QR code encoding IP|PORT|TOKEN.
Hosts a Ktor server listening on a specified port.
Accepts incoming POST requests and decodes image data sent in Base64.
🔐 Security
We use a hardcoded token (my_secure_token) for simple token-based validation.
val connectionInfo = "$ip|$port|$token"
val qrBitmap = generateQrCode(connectionInfo)
qrImageView.setImageBitmap(qrBitmap)
The Ktor server listens like so:
`post("/receive") {
val auth = call.request.header("Authorization")?.removePrefix("Bearer ")
if (auth == token) {
val imageBase64 = call.receive()
val bytes = Base64.decode(imageBase64, Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
receivedImage.setImageBitmap(bitmap)
call.respond(HttpStatusCode.OK, "Image received")
} else {
call.respond(HttpStatusCode.Unauthorized, "Invalid token")
}
}
📲 App B: QR Scanner + Image Picker + Ktor Client
App B is the client. It:
Scans the QR code using ZXing (JourneyApps).
Extracts IP, port, and token.
Opens an image picker.
Converts the image to Base64 and sends it to App A.
val response = client.post("http://$ip:$port/receive") {
header("Authorization", "Bearer $token")
contentType(ContentType.Application.Json)
setBody(base64Image)
}
💡 Why This is Unique
✅ Offline-First: No internet required
✅ Secure by Design: Token-based authorization
✅ Portable & Lightweight: Runs using Ktor CIO
✅ Modular Architecture: Client/server split encourages scalability
✅ Peer-to-Peer (P2P): Works in isolated networks (Wi-Fi Direct, hotspots)
📸 Demo Screenshot
App A generates QR code with IP, port, and token.
App B scans, picks an image, and sends it.
🧪 How to Test
1.Install App A and App B on two Android devices (same Wi-Fi or hotspot).
2.Open App A → Tap Start Server → QR Code data (IP|Port|Token) is displayed.
3.Open App B → Tap Scan QR → Scan QR code → Pick image from gallery.
4.App B sends image → App A receives and displays it.
🚀 Final Thoughts
With Ktor's power and a touch of Kotlin magic, we've built a fully offline, peer-to-peer communication system between two Android apps.
This opens up new possibilities for:
Medical & field data capture
Secure, local transfers without internet dependency
Portable apps that work anywhere
📂 Source Code
I published this project on GitHub . Stay tuned!
✨ Let's Connect
👨💻 Have questions, ideas, or want to collaborate on this concept? Let's connect on GitHub Mediumand LinkedInor drop a comment below!