Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-network-information",
"version": "3.0.0-dev",
"version": "3.0.1-dev",
"description": "Cordova Network Information Plugin",
"types": "./types/index.d.ts",
"cordova": {
Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-network-information"
version="3.0.0-dev">
version="3.0.1-dev">

<name>Network Information</name>
<description>Cordova Network Information Plugin</description>
Expand Down
199 changes: 153 additions & 46 deletions src/android/NetworkManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,28 @@ Licensed to the Apache Software Foundation (ASF) under one
import org.apache.cordova.PluginResult;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.telephony.ServiceState;

import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;

import java.util.Locale;

import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE;

public class NetworkManager extends CordovaPlugin {

public static int NOT_REACHABLE = 0;
Expand All @@ -46,17 +55,17 @@ public class NetworkManager extends CordovaPlugin {

public static final String WIFI = "wifi";
public static final String WIMAX = "wimax";
// mobile
// mobile
public static final String MOBILE = "mobile";

// Android L calls this Cellular, because I have no idea!
// Android L calls this Cellular, because I have no idea!
public static final String CELLULAR = "cellular";
// 2G network types
// 2G network types
public static final String TWO_G = "2g";
public static final String GSM = "gsm";
public static final String GPRS = "gprs";
public static final String EDGE = "edge";
// 3G network types
// 3G network types
public static final String THREE_G = "3g";
public static final String CDMA = "cdma";
public static final String UMTS = "umts";
Expand All @@ -65,11 +74,16 @@ public class NetworkManager extends CordovaPlugin {
public static final String HSDPA = "hsdpa";
public static final String ONEXRTT = "1xrtt";
public static final String EHRPD = "ehrpd";
// 4G network types
// 4G network types
public static final String FOUR_G = "4g";
public static final String LTE = "lte";
public static final String UMB = "umb";
public static final String HSPA_PLUS = "hspa+";

// 5G network types
public static final String FIVE_G = "5g";
public static final String NR = "nr";

// return type
public static final String TYPE_UNKNOWN = "unknown";
public static final String TYPE_ETHERNET = "ethernet";
Expand All @@ -78,29 +92,37 @@ public class NetworkManager extends CordovaPlugin {
public static final String TYPE_2G = "2g";
public static final String TYPE_3G = "3g";
public static final String TYPE_4G = "4g";
public static final String TYPE_5G = "5g";
public static final String TYPE_NONE = "none";

public static final int NETWORK_TYPE_NR = 20;
public static final int NETWORK_TYPE_LTE_CA = 19;

private static final String LOG_TAG = "NetworkManager";

private CallbackContext connectionCallbackContext;

ConnectivityManager sockMan;
BroadcastReceiver receiver;
private String lastTypeOfNetwork;
private String lastTypeOfNetwork = TYPE_UNKNOWN;
TelephonyManager telMan;
private static boolean isNrAvailable;

/**
* Sets the context of the Command. This can then be used to do things like
* get file paths associated with the Activity.
*
* @param cordova The context of the main Activity.
* @param webView The CordovaWebView Cordova is running in.
*/
* Sets the context of the Command. This can then be used to do things like
* get file paths associated with the Activity.
*
* @param cordova The context of the main Activity.
* @param webView The CordovaWebView Cordova is running in.
*/
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
this.sockMan = (ConnectivityManager) cordova.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
this.connectionCallbackContext = null;
super.initialize(cordova, webView);
this.sockMan = (ConnectivityManager) cordova.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
this.telMan = (TelephonyManager) cordova.getActivity().getSystemService(Context.TELEPHONY_SERVICE);
this.telMan.listen( phoneStateListener, LISTEN_SERVICE_STATE);
this.connectionCallbackContext = null;

this.registerConnectivityActionReceiver();
this.registerConnectivityActionReceiver();
}

/**
Expand Down Expand Up @@ -158,7 +180,7 @@ private void registerConnectivityActionReceiver() {
public void onReceive(Context context, Intent intent) {
// (The null check is for the ARM Emulator, please use Intel Emulator for better results)
if (NetworkManager.this.webView != null) {
updateConnectionInfo(sockMan.getActiveNetworkInfo());
updateConnectionInfo(sockMan.getActiveNetworkInfo(), true);
}

String connectionType;
Expand Down Expand Up @@ -204,10 +226,10 @@ private void unregisterReceiver() {
* @param info the current active network info
* @return
*/
private void updateConnectionInfo(NetworkInfo info) {
private void updateConnectionInfo(NetworkInfo info, boolean forceRefresh) {
// send update to javascript "navigator.connection"
// Jellybean sends its own info
String currentNetworkType = this.getTypeOfNetworkFallbackToTypeNoneIfNotConnected(info);
String currentNetworkType = this.getTypeOfNetworkFallbackToTypeNoneIfNotConnected(info, forceRefresh);
if (currentNetworkType.equals(this.lastTypeOfNetwork)) {
LOG.d(LOG_TAG, "Networkinfo state didn't change, there is no event propagated to the JavaScript side.");
} else {
Expand All @@ -222,16 +244,20 @@ private void updateConnectionInfo(NetworkInfo info) {
* @param info the current active network info
* @return type the type of network
*/
private String getTypeOfNetworkFallbackToTypeNoneIfNotConnected(NetworkInfo info) {
@RequiresApi(api = Build.VERSION_CODES.N)
private String getTypeOfNetworkFallbackToTypeNoneIfNotConnected(NetworkInfo info, Boolean forceRefresh) {
// the info might still be null in this part of the code
String type;
if (info != null) {
// If we are not connected to any network set type to none
if (!info.isConnected()) {
type = TYPE_NONE;
}
else {
type = getType(info);
} else {
if(lastTypeOfNetwork.equals(TYPE_UNKNOWN) || forceRefresh) {
type = getType(info);
} else {
type = lastTypeOfNetwork;
}
}
} else {
type = TYPE_NONE;
Expand All @@ -240,6 +266,11 @@ private String getTypeOfNetworkFallbackToTypeNoneIfNotConnected(NetworkInfo info
LOG.d(LOG_TAG, "Connection Type: " + type);
return type;
}
@RequiresApi(api = Build.VERSION_CODES.N)
private String getTypeOfNetworkFallbackToTypeNoneIfNotConnected(NetworkInfo info) {
// the info might still be null in this part of the code
return this.getTypeOfNetworkFallbackToTypeNoneIfNotConnected(info, false);
}

/**
* Create a new plugin result and send it back to JavaScript
Expand All @@ -259,7 +290,7 @@ private void sendUpdate(String type) {
* Determine the type of connection
*
* @param info the network info so we can determine connection type.
* @return the type of mobile network we are on
* @return the type of network we are on
*/
private String getType(NetworkInfo info) {
String type = info.getTypeName().toLowerCase(Locale.US);
Expand All @@ -270,28 +301,104 @@ private String getType(NetworkInfo info) {
} else if (type.toLowerCase().equals(TYPE_ETHERNET) || type.toLowerCase().startsWith(TYPE_ETHERNET_SHORT)) {
return TYPE_ETHERNET;
} else if (type.equals(MOBILE) || type.equals(CELLULAR)) {
type = info.getSubtypeName().toLowerCase(Locale.US);
if (type.equals(GSM) ||
type.equals(GPRS) ||
type.equals(EDGE) ||
type.equals(TWO_G)) {
return TYPE_2G;
} else if (type.startsWith(CDMA) ||
type.equals(UMTS) ||
type.equals(ONEXRTT) ||
type.equals(EHRPD) ||
type.equals(HSUPA) ||
type.equals(HSDPA) ||
type.equals(HSPA) ||
type.equals(THREE_G)) {
return TYPE_3G;
} else if (type.equals(LTE) ||
type.equals(UMB) ||
type.equals(HSPA_PLUS) ||
type.equals(FOUR_G)) {
return TYPE_4G;
return getMobileType(info);
}
return TYPE_UNKNOWN;
}

/**
* Determine the subtype of mobile connection
*
* @param info the network info so we can determine connection type.
* @return the type of mobile network we are on
*/
private String getMobileType(NetworkInfo info){
int subTypeId = info.getSubtype();
String subTypeName = info.getSubtypeName().toLowerCase(Locale.US);
if(is2G(subTypeId, subTypeName)){
return TYPE_2G;
} else if(is3G(subTypeId, subTypeName)) {
return TYPE_3G;
} else if(is4G(subTypeId, subTypeName)) {
if(isNrAvailable){ // if is LTE network could be 5g if NR is available
return TYPE_5G;
}
return TYPE_4G;
} else if(is5G(subTypeId, subTypeName)) {
return TYPE_5G;
}
return TYPE_UNKNOWN;
}

private boolean is2G(int type, String name){
return type == TelephonyManager.NETWORK_TYPE_GPRS ||
type == TelephonyManager.NETWORK_TYPE_EDGE ||
type == TelephonyManager.NETWORK_TYPE_CDMA ||
type == TelephonyManager.NETWORK_TYPE_1xRTT ||
type == TelephonyManager.NETWORK_TYPE_IDEN || // api< 8: replace by 11
type == TelephonyManager.NETWORK_TYPE_GSM || // api<25: replace by 16
name.equals(GSM) ||
name.equals(GPRS) ||
name.equals(EDGE) ||
name.equals(TWO_G);
}

private boolean is3G(int type, String name){
return type == TelephonyManager.NETWORK_TYPE_UMTS ||
type == TelephonyManager.NETWORK_TYPE_EVDO_0 ||
type == TelephonyManager.NETWORK_TYPE_EVDO_A ||
type == TelephonyManager.NETWORK_TYPE_HSDPA ||
type == TelephonyManager.NETWORK_TYPE_HSUPA ||
type == TelephonyManager.NETWORK_TYPE_HSPA ||
type == TelephonyManager.NETWORK_TYPE_EVDO_B || // api< 9: replace by 12
type == TelephonyManager.NETWORK_TYPE_EHRPD || // api<11: replace by 14
type == TelephonyManager.NETWORK_TYPE_HSPAP || // api<13: replace by 15
type == TelephonyManager.NETWORK_TYPE_TD_SCDMA || // api<25: replace by 17
name.startsWith(CDMA) ||
name.equals(UMTS) ||
name.equals(ONEXRTT) ||
name.equals(EHRPD) ||
name.equals(HSUPA) ||
name.equals(HSDPA) ||
name.equals(HSPA) ||
name.equals(THREE_G);
}

private boolean is4G(int type, String name){

return type == TelephonyManager.NETWORK_TYPE_LTE || // api<11: replace by 13
type == TelephonyManager.NETWORK_TYPE_IWLAN || // api<25: replace by 18
type == NETWORK_TYPE_LTE_CA || // LTE_CA
name.equals(LTE) ||
name.equals(UMB) ||
name.equals(HSPA_PLUS) ||
name.equals(FOUR_G);
}

private boolean is5G(int type, String name){

return type == TelephonyManager.NETWORK_TYPE_LTE || // api<11: replace by 13
type == NETWORK_TYPE_NR || // api<25: replace by 18
name.equals(FIVE_G) ||
name.equals(NR);
}

private PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
NetworkManager.this.isNrAvailable = isNrAvailable(serviceState);
updateConnectionInfo(sockMan.getActiveNetworkInfo(), true);
}
};

/**
* Determine if NR network is available, for detect sdk < 30
*
* @param serviceState the ServiceState from PhoneStateListener
* @return flag boolean if NR is available
*/
private boolean isNrAvailable(ServiceState serviceState ){
String stateStr = serviceState.toString();
return stateStr.contains("nrState=CONNECTED") || stateStr.contains("isNrAvailable = true");
}
}
13 changes: 10 additions & 3 deletions src/ios/CDVConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ - (NSString*)w3cConnectionTypeFor:(CDVReachability*)reachability
return @"3g";
} else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
return @"4g";
} else if (@available(iOS 14.0, *)) {
if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyNRNSA]) {
return @"5g";
} else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyNR]) {
return @"5g";
}
}
}
return @"cellular";
Expand All @@ -104,9 +110,10 @@ - (NSString*)w3cConnectionTypeFor:(CDVReachability*)reachability
- (BOOL)isCellularConnection:(NSString*)theConnectionType
{
return [theConnectionType isEqualToString:@"2g"] ||
[theConnectionType isEqualToString:@"3g"] ||
[theConnectionType isEqualToString:@"4g"] ||
[theConnectionType isEqualToString:@"cellular"];
[theConnectionType isEqualToString:@"3g"] ||
[theConnectionType isEqualToString:@"4g"] ||
[theConnectionType isEqualToString:@"5g"] ||
[theConnectionType isEqualToString:@"cellular"];
}

- (void)updateReachability:(CDVReachability*)reachability
Expand Down
2 changes: 2 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ exports.defineAutoTests = function () {
cellular: 1,
'3g': 1,
'4g': 1,
'5g': 1,
none: 1
};
expect(validValues[navigator.connection.type]).toBe(1);
Expand All @@ -49,6 +50,7 @@ exports.defineAutoTests = function () {
expect(Connection.CELL_2G).toBe('2g');
expect(Connection.CELL_3G).toBe('3g');
expect(Connection.CELL_4G).toBe('4g');
expect(Connection.CELL_5G).toBe('5g');
expect(Connection.NONE).toBe('none');
expect(Connection.CELL).toBe('cellular');
});
Expand Down
2 changes: 2 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ interface Connection {
* Connection.CELL_2G
* Connection.CELL_3G
* Connection.CELL_4G
* Connection.CELL_5G
* Connection.CELL
* Connection.NONE
*/
Expand All @@ -57,6 +58,7 @@ declare var Connection: {
CELL_2G: string;
CELL_3G: string;
CELL_4G: string;
CELL_5G: string;
CELL: string;
NONE: string;
}
Loading