Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AmmarYasserAllaithy/7e04d3c43bd78560b1a57f9fd543d2d0 to your computer and use it in GitHub Desktop.
Save AmmarYasserAllaithy/7e04d3c43bd78560b1a57f9fd543d2d0 to your computer and use it in GitHub Desktop.
What are the most effective ways for two Android applications on the same device to securely communicating with each other?

The most effective ways for two Android applications on the same device to securely communicate with each other.

All the possible ways for communication between two Android applications on the same device including Socket.IO, Intents, Broadcasts, Content Providers, Bound Services, and more. Each method will be clearly explained with code examples, specifying which parts go into Application A and Application B.

Overview of Communication Methods

  1. Explicit Intents
  2. Implicit Intents
  3. Broadcast Receivers
  4. Content Providers
  5. Bound Services AIDL
  6. Messenger IPC
  7. Socket.IO (Real-time Communication)

Explicit Intents

This is the simplest way to communicate between two applications.

Use Case: Launch Application B from Application A and send data.

Application A (Sender):

// Application A - MainActivity.kt
package com.example.applicationa

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Explicit Intent to launch Application B
        val intent = Intent().apply {
            setClassName("com.example.applicationb", "com.example.applicationb.MainActivity")
            putExtra("message", "Hello from Application A")
        }
        startActivity(intent)
    }
}

Application B (Receiver):

// Application B - MainActivity.kt
package com.example.applicationb

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Receive data from Application A
        val message = intent.getStringExtra("message")
        findViewById<TextView>(R.id.textView).text = message
    }
}

Implicit Intents

Allows communication using intent filters defined in AndroidManifest.xml.

Application A (Sender):

// Application A - MainActivity.kt
package com.example.applicationa

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Implicit Intent to launch Application B
        val intent = Intent("com.example.ACTION_SEND_MESSAGE")
        intent.putExtra("message", "Hello from Application A")
        startActivity(intent)
    }
}

Application B (Receiver):

In AndroidManifest.xml:

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="com.example.ACTION_SEND_MESSAGE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Application B - MainActivity.kt:

// Application B - MainActivity.kt
package com.example.applicationb

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val message = intent.getStringExtra("message")
        findViewById<TextView>(R.id.textView).text = message
    }
}

Broadcast Receivers

Use broadcasts to send data between applications.

Application A (Sender):

// Application A - MainActivity.kt
package com.example.applicationa

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Sending a broadcast
        val intent = Intent("com.example.SEND_BROADCAST")
        intent.putExtra("message", "Hello from Application A")
        sendBroadcast(intent)
    }
}

Application B (Receiver):

In AndroidManifest.xml:

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.SEND_BROADCAST" />
    </intent-filter>
</receiver>

Application B - MyBroadcastReceiver.kt:

// Application B - MyBroadcastReceiver.kt
package com.example.applicationb

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast

class MyBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val message = intent.getStringExtra("message")
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
    }
}

Content Providers

Allows one application to access data from another application securely.

Application B (Provider):

In AndroidManifest.xml:

<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.applicationb.provider"
    android:exported="true" />

Application B - MyContentProvider.kt:

// Application B - MyContentProvider.kt
package com.example.applicationb

import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri

class MyContentProvider : ContentProvider() {
    override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {
        // Your query logic here
        return null
    }

    override fun onCreate(): Boolean = true
    override fun insert(uri: Uri, values: ContentValues?): Uri? = null
    override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?): Int = 0
    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int = 0
    override fun getType(uri: Uri): String? = null
}

Application A (Consumer):

// Application A - MainActivity.kt
package com.example.applicationa

import android.content.ContentResolver
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val uri = Uri.parse("content://com.example.applicationb.provider")
        contentResolver.query(uri, null, null, null, null)
    }
}

Bound Services with AIDL

For inter-process communication with more complex data.

Messenger (IPC)

Useful for simple communication between apps using handlers.

Socket.IO (Real-Time Communication)

Refer to the detailed Socket.IO example provided earlier.

Which Method to Choose?

  • Explicit Intents: Best for simple interactions like launching activities.
  • Broadcast Receivers: Good for sending global messages.
  • Content Providers: Ideal for sharing structured data securely.
  • Bound Services/AIDL: Best for complex, secure inter-process communication.
  • Socket.IO: Use for real-time data transfer like chat apps.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment