package com.example.myapp.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
class NetworkChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
val isConnected = isNetworkAvailable(context)
// Handle network change
onNetworkChange(isConnected)
}
}
private fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(network)
?: return false
capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
} else {
@Suppress("DEPRECATION")
val networkInfo = connectivityManager.activeNetworkInfo
networkInfo?.isConnected == true
}
}
private fun onNetworkChange(isConnected: Boolean) {
// Notify app of network state change
}
companion object {
fun observeNetworkChanges(context: Context): Flow<Boolean> = callbackFlow {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
trySend(true)
}
override fun onLost(network: Network) {
trySend(false)
}
}
val request = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(request, callback)
awaitClose {
connectivityManager.unregisterNetworkCallback(callback)
}
} else {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@Suppress("DEPRECATION")
val isConnected = connectivityManager.activeNetworkInfo?.isConnected == true
trySend(isConnected)
}
}
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
context.registerReceiver(receiver, filter)
awaitClose {
context.unregisterReceiver(receiver)
}
}
}
}
}
package com.example.myapp.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.myapp.workers.SyncWorker
class BootCompletedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
// Schedule periodic work after device boot
SyncWorker.schedulePeriodicSync(context)
}
}
}
// In AndroidManifest.xml:
// <receiver
// android:name=".receivers.BootCompletedReceiver"
// android:enabled="true"
// android:exported="false">
// <intent-filter>
// <action android:name="android.intent.action.BOOT_COMPLETED" />
// </intent-filter>
// </receiver>
//
// <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
BroadcastReceiver responds to system-wide or app-specific events. I register receivers statically in AndroidManifest or dynamically with registerReceiver(). The onReceive() method handles broadcasts—network changes, battery status, boot completed, SMS received. Ordered broadcasts allow priority and result propagation. Local broadcasts limit scope to app with LocalBroadcastManager. Permission requirements protect sensitive broadcasts. Background execution limits on Android 8+ require JobScheduler or WorkManager for most system events. Receivers enable responding to system state changes and inter-component communication. Common use cases include syncing on network availability, reacting to power changes, or handling custom app events.