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.
Related snips
package com.example.myapp
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
Dependency injection with Hilt
package com.example.myapp.ui
import androidx.lifecycle.*
import kotlinx.coroutines.launch
class UserViewModel(
LiveData transformations and mediators
package com.example.myapp.utils
import android.os.Build
import android.os.StrictMode
import android.os.Trace
import timber.log.Timber
Performance optimization and profiling
package com.example.myapp.widget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
App widgets for home screen
package com.example.myapp.data.repository
import com.example.myapp.data.local.PostDao
import com.example.myapp.data.local.PostEntity
import com.example.myapp.data.remote.ApiService
import com.example.myapp.models.Post
Unit testing with JUnit and MockK
package com.example.myapp.utils
import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.app.PendingIntent
Notification channels and categories
Share this code
Here's the card — post it anywhere.