Merge pull request #41 from eternal-flame-AD/upstream-patch-network
listen for network changes
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.github.gotify.service;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import com.github.gotify.log.Log;
|
||||||
|
|
||||||
|
public class ReconnectListener extends BroadcastReceiver {
|
||||||
|
|
||||||
|
private Runnable reconnected;
|
||||||
|
|
||||||
|
ReconnectListener(Runnable reconnected) {
|
||||||
|
this.reconnected = reconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
ConnectivityManager cm =
|
||||||
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
|
||||||
|
NetworkInfo network = cm.getActiveNetworkInfo();
|
||||||
|
|
||||||
|
if (network != null && network.isConnected()) {
|
||||||
|
Log.i("Network reconnected");
|
||||||
|
reconnected.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.github.gotify.service;
|
package com.github.gotify.service;
|
||||||
|
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import com.github.gotify.SSLSettings;
|
import com.github.gotify.SSLSettings;
|
||||||
import com.github.gotify.Utils;
|
import com.github.gotify.Utils;
|
||||||
@@ -16,9 +18,11 @@ import okhttp3.WebSocket;
|
|||||||
import okhttp3.WebSocketListener;
|
import okhttp3.WebSocketListener;
|
||||||
|
|
||||||
public class WebSocketConnection {
|
public class WebSocketConnection {
|
||||||
|
private final ConnectivityManager connectivityManager;
|
||||||
private OkHttpClient client;
|
private OkHttpClient client;
|
||||||
|
|
||||||
private final Handler handler = new Handler();
|
private final Handler reconnectHandler = new Handler();
|
||||||
|
private Runnable reconnectCallback = this::start;
|
||||||
private int errorCount = 0;
|
private int errorCount = 0;
|
||||||
|
|
||||||
private final String baseUrl;
|
private final String baseUrl;
|
||||||
@@ -28,11 +32,17 @@ public class WebSocketConnection {
|
|||||||
private Runnable onClose;
|
private Runnable onClose;
|
||||||
private Runnable onOpen;
|
private Runnable onOpen;
|
||||||
private BadRequestRunnable onBadRequest;
|
private BadRequestRunnable onBadRequest;
|
||||||
private OnFailureCallback onFailure;
|
private OnNetworkFailureRunnable onNetworkFailure;
|
||||||
private Runnable onReconnected;
|
private Runnable onReconnected;
|
||||||
private boolean isClosed;
|
private boolean isClosed;
|
||||||
|
private Runnable onDisconnect;
|
||||||
|
|
||||||
WebSocketConnection(String baseUrl, SSLSettings settings, String token) {
|
WebSocketConnection(
|
||||||
|
String baseUrl,
|
||||||
|
SSLSettings settings,
|
||||||
|
String token,
|
||||||
|
ConnectivityManager connectivityManager) {
|
||||||
|
this.connectivityManager = connectivityManager;
|
||||||
OkHttpClient.Builder builder =
|
OkHttpClient.Builder builder =
|
||||||
new OkHttpClient.Builder()
|
new OkHttpClient.Builder()
|
||||||
.readTimeout(0, TimeUnit.MILLISECONDS)
|
.readTimeout(0, TimeUnit.MILLISECONDS)
|
||||||
@@ -66,8 +76,13 @@ public class WebSocketConnection {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized WebSocketConnection onFailure(OnFailureCallback onFailure) {
|
synchronized WebSocketConnection onDisconnect(Runnable onDisconnect) {
|
||||||
this.onFailure = onFailure;
|
this.onDisconnect = onDisconnect;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized WebSocketConnection onNetworkFailure(OnNetworkFailureRunnable onNetworkFailure) {
|
||||||
|
this.onNetworkFailure = onNetworkFailure;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +119,18 @@ public class WebSocketConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void scheduleReconnect(long millis) {
|
||||||
|
reconnectHandler.removeCallbacks(reconnectCallback);
|
||||||
|
|
||||||
|
Log.i(
|
||||||
|
"WebSocket: scheduling a restart in "
|
||||||
|
+ TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS)
|
||||||
|
+ " second(s)");
|
||||||
|
reconnectHandler.postDelayed(reconnectCallback, millis);
|
||||||
|
}
|
||||||
|
|
||||||
private class Listener extends WebSocketListener {
|
private class Listener extends WebSocketListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(WebSocket webSocket, Response response) {
|
public void onOpen(WebSocket webSocket, Response response) {
|
||||||
Log.i("WebSocket: opened");
|
Log.i("WebSocket: opened");
|
||||||
@@ -153,14 +179,19 @@ public class WebSocketConnection {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int minutes = Math.min(errorCount * 2 + 1, 20);
|
|
||||||
|
|
||||||
Log.i("WebSocket: trying to restart in " + minutes + " minute(s)");
|
|
||||||
|
|
||||||
errorCount++;
|
errorCount++;
|
||||||
handler.postDelayed(
|
|
||||||
WebSocketConnection.this::start, TimeUnit.MINUTES.toMillis(minutes));
|
NetworkInfo network = connectivityManager.getActiveNetworkInfo();
|
||||||
onFailure.execute(minutes);
|
if (network == null || !network.isConnected()) {
|
||||||
|
Log.i("WebSocket: Network not connected");
|
||||||
|
onDisconnect.run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int minutes = Math.min(errorCount * 2 - 1, 20);
|
||||||
|
|
||||||
|
onNetworkFailure.execute(minutes);
|
||||||
|
scheduleReconnect(TimeUnit.MINUTES.toMillis(minutes));
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onFailure(webSocket, t, response);
|
super.onFailure(webSocket, t, response);
|
||||||
@@ -171,7 +202,7 @@ public class WebSocketConnection {
|
|||||||
void execute(String message);
|
void execute(String message);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnFailureCallback {
|
interface OnNetworkFailureRunnable {
|
||||||
void execute(int minutesToTryAgain);
|
void execute(long millis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import android.app.PendingIntent;
|
|||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -25,6 +27,7 @@ import com.github.gotify.log.Log;
|
|||||||
import com.github.gotify.log.UncaughtExceptionHandler;
|
import com.github.gotify.log.UncaughtExceptionHandler;
|
||||||
import com.github.gotify.messages.MessagesActivity;
|
import com.github.gotify.messages.MessagesActivity;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class WebSocketService extends Service {
|
public class WebSocketService extends Service {
|
||||||
@@ -84,15 +87,38 @@ public class WebSocketService extends Service {
|
|||||||
missingMessageUtil.lastReceivedMessage(lastReceivedMessage::set);
|
missingMessageUtil.lastReceivedMessage(lastReceivedMessage::set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConnectivityManager cm =
|
||||||
|
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
|
||||||
connection =
|
connection =
|
||||||
new WebSocketConnection(settings.url(), settings.sslSettings(), settings.token())
|
new WebSocketConnection(
|
||||||
|
settings.url(), settings.sslSettings(), settings.token(), cm)
|
||||||
.onOpen(this::onOpen)
|
.onOpen(this::onOpen)
|
||||||
.onClose(() -> foreground(getString(R.string.websocket_closed)))
|
.onClose(() -> foreground(getString(R.string.websocket_closed)))
|
||||||
.onBadRequest(this::onBadRequest)
|
.onBadRequest(this::onBadRequest)
|
||||||
.onFailure((min) -> foreground(getString(R.string.websocket_failed, min)))
|
.onNetworkFailure(
|
||||||
|
(min) -> foreground(getString(R.string.websocket_failed, min)))
|
||||||
|
.onDisconnect(this::onDisconnect)
|
||||||
.onMessage(this::onMessage)
|
.onMessage(this::onMessage)
|
||||||
.onReconnected(this::notifyMissedNotifications)
|
.onReconnected(this::notifyMissedNotifications)
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||||
|
ReconnectListener receiver = new ReconnectListener(this::doReconnect);
|
||||||
|
registerReceiver(receiver, intentFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDisconnect() {
|
||||||
|
foreground(getString(R.string.websocket_no_network));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doReconnect() {
|
||||||
|
if (connection == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.scheduleReconnect(TimeUnit.SECONDS.toMillis(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onBadRequest(String message) {
|
private void onBadRequest(String message) {
|
||||||
|
|||||||
@@ -57,4 +57,5 @@
|
|||||||
<string name="warning">Warning</string>
|
<string name="warning">Warning</string>
|
||||||
<string name="http_warning">Using http is insecure and it\'s recommend to use https instead. Use your favorite search engine to get more information about this topic.</string>
|
<string name="http_warning">Using http is insecure and it\'s recommend to use https instead. Use your favorite search engine to get more information about this topic.</string>
|
||||||
<string name="i_understand">I Understand</string>
|
<string name="i_understand">I Understand</string>
|
||||||
|
<string name="websocket_no_network">Waiting for network</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user