un-snooze notification - android

I am using a notification listener to snooze unwanted notifications, but how do I un-snooze these once my app is no longer running? Currently they only way I have found to do this is the user must reboot their phone.
This is how I am snoozing the notification, I found out I can use getSnoozedNotifications to get a list of snoozed apps, but what is the command to un-snooze it?
snoozeNotification(sbn.getKey(), Long.MAX_VALUE - System.currentTimeMillis());
And this is how I get the snoozed apps, I just can't find anywhere that tells me the command to un-snooze it, I have even tried to set the duration to 0.
private void clearSnoozedNotifications()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
StatusBarNotification sbns[] = getSnoozedNotifications();
for (StatusBarNotification sbn : sbns) {
try {
if (sbn == null) {
Log.e("Notification Listener", "sbn is null");
return;
}
Log.e("Notification Listener", "Starting: " + sbn.getKey());
snoozeNotification(sbn.getKey(), 0);
} catch (Exception e) {
Log.e("Notification Listener", "error: " + e.getMessage());
}
}
}
}

I have observed on Android 11 that you can restore the notification by calling snoozeNotification on the same key with a low duration number greater than zero.
For example I use the following:
snoozeNotification(key, 100L);
On earlier versions of Android the notifications will re-appear after a reboot when they have been snoozed, in Android 11 they won't.

Related

How can I disable receiving notifications If the app is running in the Background? - Kotlin

I want to add functionality to my App to disable and enable notifications.
and for the notification I will use firebase cloud messaging "service push notifications"
If the app is running in the foreground then I will check a variable "showNotification" in the onMessageReceived function to show the notifications or not
if(showNotification) {
if (remoteMessage.notification != null) {
generateNot(
remoteMessage.notification!!.title!!,
remoteMessage.notification!!.body!!
)
}
}
The challenge I have is when the app is running in the background and since notifications are only displayed by the system when the app is not active.
Is there a way to disable showing notifications if the app is running in the background when the variable showNotification is false ?
I solved this problem using another method. you can override handleIntent instead of onMessageReceived. by using this method you are able to handle notification received from the firebase in foreground or background.
override fun handleIntent(intent: Intent?) {
val body = intent!!.getStringExtra("gcm.notification.body").toString()
val title = intent.getStringExtra("gcm.notification.title").toString()
try {
if(isAppOnForeground()){
// your app is running in the foreground
}else {
// your app is running in the background
}
} catch (e: Exception) {
Log.e("handleIntent: ", e.toString())
}
}
also you can get title and body using the code above. also with function below you can check if your app is in the background or not.
private fun isAppOnForeground(): Boolean {
return ProcessLifecycleOwner.get().lifecycle.currentState
.isAtLeast(Lifecycle.State.STARTED)
}

Keep screen off while receiving notification and device is locked

I googled a lot to manage notifications and I found that can be done using Notification Listener but I am stuck with the problem that is, I want to keep screen off (not event blinking of light) while receiving notification.
I used following code:
if (Build.VERSION.SDK_INT >= 23) {
if ((notificationManager != null) && !notificationManager.isNotificationPolicyAccessGranted()) {
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivityForResult(intent, RQS_ENABLE_DO_NOT_DISTURB_SCREEN_FLASH);
} else {
if (b) {
notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
} else {
notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
}
}
} else {
Toast.makeText(this, "Don't have notification policy permissions", Toast.LENGTH_LONG);
}
Can anyone give me idea to do this?
Your help would be appreciated. Thank you.

Geofence events not always called

