/*
- * Copyright (C) 2012-2015 Tobias Brunner
+ * Copyright (C) 2012-2019 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
+import android.net.Network;
import android.net.NetworkInfo;
+import android.net.NetworkRequest;
+import android.os.Build;
import java.util.LinkedList;
{
private final Context mContext;
private volatile boolean mRegistered;
+ private ConnectivityManager.NetworkCallback mCallback;
private Thread mEventNotifier;
+ private int mConnectedNetworks = 0;
private LinkedList<Boolean> mEvents = new LinkedList<>();
public NetworkManager(Context context)
{
mContext = context;
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ {
+ mCallback = new ConnectivityManager.NetworkCallback()
+ {
+ @Override
+ public void onAvailable(Network network)
+ {
+ synchronized (NetworkManager.this)
+ {
+ /* we expect this to be called if connected to at least one network during
+ * callback registration */
+ mConnectedNetworks += 1;
+ mEvents.addLast(true);
+ NetworkManager.this.notifyAll();
+ }
+ }
+
+ @Override
+ public void onLost(Network network)
+ {
+ synchronized (NetworkManager.this)
+ {
+ /* in particular mobile connections are disconnected overlapping with WiFi */
+ mConnectedNetworks -= 1;
+ mEvents.addLast(mConnectedNetworks > 0);
+ NetworkManager.this.notifyAll();
+ }
+ }
+ };
+ }
}
public void Register()
mRegistered = true;
mEventNotifier = new Thread(this);
mEventNotifier.start();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ {
+ ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+ /* while we only get events for the VPN network via registerDefaultNetworkCallback,
+ * the default capabilities in the builder include NetworkCapabilities.NET_CAPABILITY_NOT_VPN */
+ NetworkRequest.Builder builder = new NetworkRequest.Builder();
+ cm.registerNetworkCallback(builder.build(), mCallback);
+ }
+ else
+ {
+ registerLegacyReceiver();
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void registerLegacyReceiver()
+ {
+ /* deprecated since API level 28 */
mContext.registerReceiver(this, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
public void Unregister()
{
- mContext.unregisterReceiver(this);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ {
+ ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+ cm.unregisterNetworkCallback(mCallback);
+ }
+ else
+ {
+ mContext.unregisterReceiver(this);
+ }
mRegistered = false;
synchronized (this)
{