<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: jc jaay</title>
    <description>The latest articles on DEV Community by jc jaay (@jc_jaay).</description>
    <link>https://dev.to/jc_jaay</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3034262%2Fb2a8b070-0e19-4b5c-9afc-8086c1a7f3c7.jpg</url>
      <title>DEV Community: jc jaay</title>
      <link>https://dev.to/jc_jaay</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jc_jaay"/>
    <language>en</language>
    <item>
      <title>Seamless Data Exchange Between Android Apps Using Ktor</title>
      <dc:creator>jc jaay</dc:creator>
      <pubDate>Wed, 09 Apr 2025 14:01:15 +0000</pubDate>
      <link>https://dev.to/jc_jaay/seamless-data-exchange-between-android-apps-using-ktor-5hnh</link>
      <guid>https://dev.to/jc_jaay/seamless-data-exchange-between-android-apps-using-ktor-5hnh</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfopqzru2a5obdx7za0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfopqzru2a5obdx7za0r.png" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the world of &lt;strong&gt;modern mobile development&lt;/strong&gt;, 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.&lt;br&gt;
In this post, I'll walk you through an innovative concept - using Ktor to enable seamless &lt;strong&gt;data exchange between Android apps&lt;/strong&gt;, both on the same device and across multiple devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 The Concept&lt;/strong&gt;&lt;br&gt;
What if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App Bwants to send data (text, files, events) to App A?&lt;/li&gt;
&lt;li&gt;App A is either:
 - Installed on the same device
 - Or running on another device in the same network (or even remotely)?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ktor makes this not only possible but lightweight, flexible, and secure - all using pure Kotlin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔧 Why Ktor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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?&lt;br&gt;
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.&lt;br&gt;
⚙️ Tech Stack:&lt;br&gt;
 Ktor, Kotlin Coroutines, QR Code (ZXing), Jetpack Lifecycle, Content Negotiation, Android Networking (CIO Engine)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🌟 Use Case&lt;/strong&gt;&lt;br&gt;
Let's say App A wants to receive an image from App B. Instead of using Firebase or REST APIs over the internet, we:&lt;br&gt;
Spin up a local Ktor server on App A.&lt;br&gt;
Encode the server's IP address, port, and a secure token into a QR code.&lt;br&gt;
App B scans this QR code, picks an image, and sends it directly to App A over a local Wi-Fi connection or hotspot.&lt;/p&gt;

&lt;p&gt;💡 Great for offline apps, peer-to-peer sharing, or isolated environments like field operations, clinics, etc.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;💪 App A: Ktor Server + QR Code Generator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This app:&lt;br&gt;
Gets the device's local IP address.&lt;br&gt;
Generates a QR code encoding IP|PORT|TOKEN.&lt;br&gt;
Hosts a Ktor server listening on a specified port.&lt;br&gt;
Accepts incoming POST requests and decodes image data sent in Base64.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔐 Security&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We use a hardcoded token (my_secure_token) for simple token-based validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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&amp;lt;String&amp;gt;()
        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")
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;📲 App B: QR Scanner + Image Picker + Ktor Client&lt;/strong&gt;&lt;br&gt;
App B is the client. It:&lt;br&gt;
Scans the QR code using ZXing (JourneyApps).&lt;br&gt;
Extracts IP, port, and token.&lt;br&gt;
Opens an image picker.&lt;br&gt;
Converts the image to Base64 and sends it to App A.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
val response = client.post("http://$ip:$port/receive") {
    header("Authorization", "Bearer $token")
    contentType(ContentType.Application.Json)
    setBody(base64Image)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;💡 Why This is Unique&lt;br&gt;
 ✅ Offline-First: No internet required&lt;br&gt;
 ✅ Secure by Design: Token-based authorization&lt;br&gt;
 ✅ Portable &amp;amp; Lightweight: Runs using Ktor CIO&lt;br&gt;
 ✅ Modular Architecture: Client/server split encourages scalability&lt;br&gt;
 ✅ Peer-to-Peer (P2P): Works in isolated networks (Wi-Fi Direct, hotspots)&lt;/p&gt;




&lt;p&gt;📸 Demo Screenshot&lt;br&gt;
App A generates QR code with IP, port, and token.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvcnraepi8mek2uve6nfo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvcnraepi8mek2uve6nfo.gif" alt="Image description" width="720" height="1600"&gt;&lt;/a&gt;&lt;br&gt;
App B scans, picks an image, and sends it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fog19hjv9brqyrnhby7b0.png" alt="Image description" width="800" height="1333"&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🧪 How to Test&lt;/strong&gt;&lt;br&gt;
1.Install App A and App B on two Android devices (same Wi-Fi or hotspot).&lt;br&gt;
2.Open App A → Tap Start Server → QR Code data (IP|Port|Token) is displayed.&lt;br&gt;
3.Open App B → Tap Scan QR → Scan QR code → Pick image from gallery.&lt;br&gt;
4.App B sends image → App A receives and displays it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Final Thoughts&lt;/strong&gt;&lt;br&gt;
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.&lt;br&gt;
This opens up new possibilities for:&lt;br&gt;
Medical &amp;amp; field data capture&lt;br&gt;
Secure, local transfers without internet dependency&lt;br&gt;
Portable apps that work anywhere&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Source Code&lt;/strong&gt;&lt;br&gt;
I published this project on GitHub . Stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✨ Let's Connect&lt;/strong&gt;&lt;br&gt;
👨‍💻 Have questions, ideas, or want to collaborate on this concept? Let's connect on &lt;a href="https://github.com/jaichandar14/ktor-data-exchange" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;   &lt;a href="https://medium.com/@jaichandar14/seamless-data-exchange-between-android-apps-using-ktor-3c90a35244bd" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;and &lt;a href="//www.linkedin.com/in/jayachandran-jc-jai"&gt;LinkedIn&lt;/a&gt;or drop a comment below!&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>androiddev</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