This is how I add my geofences:
public void setGeofenceRequest(Location location) {
if (geofences == null) {
geofences = new ArrayList<Geofence>();
}
geofences.add(new Geofence.Builder()
.setRequestId("3")
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
.setCircularRegion(
location.getLatitude(), location.getLongitude(), PSLocationService.getInstance(context).kPSGeofencingDistanceMedium)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build());
Intent intent = new Intent(context, ReceiveTransitionsBroadcastReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (geofences.size() > 0) {
LocationServices.GeofencingApi.addGeofences(mLocationClient, geofences, pi);
Log.i("", "geof autopilot2 will set geofence for autopilot-3");
}
}
And this is my BroadcastReceiver. Where I should receive them:
public class ReceiveTransitionsBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
Log.i("","autopilot valid geof on receive transisionts broadcast receiver");
PSMotionService.getInstance(ctx).buildGoogleApiClient();
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
int transitionType = geofencingEvent.getGeofenceTransition();
Location geofenceCenter = PSApplicationClass.getInstance().pref.getGeoCenter(ctx);
if(geofencingEvent.getTriggeringLocation() != null) {
if (geofenceCenter != null) {
Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver TRIGGERING LOCATION: " + geofencingEvent.getTriggeringLocation().toString() + " / GEOFENCE CENTER: " + geofenceCenter.getLatitude() + ", " + geofenceCenter.getLongitude(), "D", Constants.TRACKER);
} else
Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver TRIGGERING LOCATION: " + geofencingEvent.getTriggeringLocation().toString(), "D", Constants.TRACKER);
}else Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver ERROR => TRIGGERING LOCATION NULL", "D", Constants.TRACKER);
if(transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
List<Geofence> triggerList = geofencingEvent.getTriggeringGeofences();
for (Geofence geofence : triggerList) {
Log.i("", "geof is s receive transition broadcast receiver " + transitionType + " GPS zone " + geofence.getRequestId());
if(geofence.getRequestId().contentEquals("3")) {
Log.i("", "geof autopilot2 ENTERED GEOFENCE will start pilot with first location");
Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver check to see if should start pilot", "T", Constants.TRACKER);
PSLocationService.getInstance(ctx).fastGPS = -1;
PSLocationService.getInstance(ctx).RequestLocationUpdates();
if(PSTrip.getActiveTrip() != null) {
PSLocationService.getInstance(ctx).removeAutoPilotGeofence();
}else PSMotionService.getInstance(ctx).checkinTime = System.currentTimeMillis() / 1000;
}
}
}
}
}
Now usually it works, but not always. I would say that only about 75% of the time it should work, the geofence events are actually called. I feel like the more time since I've set the geofence, the less likely it will be to be called.
Why is this happening? Is the triggering event also being dismissed, when the app is cleaned by the garbage collector?
How can I make it so that my geofence is always being called, when the case?
EDIT:
This is my defaultConfig:
defaultConfig {
minSdkVersion 15
targetSdkVersion 23
ndk {
moduleName "ndkVidyoSample"
}
}
I changed from a Broadcast Receiver to a IntentService:
public class PSGeofenceTransitionsIntentService extends IntentService {
private static ActivityManager manager;
private static PSGeofenceTransitionsIntentService instance;
private GeofencingClient mGeofencingClient;
Context context;
private PendingIntent mGeofencePendingIntent;
public static boolean isMyServiceRunning(Class<?> serviceClass) {
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
public static PSGeofenceTransitionsIntentService getInstance(Context context) {
if (instance == null) {
// Create the instance
instance = new PSGeofenceTransitionsIntentService(context);
}
if (!isMyServiceRunning(PSGeofenceTransitionsIntentService.class)) {
Intent bindIntent = new Intent(context, PSGeofenceTransitionsIntentService.class);
context.startService(bindIntent);
}
// Return the instance
return instance;
}
public PSGeofenceTransitionsIntentService() {
super("GeofenceTransitionsIntentService");
}
public PSGeofenceTransitionsIntentService(Context context) {
super("GeofenceTransitionsIntentService");
mGeofencingClient = LocationServices.getGeofencingClient(context);
manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
instance = this;
this.context = context;
}
protected void onHandleIntent(Intent intent) {
Log.i("", "autopilot valid geof on receive transisionts broadcast receiver");
PSMotionService.getInstance(context).buildGoogleApiClient();
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
int transitionType = geofencingEvent.getGeofenceTransition();
Location geofenceCenter = PSApplicationClass.getInstance().pref.getGeoCenter(context);
if (geofencingEvent.getTriggeringLocation() != null) {
if (geofenceCenter != null) {
Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver TRIGGERING LOCATION: " + geofencingEvent.getTriggeringLocation().toString() + " / GEOFENCE CENTER: " + geofenceCenter.getLatitude() + ", " + geofenceCenter.getLongitude(), "D", Constants.TRACKER);
} else
Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver TRIGGERING LOCATION: " + geofencingEvent.getTriggeringLocation().toString(), "D", Constants.TRACKER);
} else
Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver ERROR => TRIGGERING LOCATION NULL", "D", Constants.TRACKER);
if (transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
List<Geofence> triggerList = geofencingEvent.getTriggeringGeofences();
for (Geofence geofence : triggerList) {
Log.i("", "geof is s receive transition broadcast receiver " + transitionType + " GPS zone " + geofence.getRequestId());
if (geofence.getRequestId().contentEquals("3")) {
Log.i("", "geof autopilot2 ENTERED GEOFENCE will start pilot with first location");
Utils.appendLog("GEOFENCE ENTERED ReceiveTransitionsBroadcastReceiver check to see if should start pilot", "T", Constants.TRACKER);
PSLocationService.getInstance(context).isLocationRequestsOn = -1;
PSLocationService.getInstance(context).RequestLocationUpdates();
if (PSTrip.getActiveTrip() != null) {
removeAutoPilotGeofence();
} else
PSMotionService.getInstance(context).checkinTime = System.currentTimeMillis() / 1000;
}
}
}
}
public void removeAutoPilotGeofence() {
try {
Log.i("", "autopilot remove autopilot geofence");
List<String> list = new ArrayList<String>();
list.add("3");
if(mGeofencingClient == null)
mGeofencingClient = LocationServices.getGeofencingClient(context);
mGeofencingClient.removeGeofences(list).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Utils.appendLog("GEOFENCE removeAutoPilotGeofence Success removing geofences!", "I", Constants.TRACKER);
Log.i("", "GEOFENCE removeAutoPilotGeofence Success removing geofences!");
PSApplicationClass.getInstance().pref.setGeoCenterString(context, "-1");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Utils.appendLog("GEOFENCE removeAutoPilotGeofence FAILURE removing geofences!" + e.getMessage(), "I", Constants.TRACKER);
Log.i("", "GEOFENCE removeAutoPilotGeofence FAILURE removing geofences!" + e.getMessage());
}
});
Utils.appendLog("GEOFENCE: Disabling geofence done removeAutoPilotGeofence", "E", Constants.TRACKER);
} catch (final Exception e) {
if (e.getMessage().contains("GoogleApiClient") && e.getMessage().contains("not connected")) {
PSLocationService.getInstance(context).startLocationClient();
Handler han = new Handler();
han.postDelayed(new Runnable() {
#Override
public void run() {
Utils.appendLog("autopilot2 error will try again", "E", Constants.TRACKER);
removeAutoPilotGeofence();
}
}, 1000);
}
Log.i("", "autopilot2 error replaceFragment autopilot geofence:" + e.getMessage());
Utils.appendLog("autopilot2 error replaceFragment autopilot geofence:" + e.getMessage(), "E", Constants.TRACKER);
}
}
public void setGeofenceRequest(final Location location) {
ArrayList geofences = new ArrayList<>();
geofences.add(new Geofence.Builder()
.setRequestId("3")
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
.setCircularRegion(
location.getLatitude(), location.getLongitude(), PSLocationService.kPSGeofencingDistanceMedium)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build());
//ADDING GEOFENCES
if (geofences.size() > 0) {
if(mGeofencingClient == null)
mGeofencingClient = LocationServices.getGeofencingClient(context);
mGeofencingClient.addGeofences(getGeofencingRequest(location, geofences), getGeofencePendingIntent()).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
RealmLocation realmLocation = new RealmLocation(location.getLatitude(), location.getLongitude(), location.getTime() / 1000, null, true);
realmLocation.setAccuracy(location.getAccuracy());
realmLocation.setSpeed(location.getSpeed());
PSApplicationClass.getInstance().pref.setGeoCenter(realmLocation, context);
Utils.appendLog("GEOFENCE setGeofenceRequest Success adding geofences!" + location.getLatitude() + " / " + location.getLongitude(), "I", Constants.TRACKER);
Log.i("", "GEOFENCE setGeofenceRequest Success adding geofences! " + location.getLatitude() + " / " + location.getLongitude());
PSLocationService.getInstance(context).stopLocationClient();
PSMotionService.getInstance(context).buildGoogleApiClient();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Utils.appendLog("GEOFENCE setGeofenceRequest FAILURE adding geofences!" + e.getMessage(), "I", Constants.TRACKER);
Log.i("", "GEOFENCE setGeofenceRequest FAILURE adding geofences!" + e.getMessage());
}
});
Log.i("", "geof autopilot2 will set geofence for autopilot-3");
}
}
/**
* Gets a PendingIntent to send with the request to add or remove Geofences. Location Services
* issues the Intent inside this PendingIntent whenever a geofence transition occurs for the
* current list of geofences.
*
* #return A PendingIntent for the IntentService that handles geofence transitions.
*/
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
Intent intent = new Intent(context, PSGeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling
// addGeofences() and removeGeofences().
return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/**
* Builds and returns a GeofencingRequest. Specifies the list of geofences to be monitored.
* Also specifies how the geofence notifications are initially triggered.
*/
private GeofencingRequest getGeofencingRequest(Location location, ArrayList<Geofence> geofences) {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
// The INITIAL_TRIGGER_ENTER flag indicates that geofencing service should trigger a
// GEOFENCE_TRANSITION_ENTER notification when the geofence is added and if the device
// is already inside that geofence.
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_EXIT);
// Add the geofences to be monitored by geofencing service.
builder.addGeofences(geofences);
// Return a GeofencingRequest.
return builder.build();
}
}
I have in it also the code to remove and add the geofences, and the listener always goes into onSuccess regarding adding them.
For starters, I would not put this code inside a BroadcastReceiver.
Besides being bad practice, the component might be shutdown before the code has finished executing.
Please consider starting a Service from your Receiver, if you need to run code that might take some time.
Otherwise for a short execution time, you may use an IntentService.
By looking at your code, I'm aware of two reasons your Geofences are not working as expected:
1) The nature of Geofences
Geofences API retrieves your location mostly from WiFi / Cellular Data, which is often unavailable.
I tried to use Geofences once, and I found them very inaccurate. I switched to LocationManager making it use pure GPS location and it met my expectations.
Please see this answer, which advises to
Poll the GPS hardware on an interval without doing anything with the result and you'll start getting more accurate geofences.
I have never tried Google's FusedLocation API, but I have heard people saying it worked very well for them.
If you use LocationManager, you will have to implement your 'Geofencing logic' yourself; you can easily do it with Location.distanceTo(Location).
Example:
final float distanceFromCenter = currentLocation.distanceTo(this.destination);
if (distanceFromCenter <= YOUR_RADIUS_IN_METERS) {
// you are inside your geofence
}
2) CPU is not active
The fact that the Geofences are active, does not necessarily mean that your phone is awake and computing location checks.
To fix that, you can start a ForegroundService from your BroacastReceiver. The Service should hold a partial WakeLock as well.
This guarantees that:
The OS does not kill the service (or better: less chance to be killed...)
The user is aware of the service and can dismiss it if necessary
The CPU is running. Therefore you can be sure that the code that retrieves the location is running (please remember to to release the WakeLock when the service stops).
Please note that Android may still kill your service if necessary.
You can find plenty of examples on the web on how to start a ForegroundService from a BroadcastReceiver, how to hold a WakeLock and so on...
Also, check out to the new Android O API, that brought some minor changes to the ForegroundService and other components.
PS: I have developed and application that uses all the components mentioned above (except for the FusedLocation) and I was extremely satisfied.
EDIT: Answering OP's questions
Okey, let's try to make some order here, otherwise future readers may easily get confused. I'll start by answering what written in the original question and the 'bounty banner', then the OP edits, and finally the questions the OP placed in the comments.
1) Original question
Is the triggering event also being dismissed, when the app is cleaned by the garbage collector?
Most probably yes. See this answer where OP implemented a service that runs in a separate process, in order to make geofence be triggered even when the app is killed.
I need to understand what causes the geofences not to get called, if enough time has passed
Plenty of reasons. See my original answer.
I saw an implementation of the geofence logic with an Service instead of a broadcast receiver, will that work better?
A Receiver and a Service are two different things. Please read Android's documentation. You can start a Service from a BroadcastReceiver, which is usually the preferred way to 'receive' PendingIntents and do something with them.
2) Edits
Please note that I did not tell you to replace the BroadcastReceiver with a Service, but that it might be a good idea to start a Service from your Receiver and handle all your logic there.
Making your IntentService a Singleton class is not necessary as (from IntentService documentation)
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
Do not store Context into a Singleton class or some static references. I'm impressed Android Studio did not warn you.
3) Comments
I need this to work 24/7 hence I cannot use the location all the time, cause of obvious battery issues.
Please read Android Oreo Background Execution Limits. This might be an issue for you.
Also now that I changed to a intentService, is that enough to ensure it should stay awake?
No, as I said, you probably need a partial WakeLock in order to turn on the CPU.
Do I need to initiate it another way, in order to keep it in the foreground?
Yes. In order to start a Foreground Service, you need to call startForeground(int, Notification)
Please note: IntentServices lifespan is limited to the end of the onHandleIntent() function. They are not supposed to live for more than a few seconds, typically. Use the Service class if you want to start a Foreground.
Moreover, as said in the original answer, a new Foreground API is available and preferred for Android Oreo.
Not a question, just a notice: I need to use here Geofencing. (Geofencing will start if necessary the gps
Ok perfect. See what works best for you.

How to remove a specific "system notification" in android?

I'm want to remove the "system" screenshot notification. I already achieved it, using the Notification Listener Service and the ID which I got from my phone. But I found out that the ID for the system notification is changing on some samsung and other devices. How can I make sure to remove the notification also on other devices. is there a different way to detect that the system screenshot notification has shown? Some specific TAG?
Edit: This how I do it right now:
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
//super.onNotificationPosted(sbn);
Log.i(TAG, "ID: " + sbn.getId());
Log.i(TAG, "Package: " + sbn.getPackageName());
//Remove Notification
if (sbn.getId() == 2131820569) {
if(status.getBoolean("comboserviceaktiv",false) || status.getBoolean("serviceaktiv",false) && standardprefs.getBoolean("settings_silent",false)){
if(Build.VERSION.SDK_INT >= 21) {
this.cancelNotification(sbn.getKey());
Log.i(TAG, "System Screenshot Notification deleted");
} else {
this.cancelNotification(sbn.getPackageName(),sbn.getTag(),sbn.getId());
Log.i(TAG, "System Sreenshot Notification deleted");
}
}
}
}
Thank you very much!

