This AppStudio blog describes how we can use the Networking component to detect for network connectivity and classify the type of network (LAN, WIFI, Mobile Data). This allows you to build apps that can react differently dependent on what type of network they're on, e.g. ask the user whether they want to download content whilst on an expensive mobile data network.
Let's start with a minimal app that shows all Network connections whether active or inactive:
import QtQuick 2.7
import QtQuick.Controls 2.1
import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Networking 1.0
App {
width: 640 * AppFramework.displayScaleFactor
height: 480 * AppFramework.displayScaleFactor
Flickable {
anchors.fill: parent
contentWidth: textArea.width
contentHeight: textArea.height
TextArea {
id: textArea
text: JSON.stringify(Networking.configurations, undefined, 2)
}
}
}
On my Windows machine, I get:
{
"0": {
"objectName": "",
"valid": true,
"name": "vEthernet (Internal Ethernet Port Windows Phone Emulator Internal Switch) 2",
"identifier": "312537767",
"bearerType": 1,
"bearerTypeFamily": 1,
"bearerTypeName": "Ethernet",
"configurationType": 0,
"connectTimeout": 30000,
"purpose": 0,
"roamingAvailable": false,
"state": 14
},
"1": {
"objectName": "",
"valid": true,
"name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet8 Virtual Switch)",
"identifier": "287176532",
"bearerType": 1,
"bearerTypeFamily": 1,
"bearerTypeName": "Ethernet",
"configurationType": 0,
"connectTimeout": 30000,
"purpose": 0,
"roamingAvailable": false,
"state": 14
},
"2": {
"objectName": "",
"valid": true,
"name": "vEthernet (Default Switch)",
"identifier": "287176527",
"bearerType": 1,
"bearerTypeFamily": 1,
"bearerTypeName": "Ethernet",
"configurationType": 0,
"connectTimeout": 30000,
"purpose": 0,
"roamingAvailable": false,
"state": 14
},
"3": {
"objectName": "",
"valid": true,
"name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet1 Virtual Switch)",
"identifier": "312537825",
"bearerType": 1,
"bearerTypeFamily": 1,
"bearerTypeName": "Ethernet",
"configurationType": 0,
"connectTimeout": 30000,
"purpose": 0,
"roamingAvailable": false,
"state": 14
},
"4": {
"objectName": "",
"valid": true,
"name": "Bluetooth Network Connection",
"identifier": "312537798",
"bearerType": 1,
"bearerTypeFamily": 1,
"bearerTypeName": "Ethernet",
"configurationType": 0,
"connectTimeout": 30000,
"purpose": 0,
"roamingAvailable": false,
"state": 2
},
"5": {
"objectName": "",
"valid": true,
"name": "vEthernet (Intel(R) 82579LM Gigabit Network Connection Virtual Switch)",
"identifier": "312537802",
"bearerType": 1,
"bearerTypeFamily": 1,
"bearerTypeName": "Ethernet",
"configurationType": 0,
"connectTimeout": 30000,
"purpose": 0,
"roamingAvailable": false,
"state": 14
}
}
The things we observed about Networking.configurations are:
In order to filter the list down quickly, we transform the object to an array, then filter the results using Array.prototype.filter:
import QtQuick 2.7
import QtQuick.Controls 2.1
import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Networking 1.0
App {
width: 640 * AppFramework.displayScaleFactor
height: 480 * AppFramework.displayScaleFactor
Flickable {
anchors.fill: parent
contentWidth: textArea.width
contentHeight: textArea.height
TextArea {
id: textArea
text: JSON.stringify(
toArray(Networking.configurations)
.filter(isConfigActive)
.map(summary),
undefined, 2)
}
}
function toArray(o) {
return Object.keys(o).map(function (e) { return o[e]; } );
}
function isConfigActive(c) {
return (c.state & NetworkConfiguration.StateActive) === NetworkConfiguration.StateActive;
}
function summary(c) {
return {
name: c.name,
bearerType: c.bearerType
};
}
}
On my Windows machine, this reduces to an easier to read list:
[
{
"bearerType": 1,
"name": "vEthernet (Internal Ethernet Port Windows Phone Emulator Internal Switch) 2"
},
{
"bearerType": 1,
"name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet1 Virtual Switch)"
},
{
"bearerType": 1,
"name": "vEthernet (Default Switch)"
},
{
"bearerType": 1,
"name": "vEthernet (Intel(R) 82579LM Gigabit Network Connection Virtual Switch)"
},
{
"bearerType": 1,
"name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet8 Virtual Switch)"
}
]
On my Android device, when WIFI is enabled:
[
{
"bearerType": 2,
"name": "WIFI"
}
]
or, when Mobile Data is enabled:
[
{
"bearerType": 10,
"name": "Mobile"
}
]
On my iOS device, when WIFI is enabled:
[
{
"bearerType": 0,
"name": "en0"
},
{
"bearerType": 0,
"name": "awdl0"
},
{
"bearerType": 0,
"name": "utun0"
}
]
On Windows, Android and Linux the bearerType can be used to classify the network connection, e.g.
Whilst on iOS and macOS, the bearerType may not be provided by the operating system resulting in NetworkConfiguration.BearerUnknown. To cover iOS and macOS, we note that the name of the configuration instead:
function isConfigLAN(c) {
if (c.bearerType === NetworkConfiguration.BearerEthernet) {
return true;
}
if (Qt.platform.os === "osx") {
return c.name === "en0";
}
return false;
}
function isConfigWIFI(c) {
if (c.bearerType === NetworkConfiguration.BearerWLAN) {
return true;
}
if (Qt.platform.os === "ios") {
return c.name === "en0";
}
if (Qt.platform.os === "osx") {
return c.name === "awdl0";
}
return false;
}
function isConfigMobileData(c) {
switch (c.bearerType) {
case NetworkConfiguration.Bearer2G:
case NetworkConfiguration.BearerCDMA2000:
case NetworkConfiguration.BearerWCDMA:
case NetworkConfiguration.BearerHSPA:
case NetworkConfiguration.BearerWiMAX:
case NetworkConfiguration.BearerEVDO:
case NetworkConfiguration.BearerLTE:
case NetworkConfiguration.Bearer3G:
case NetworkConfiguration.Bearer4G:
return true;
}
if (Qt.platform.os === "ios") {
return c.name === "pdp_ip0";
}
return false;
}
function isConfigActiveLAN(c) {
return isConfigActive(c) && isConfigLAN(c);
}
function isConfigActiveWIFI(c) {
return isConfigActive(c) && isConfigWIFI(c);
}
function isConfigActiveMobileData(c) {
return isConfigActive(c) && isConfigMobileData(c);
}
Now that we have these useful functions, we can quickly chain them together to determine whether we're on WIFI or MobileData. Because we convert the object to an array, we can make use of Array.prototype.some to quickly lookup a network configuration of a particular type:
property var config: toArray(Networking.configurations)
property bool isOnline: isLAN || isWIFI || isMobileData
property bool isLAN: config.some(isConfigActiveLAN)
property bool isWIFI: config.some(isConfigActiveWIFI)
property bool isMobileData: config.some(isConfigActiveMobileData)
property bool isMobileDataOnly: isMobileData && !isWIFI && !isLAN
The "Network Check" app is available for you to try which demonstrates all of the above points. You can find "Network Check" app in AppStudio.
The "Network Check" source code is also avilable at arcgis-appstudio-samples GitHub.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.