Platform
android
Plugin
connectivity_plus
Version
6.1.5
Flutter SDK
3.14.0
Steps to reproduce
Bug Report: checkConnectivity() returns [ConnectivityResult.none] on Android when only VPN is active
Plugin
connectivity_plus
Version
6.1.5 (locked), constraint ^6.1.4
Platform
Android
Device
Samsung Galaxy A05s (SM-A057G/DSN), MediaTek Helio G85 chipset, One UI
Flutter SDK
3.24.0
Description
On Samsung Galaxy A05s, when the device is connected to the internet exclusively through a VPN (e.g., corporate VPN without a separate Wi-Fi/mobile data indicator), Connectivity().checkConnectivity() returns [ConnectivityResult.none] instead of [ConnectivityResult.vpn] or a list containing ConnectivityResult.vpn.
This causes the app to incorrectly determine that there is no network connectivity, even though the device has full internet access through the VPN tunnel.
Steps to Reproduce
- Use a Samsung Galaxy A05s (SM-A057G/DSN) running Android with One UI
- Connect to a VPN (corporate or third-party VPN app)
- Ensure internet is accessible through the VPN (verify by opening a browser)
- Call
Connectivity().checkConnectivity()
- Observe the returned result
Expected Behavior
checkConnectivity() should return a list containing ConnectivityResult.vpn (and possibly the underlying transport like ConnectivityResult.wifi or ConnectivityResult.mobile).
For example:
[ConnectivityResult.vpn]
// or
[ConnectivityResult.vpn, ConnectivityResult.wifi]
Actual Behavior
checkConnectivity() returns:
[ConnectivityResult.none]
This happens despite the device having full internet access through the VPN.
Root Cause Analysis
The issue is in the Android native implementation of connectivity_plus. The plugin uses Android's ConnectivityManager.getNetworkCapabilities() on the activeNetwork to determine transport types. It checks for:
NetworkCapabilities.TRANSPORT_WIFI → ConnectivityResult.wifi
NetworkCapabilities.TRANSPORT_CELLULAR → ConnectivityResult.mobile
NetworkCapabilities.TRANSPORT_VPN → ConnectivityResult.vpn
NetworkCapabilities.TRANSPORT_ETHERNET → ConnectivityResult.ethernet
However, on certain Android devices (particularly Samsung budget devices with MediaTek chipsets like the Galaxy A05s), the ConnectivityManager behaves differently when a VPN is active:
-
activeNetwork may return null: Some Samsung devices with custom network stacks don't properly expose the VPN network as the active network, causing getNetworkCapabilities() to return null, which the plugin maps to ConnectivityResult.none.
-
VPN transport not reported: On some devices, when a VPN is the sole active connection, getNetworkCapabilities() on the active network does not include TRANSPORT_VPN in the capabilities. This is a known Android platform behavior documented in multiple StackOverflow threads:
-
Samsung One UI network stack quirks: Samsung's custom Android implementation on budget chipsets (MediaTek Helio G85 in the A05s) has known inconsistencies in how NetworkCapabilities are reported for VPN connections compared to stock Android or Qualcomm-based Samsung devices.
Impact
This is a critical issue for enterprise apps that rely on connectivity_plus to gate API calls. When the plugin incorrectly reports ConnectivityResult.none, the app:
- Blocks all API calls thinking there is no internet
- Shows "no internet" error dialogs to the user
- Prevents data synchronization
- Breaks first-time app setup flows that require server data
The plugin's own README states: "Connection type availability does not guarantee that there is an Internet access." However, the inverse is also problematic — the plugin reports NO connection when there IS internet access via VPN.
Workaround
We are currently working around this by performing an actual reachability check (using internet_connection_checker package) when connectivity_plus returns ConnectivityResult.none:
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
class NetworkCheck {
Future<bool> check() async {
final List<ConnectivityResult> connectivityResult =
await (Connectivity().checkConnectivity());
if (connectivityResult.contains(ConnectivityResult.mobile)) {
return true;
} else if (connectivityResult.contains(ConnectivityResult.wifi)) {
return true;
} else if (connectivityResult.contains(ConnectivityResult.vpn)) {
return true;
} else if (connectivityResult.contains(ConnectivityResult.other)) {
return true;
} else if (connectivityResult.contains(ConnectivityResult.ethernet)) {
return true;
} else if (connectivityResult.contains(ConnectivityResult.none)) {
// Fallback: actual reachability check for devices where VPN
// is not properly reported by ConnectivityManager
try {
final hasConnection =
await InternetConnectionChecker.createInstance(
checkTimeout: const Duration(seconds: 5),
).hasConnection;
return hasConnection;
} catch (_) {
return false;
}
}
return false;
}
}
Suggested Fix
The Android native implementation should consider iterating over all networks (not just activeNetwork) when activeNetwork returns null capabilities, or when the capabilities don't include any known transport type. Android's ConnectivityManager.getAllNetworks() can be used as a fallback:
// Pseudocode for suggested fix in the Android plugin
val activeNetwork = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
if (capabilities == null) {
// Fallback: check all available networks
val allNetworks = connectivityManager.allNetworks
for (network in allNetworks) {
val caps = connectivityManager.getNetworkCapabilities(network)
if (caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
return listOf("vpn")
}
}
}
Alternatively, the plugin could check NET_CAPABILITY_INTERNET or NET_CAPABILITY_VALIDATED on available networks as a secondary signal.
Related Issues
Environment
Flutter 3.24.0
connectivity_plus: 6.1.5
Device: Samsung Galaxy A05s (SM-A057G/DSN)
Chipset: MediaTek Helio G85
Android Version: [fill in your exact Android version]
One UI Version: [fill in your One UI version]
VPN App Used: [fill in the VPN app name]
Checklist
Code Sample
Logs
Flutter Doctor
Checklist before submitting a bug
Platform
android
Plugin
connectivity_plus
Version
6.1.5
Flutter SDK
3.14.0
Steps to reproduce
Bug Report:
checkConnectivity()returns[ConnectivityResult.none]on Android when only VPN is activePlugin
connectivity_plusVersion
6.1.5(locked), constraint^6.1.4Platform
Android
Device
Samsung Galaxy A05s (SM-A057G/DSN), MediaTek Helio G85 chipset, One UI
Flutter SDK
3.24.0
Description
On Samsung Galaxy A05s, when the device is connected to the internet exclusively through a VPN (e.g., corporate VPN without a separate Wi-Fi/mobile data indicator),
Connectivity().checkConnectivity()returns[ConnectivityResult.none]instead of[ConnectivityResult.vpn]or a list containingConnectivityResult.vpn.This causes the app to incorrectly determine that there is no network connectivity, even though the device has full internet access through the VPN tunnel.
Steps to Reproduce
Connectivity().checkConnectivity()Expected Behavior
checkConnectivity()should return a list containingConnectivityResult.vpn(and possibly the underlying transport likeConnectivityResult.wifiorConnectivityResult.mobile).For example:
Actual Behavior
checkConnectivity()returns:[ConnectivityResult.none]This happens despite the device having full internet access through the VPN.
Root Cause Analysis
The issue is in the Android native implementation of
connectivity_plus. The plugin uses Android'sConnectivityManager.getNetworkCapabilities()on theactiveNetworkto determine transport types. It checks for:NetworkCapabilities.TRANSPORT_WIFI→ConnectivityResult.wifiNetworkCapabilities.TRANSPORT_CELLULAR→ConnectivityResult.mobileNetworkCapabilities.TRANSPORT_VPN→ConnectivityResult.vpnNetworkCapabilities.TRANSPORT_ETHERNET→ConnectivityResult.ethernetHowever, on certain Android devices (particularly Samsung budget devices with MediaTek chipsets like the Galaxy A05s), the
ConnectivityManagerbehaves differently when a VPN is active:activeNetworkmay returnnull: Some Samsung devices with custom network stacks don't properly expose the VPN network as the active network, causinggetNetworkCapabilities()to returnnull, which the plugin maps toConnectivityResult.none.VPN transport not reported: On some devices, when a VPN is the sole active connection,
getNetworkCapabilities()on the active network does not includeTRANSPORT_VPNin the capabilities. This is a known Android platform behavior documented in multiple StackOverflow threads:Samsung One UI network stack quirks: Samsung's custom Android implementation on budget chipsets (MediaTek Helio G85 in the A05s) has known inconsistencies in how
NetworkCapabilitiesare reported for VPN connections compared to stock Android or Qualcomm-based Samsung devices.Impact
This is a critical issue for enterprise apps that rely on
connectivity_plusto gate API calls. When the plugin incorrectly reportsConnectivityResult.none, the app:The plugin's own README states: "Connection type availability does not guarantee that there is an Internet access." However, the inverse is also problematic — the plugin reports NO connection when there IS internet access via VPN.
Workaround
We are currently working around this by performing an actual reachability check (using
internet_connection_checkerpackage) whenconnectivity_plusreturnsConnectivityResult.none:Suggested Fix
The Android native implementation should consider iterating over all networks (not just
activeNetwork) whenactiveNetworkreturns null capabilities, or when the capabilities don't include any known transport type. Android'sConnectivityManager.getAllNetworks()can be used as a fallback:Alternatively, the plugin could check
NET_CAPABILITY_INTERNETorNET_CAPABILITY_VALIDATEDon available networks as a secondary signal.Related Issues
[connectivity_plus] returns "none" on iOS always(similar issue on iOS, still open)checkConnectivity always return none on iOS 15.4[connectivity_plus] can't check wifi connection without internet accessConnectivity plus returns only ConnectivityResult.ethernet even when device is connected via LAN and WiFiEnvironment
Checklist
flutter cleanCode Sample
Logs
.Flutter Doctor
.Checklist before submitting a bug
flutter pub upgradeflutter clean