Paho MQTT AlarmPingSender wakelock stucked

I am using Paho Android Service for my project (app name is Sealer). (link)
I've tested it about 22 hours and the result has brought me a strange result.
It seems that my app keeps awake the CPU a very long time (~10,5 h).
I've searched in the source code by wakelock tag and found that the wakelock tag belongs to the AlarmPingSender class. Has anybody met this problem ever ?
I didn't modify the Android Service source code, it's the original.
I've attached some screenshots (Hangouts and Viber just for comparison).
Screenshots
EDIT 1.
There is a code snippet from my source code:
mqttOptions = new MqttConnectOptions();
mqttOptions.setCleanSession(false);
// defaultKeepAlive is 240
mqttOptions.setKeepAliveInterval(Constants.defaultKeepAlive);
EDIT 2
I think this is the relevant code from Android Service source code:
/*
* This class sends PingReq packet to MQTT broker
*/
class AlarmReceiver extends BroadcastReceiver {
private WakeLock wakelock;
private String wakeLockTag = MqttServiceConstants.PING_WAKELOCK
+ that.comms.getClient().getClientId();
#Override
public void onReceive(Context context, Intent intent) {
// According to the docs, "Alarm Manager holds a CPU wake lock as
// long as the alarm receiver's onReceive() method is executing.
// This guarantees that the phone will not sleep until you have
// finished handling the broadcast.", but this class still get
// a wake lock to wait for ping finished.
int count = intent.getIntExtra(Intent.EXTRA_ALARM_COUNT, -1);
Log.d(TAG, "Ping " + count + " times.");
Log.d(TAG, "Check time :" + System.currentTimeMillis());
IMqttToken token = comms.checkForActivity();
// No ping has been sent.
if (token == null) {
return;
}
// Assign new callback to token to execute code after PingResq
// arrives. Get another wakelock even receiver already has one,
// release it until ping response returns.
if (wakelock == null) {
PowerManager pm = (PowerManager) service
.getSystemService(Service.POWER_SERVICE);
wakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
wakeLockTag);
}
wakelock.acquire();
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d(TAG, "Success. Release lock(" + wakeLockTag + "):"
+ System.currentTimeMillis());
//Release wakelock when it is done.
if(wakelock != null && wakelock.isHeld()){
wakelock.release();
}
}
#Override
public void onFailure(IMqttToken asyncActionToken,
Throwable exception) {
Log.d(TAG, "Failure. Release lock(" + wakeLockTag + "):"
+ System.currentTimeMillis());
//Release wakelock when it is done.
if(wakelock != null && wakelock.isHeld()){
wakelock.release();
}
}
});
}
}
It seems (at least according to the screenshots) that the wakelock somehow is 'stucked', doesn't released.
I have the same problem and created a bug report. Please have a look for further help: https://bugs.eclipse.org/bugs/show_bug.cgi?id=480134
The ping sender will need to wake up to send a ping at what ever keep alive period is configured. The app needs to wake to send the packet that keeps the connection alive. I've not played with the Paho Android service but you should be able to change this by adding the relevant values to the MQTTConnectOptions object passed to the MQTTAndoridClient.connect() method.
EDIT:
e.g.
MQTTConnectOptions opts = new MQTTConnectOptions();
opts.setConnectionTimeout(240000);
client.connect(opts);

Categories

Resources