Network Monitoring¶
Network monitoring automatically detects internet connectivity changes and notifies your application, enabling intelligent reconnection strategies and user experience improvements.
Overview¶
Mobile devices frequently switch between network types: - WiFi ↔ Cellular data - Network disconnections - Airplane mode toggles - Poor signal areas
Network monitoring helps your app respond appropriately to these changes.
Configuration¶
Enable Network Monitoring¶
Configure through the bridge:
class MyBridge : PulseMqttKitBridge {
override fun getNetworkConfig(): NetworkMonitoringConfig {
return NetworkMonitoringConfig(enabled = true)
}
// Other bridge methods...
}
Disable Network Monitoring¶
override fun getNetworkConfig(): NetworkMonitoringConfig {
return NetworkMonitoringConfig(enabled = false) // Default
}
Receiving Network Events¶
Implement [MqttUpdatesListener.onInternetConnectionStatusChanged]:
class NetworkAwareListener : MqttUpdatesListener {
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
if (isConnected) {
logger.info("Network connected")
handleNetworkRestored()
} else {
logger.warning("Network disconnected")
handleNetworkLost()
}
}
private fun handleNetworkRestored() {
// Check if MQTT needs reconnection
if (pulseMqttKit.isConnected() == false) {
pulseMqttKit.submitCommand(ConnectCommand(connectionOptions))
}
// Update UI
showOnlineIndicator()
}
private fun handleNetworkLost() {
// Pause non-critical operations
pauseBackgroundSync()
// Update UI
showOfflineIndicator()
showNetworkErrorMessage()
}
}
pulseMqttKit.addListener(NetworkAwareListener())
Usage Patterns¶
Pattern 1: Intelligent Reconnection¶
class SmartReconnectionHandler : MqttUpdatesListener {
private var wasDisconnectedDueToNetwork = false
override fun onMqttConnectionLost(cause: Throwable?) {
// Mark as potentially network-related
wasDisconnectedDueToNetwork = true
}
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
if (isConnected && wasDisconnectedDueToNetwork) {
logger.info("Network restored, attempting reconnection")
pulseMqttKit.submitCommand(
ConnectCommand(
connectionOptions = connectionOptions,
retryPolicy = RetryPolicy.exponential(
maxRetries = 3,
baseDelayMillis = 1000
)
)
)
wasDisconnectedDueToNetwork = false
}
}
}
Pattern 2: Network Type Detection¶
class NetworkTypeHandler(private val context: Context) : MqttUpdatesListener {
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
if (isConnected) {
val networkType = getNetworkType()
adjustBehaviorForNetwork(networkType)
}
}
private fun getNetworkType(): NetworkType {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork = cm.activeNetwork ?: return NetworkType.NONE
val capabilities = cm.getNetworkCapabilities(activeNetwork) ?: return NetworkType.NONE
return when {
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> NetworkType.WIFI
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> NetworkType.CELLULAR
else -> NetworkType.OTHER
}
}
private fun adjustBehaviorForNetwork(networkType: NetworkType) {
when (networkType) {
NetworkType.WIFI -> {
// Use normal settings
setKeepAlive(30)
enableLargePayloads(true)
}
NetworkType.CELLULAR -> {
// Optimize for cellular
setKeepAlive(60)
enableLargePayloads(false)
}
else -> {
// Conservative settings
setKeepAlive(45)
}
}
}
}
enum class NetworkType {
WIFI, CELLULAR, OTHER, NONE
}
Pattern 3: User Notifications¶
class NetworkNotificationHandler(
private val notificationManager: NotificationManager
) : MqttUpdatesListener {
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
if (isConnected) {
dismissOfflineNotification()
showReconnectingNotification()
} else {
showOfflineNotification()
}
}
override fun onMqttConnectComplete(reconnect: Boolean, serverUri: String?) {
if (reconnect) {
dismissReconnectingNotification()
showBriefSuccessMessage()
}
}
private fun showOfflineNotification() {
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_offline)
.setContentTitle("No Internet Connection")
.setContentText("Waiting for network to reconnect...")
.setPriority(NotificationCompat.PRIORITY_LOW)
.build()
notificationManager.notify(OFFLINE_NOTIFICATION_ID, notification)
}
}
Best Practices¶
1. Always Enable for Mobile Apps¶
2. Combine with Health Monitoring¶
class ComprehensiveMonitoring : MqttUpdatesListener {
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
if (isConnected) {
// Network back - start health monitoring
pulseMqttKit.startHealthMonitoring()
} else {
// Network lost - stop health monitoring (save battery)
pulseMqttKit.stopHealthMonitoring()
}
}
}
3. Provide User Feedback¶
// ✅ Good - Keep users informed
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
if (!isConnected) {
showSnackbar("No internet connection. Messages will be queued.")
}
}
4. Handle Rapid Network Changes¶
class DebounceNetworkChanges : MqttUpdatesListener {
private var networkChangeJob: Job? = null
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
// Cancel pending reconnection
networkChangeJob?.cancel()
if (isConnected) {
// Wait 2 seconds before reconnecting (debounce)
networkChangeJob = coroutineScope.launch {
delay(2000)
attemptReconnection()
}
}
}
}
Required Permissions¶
Add to AndroidManifest.xml:
<!-- Required for network monitoring -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Troubleshooting¶
Problem: Network events not received¶
Check:
1. Network monitoring is enabled
2. ACCESS_NETWORK_STATE permission granted
3. Listener is registered
// Verify configuration
val config = bridge.getNetworkConfig()
logger.debug("Network monitoring enabled: ${config.enabled}")
Problem: False positive network events¶
Solution: Add debouncing:
private var lastNetworkState = false
private val debounceDelay = 1000L
override fun onInternetConnectionStatusChanged(isConnected: Boolean) {
if (isConnected != lastNetworkState) {
delay(debounceDelay)
if (isConnected == currentNetworkState()) {
lastNetworkState = isConnected
handleNetworkChange(isConnected)
}
}
}
Next Steps¶
- Learn about Health Monitoring
- Explore Auto-Subscription
- See Connection Management