paho Android MQTT client does not send PINGREQ to broker when phone screen is off
04:50 02 Dec 2025

I have a small android app implementing a foreground service which communicates with mosquito mqtt broker, using paho MQTTClient: org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5
Everything is fine except the case when screen is off and charging cable disconnected.
In this case, it gets disconnected from broker because “has exceeded timeout”, which is caused by the fact that client doesn’t send any pingreq.
If screen is on (locked or not) and no charging cable connected I can see the pingreq every keepalive interval.
The same when screen is off with charging cable connected. It’s the same behavior on Android 9 and 14 Regarding android settings

  • on A14 I allowed the app “to use battery in the background without any restrictions” (unrestricted mode), in the app settings.
  • on A9 its allowed background activity and no battery optimization

The service is started in MainActivity in a standard way with

onCreate (Bundle savedInstanceState)
  {
  ...
  startService(new Intent(this, MQTTService.class));
  ...
  }

And in MQTTService class

public int onStartCommand(Intent intent, int flags, int startId)
        {
        Intent notIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notIntent, PendingIntent.FLAG_IMMUTABLE);
        Notification not = new NotificationCompat.Builder(this, CHANNEL_ID)
                                   .setContentTitle("MQTT listener")
                                   .setContentText("connecting to broker...")
                                   .setSmallIcon(R.drawable.ic_mqtt)
                                   .setContentIntent(pendingIntent)
                                   .setColor(getColor(R.color.white))
                                   .setOngoing(true)
                                   .setPriority(PRIORITY_MAX)
                                   .build();
        not.flags = Notification.FLAG_ONGOING_EVENT;
        startForeground(NOT_STATE_ID, not);
        connect2Server();
        Log.d(TAG, "onStartCommand()");
        isRunning = true;
        return START_STICKY;
        }

What am I missing here?

java android mqtt paho