Jeremy K
Jeremy K

Reputation: 543

Android dropping tcp connection when screen is off

My Android app starts and keeps a TCP connection going within a Foreground service. The activity uses StartService() to start the service. Also the service is started in it's own process.

Here is the services OnStartCommand:

// Code is in C# using Xamarin but regular Java/Android answers are acceptable
public override StartCommandResult OnStartCommand (Intent intent, StartCommandFlags flags, int startId)
{
    base.OnStartCommand (intent, flags, startId);

    ...

    var ongoingNotification = new Notification (Resource.Drawable.icon, "Service running");
    var pendingIntent = PendingIntent.GetActivity (this, 0, new Intent (this, typeof(MainActivity)), 0);
    ongoingNotification.SetLatestEventInfo (this, "Service", "The service is running.", pendingIntent);
    StartForeground ((int)NotificationFlags.ForegroundService, ongoingNotification);
    return StartCommandResult.RedeliverIntent;
}

The connection is fine when the phone's screen is on, whether or not an activity from my app is open or not. However less than 30 seconds after I turn the screen off I always lose tcp connection. My app reconnects automatically so I get the connection back, but it will continually disconnect when the screen is off. I turn it back on and it's fine, even if an activity from my app isn't open.

It could be connected to the Android Lifecycle but I just don't see how. Based on debug messages I write to a text file on the phone (the issue doesn't happen when a debugger from an IDE is attached), the service seems to be operating as it's supposed to but the connection just isn't being stable.

I've also tested this with and without the "Don't Keep Activities" in Developer options selected to no change. So it shouldn't have anything to do with the Activity Lifecycle at least.

Why is Android dropping my tcp connection, but only when the screen is off?

Upvotes: 3

Views: 2942

Answers (1)

Jeremy K
Jeremy K

Reputation: 543

I solved the problem by acquiring a Partial WakeLock while my service is running.

private PowerManager.WakeLock mWakeLock;

public override void OnCreate ()
{
    PowerManager pm = (PowerManager) GetSystemService(Context.PowerService);
    mWakeLock = pm.NewWakeLock (WakeLockFlags.Partial, "PartialWakeLockTag");
    mWakeLock.Acquire();
}

public override void OnDestroy ()
{
    mWakeLock.Release();
}

If I implement something more power efficient in the future, I'll update this answer.

Upvotes: 2

Related Questions