Foreground Services (Mandatory)

Foreground Services are essential for reliable P2P operations on Android. This guide explains when and how to use them with LiteP2P.

Why Foreground Services Are Required

Without a Foreground Service, Android will aggressively restrict your application's ability to maintain P2P connections.

Without Foreground Service

TCP connections drop silently

Android terminates background network connections without warning

NAT mappings expire

Port mappings are not renewed, breaking incoming connections

CPU execution is suspended

Your app cannot process data or maintain state

File transfers fail

Large transfers are interrupted when the app goes to background

With Foreground Service

Network stays active

Connections are maintained even when the app is in background

CPU scheduling is stable

Your app gets consistent CPU time for processing

Long operations complete reliably

File transfers and syncs finish without interruption

When to Use a Foreground Service

You must start a Foreground Service when performing these operations:

Operation Foreground Service Required Reason
Transferring files ✅ Yes Prevents transfer interruption
Cryptographic handshakes ✅ Yes Key exchange must complete atomically
Maintaining multiple peers ✅ Yes Requires sustained network access
Acting as a relay ✅ Yes Must forward traffic continuously
Performing heavy sync ✅ Yes Large data transfers need time
Idle / waiting ❌ No Use push notifications instead
Important

Do NOT use a Foreground Service when idle. This wastes battery and may cause your app to be flagged by Google Play for policy violations.

Implementation

Here's how to implement a Foreground Service for LiteP2P operations.

1. Declare in Manifest

<service
    android:name=".LiteP2PService"
    android:foregroundServiceType="dataSync"
    android:exported="false" />

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

2. Create the Service

class LiteP2PService : Service() {

    private val NOTIFICATION_ID = 1001
    private val CHANNEL_ID = "litep2p_channel"

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification = createNotification()
        startForeground(NOTIFICATION_ID, notification)

        // Start P2P operations
        LiteP2P.getInstance().startActiveSync()

        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? = null

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "LiteP2P Sync",
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "Active P2P synchronization"
            }

            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }

    private fun createNotification(): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Syncing with peers")
            .setContentText("Transferring data...")
            .setSmallIcon(R.drawable.ic_sync)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setOngoing(true)
            .build()
    }
}

3. Start and Stop Appropriately

// Start when beginning file transfer
fun startFileTransfer(peerId: String, file: File) {
    val intent = Intent(context, LiteP2PService::class.java)
    ContextCompat.startForegroundService(context, intent)

    LiteP2P.getInstance().sendFile(peerId, file) { result ->
        // Stop service when complete
        context.stopService(intent)
    }
}

// Or use LiteP2P's built-in helper
LiteP2P.getInstance().withForegroundService(context) {
    // Operations here run with foreground service protection
    sendLargeFile(peerId, file)
}

Android 14+ Foreground Service Types

Starting with Android 14, you must declare a specific foreground service type. For LiteP2P operations, use:

Operation Service Type
Data sync / file transfer dataSync
Media playback (if applicable) mediaPlayback
Connected device connectedDevice