[Android] Create NetworkMonitor in tools

Geoffrey Métais git at videolan.org
Fri Dec 27 12:17:03 CET 2019


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Thu Dec 26 15:47:50 2019 +0100| [d4d297ab08a37e3c3e3bf9488c7abced0249536d] | committer: Geoffrey Métais

Create NetworkMonitor in tools

Make it VLC independant to be used un modules

> https://code.videolan.org/videolan/vlc-android/commit/d4d297ab08a37e3c3e3bf9488c7abced0249536d
---

 .../main/java/org/videolan/tools/NetworkMonitor.kt | 99 ++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt b/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt
new file mode 100644
index 000000000..bc176dd4e
--- /dev/null
+++ b/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt
@@ -0,0 +1,99 @@
+package org.videolan.tools
+
+import android.annotation.SuppressLint
+import android.annotation.TargetApi
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
+import android.os.Build
+import androidx.lifecycle.*
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import java.lang.ref.WeakReference
+import java.net.NetworkInterface
+import java.net.SocketException
+
+interface NetworkObserver {
+    fun onNetworkChanged()
+}
+
+class NetworkMonitor(private val context: Context) : LifecycleObserver {
+    private var registered = false
+    private val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+    val connected = MutableLiveData<Boolean>()
+    @Volatile
+    var isMobile = true
+        private set
+    @Volatile
+    var isVPN = false
+        private set
+    private var networkObservers: MutableList<WeakReference<NetworkObserver>> = mutableListOf()
+
+    init {
+        ProcessLifecycleOwner.get().lifecycle.addObserver(this at NetworkMonitor)
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_START)
+    fun start() {
+        if (registered) return
+        registered = true
+        val networkFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
+        context.registerReceiver(receiver, networkFilter)
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+    fun stop() {
+        registered = false
+        context.unregisterReceiver(receiver)
+    }
+
+    @SuppressLint("MissingPermission")
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    private fun updateVPNStatus(): Boolean {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            for (network in cm.allNetworks) {
+                val nc = cm.getNetworkCapabilities(network) ?: return false
+                if (nc.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) return true
+            }
+            return false
+        } else {
+            try {
+                val networkInterfaces = NetworkInterface.getNetworkInterfaces()
+                while (networkInterfaces.hasMoreElements()) {
+                    val networkInterface = networkInterfaces.nextElement()
+                    val name = networkInterface.displayName
+                    if (name.startsWith("ppp") || name.startsWith("tun") || name.startsWith("tap"))
+                        return true
+                }
+            } catch (ignored: SocketException) {}
+            return false
+        }
+    }
+
+    val receiver = object : BroadcastReceiver() {
+        @SuppressLint("MissingPermission")
+        override fun onReceive(context: Context?, intent: Intent?) {
+            when (intent?.action) {
+                ConnectivityManager.CONNECTIVITY_ACTION -> {
+                    val networkInfo = cm.activeNetworkInfo
+                    val isConnected = networkInfo != null && networkInfo.isConnected
+                    isMobile = isConnected && networkInfo!!.type == ConnectivityManager.TYPE_MOBILE
+                    isVPN = isConnected && updateVPNStatus()
+                    if (connected.value == null || isConnected != connected.value) {
+                        connected.value = isConnected
+                    }
+                    networkObservers.forEach { it.get()?.onNetworkChanged() }
+                }
+
+            }
+        }
+
+    }
+
+    companion object : SingletonHolder<NetworkMonitor, Context>({ NetworkMonitor(it) })
+}



More information about the Android mailing list