expo-network 4.0.3 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,11 +10,19 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- ## 4.0.32021-10-21
13
+ ## 4.2.0 — 2022-04-18
14
14
 
15
- _This version does not introduce any user-facing changes._
15
+ ### ⚠️ Notices
16
+
17
+ - On Android bump `compileSdkVersion` to `31`, `targetSdkVersion` to `31` and `Java` version to `11`. ([#16941](https://github.com/expo/expo/pull/16941) by [@bbarthec](https://github.com/bbarthec))
18
+
19
+ ## 4.1.1 - 2022-02-01
20
+
21
+ ### 🐛 Bug fixes
22
+
23
+ - Fix `Plugin with id 'maven' not found` build error from Android Gradle 7. ([#16080](https://github.com/expo/expo/pull/16080) by [@kudo](https://github.com/kudo))
16
24
 
17
- ## 4.0.2 — 2021-10-15
25
+ ## 4.1.0 — 2021-12-03
18
26
 
19
27
  _This version does not introduce any user-facing changes._
20
28
 
@@ -35,6 +43,7 @@ _This version does not introduce any user-facing changes._
35
43
  ### 💡 Others
36
44
 
37
45
  - Migrated from `@unimodules/core` to `expo-modules-core`. ([#13757](https://github.com/expo/expo/pull/13757) by [@tsapeta](https://github.com/tsapeta))
46
+ - Rewrite Android code to Kotlin. ([#14474](https://github.com/expo/expo/pull/14474) by [@kkafar](https://github.com/kkafar))
38
47
 
39
48
  ## 3.2.0 — 2021-06-16
40
49
 
package/README.md CHANGED
@@ -2,20 +2,20 @@
2
2
 
3
3
  Gets device's network information such as ip address, mac address and check for airplane mode.
4
4
 
5
- See [<ModuleName> docs](https://docs.expo.io/versions/latest/sdk/<module-docs-name>) for documentation of this universal module's API.
5
+ See [<ModuleName> docs](https://docs.expo.dev/versions/latest/sdk/<module-docs-name>) for documentation of this universal module's API.
6
6
 
7
7
  # API documentation
8
8
 
9
- - [Documentation for the master branch](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/sdk/network.md)
10
- - [Documentation for the latest stable release](https://docs.expo.io/versions/latest/sdk/network/)
9
+ - [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/network.md)
10
+ - [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/network/)
11
11
 
12
12
  # Installation in managed Expo projects
13
13
 
14
- For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.io/versions/latest/sdk/network/).
14
+ For [managed](https://docs.expo.dev/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/network/).
15
15
 
16
16
  # Installation in bare React Native projects
17
17
 
18
- For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
18
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
19
19
 
20
20
  ### Add the package to your npm dependencies
21
21
 
@@ -1,63 +1,80 @@
1
1
  apply plugin: 'com.android.library'
2
2
  apply plugin: 'kotlin-android'
3
- apply plugin: 'maven'
3
+ apply plugin: 'maven-publish'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '4.0.3'
6
+ version = '4.2.0'
7
7
 
8
8
  buildscript {
9
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
10
+ if (expoModulesCorePlugin.exists()) {
11
+ apply from: expoModulesCorePlugin
12
+ applyKotlinExpoModulesCorePlugin()
13
+ }
14
+
9
15
  // Simple helper that allows the root project to override versions declared by this library.
10
16
  ext.safeExtGet = { prop, fallback ->
11
17
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
12
18
  }
13
19
 
20
+ // Ensures backward compatibility
21
+ ext.getKotlinVersion = {
22
+ if (ext.has("kotlinVersion")) {
23
+ ext.kotlinVersion()
24
+ } else {
25
+ ext.safeExtGet("kotlinVersion", "1.6.10")
26
+ }
27
+ }
28
+
14
29
  repositories {
15
30
  mavenCentral()
16
31
  }
17
32
 
18
33
  dependencies {
19
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', '1.4.21')}")
34
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
20
35
  }
21
36
  }
22
37
 
23
- // Upload android library to maven with javadoc and android sources
24
- configurations {
25
- deployerJars
26
- }
27
-
28
38
  // Creating sources with comments
29
39
  task androidSourcesJar(type: Jar) {
30
40
  classifier = 'sources'
31
41
  from android.sourceSets.main.java.srcDirs
32
42
  }
33
43
 
34
- // Put the androidSources and javadoc to the artifacts
35
- artifacts {
36
- archives androidSourcesJar
37
- }
38
-
39
- uploadArchives {
40
- repositories {
41
- mavenDeployer {
42
- configuration = configurations.deployerJars
43
- repository(url: mavenLocal().url)
44
+ afterEvaluate {
45
+ publishing {
46
+ publications {
47
+ release(MavenPublication) {
48
+ from components.release
49
+ // Add additional sourcesJar to artifacts
50
+ artifact(androidSourcesJar)
51
+ }
52
+ }
53
+ repositories {
54
+ maven {
55
+ url = mavenLocal().url
56
+ }
44
57
  }
45
58
  }
46
59
  }
47
60
 
48
61
  android {
49
- compileSdkVersion safeExtGet("compileSdkVersion", 30)
62
+ compileSdkVersion safeExtGet("compileSdkVersion", 31)
50
63
 
51
64
  compileOptions {
52
- sourceCompatibility JavaVersion.VERSION_1_8
53
- targetCompatibility JavaVersion.VERSION_1_8
65
+ sourceCompatibility JavaVersion.VERSION_11
66
+ targetCompatibility JavaVersion.VERSION_11
67
+ }
68
+
69
+ kotlinOptions {
70
+ jvmTarget = JavaVersion.VERSION_11.majorVersion
54
71
  }
55
72
 
56
73
  defaultConfig {
57
74
  minSdkVersion safeExtGet("minSdkVersion", 21)
58
- targetSdkVersion safeExtGet("targetSdkVersion", 30)
75
+ targetSdkVersion safeExtGet("targetSdkVersion", 31)
59
76
  versionCode 11
60
- versionName '4.0.3'
77
+ versionName '4.2.0'
61
78
  }
62
79
  lintOptions {
63
80
  abortOnError false
@@ -67,5 +84,5 @@ android {
67
84
  dependencies {
68
85
  implementation project(':expo-modules-core')
69
86
 
70
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${safeExtGet('kotlinVersion', '1.4.21')}"
87
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
71
88
  }
@@ -0,0 +1,154 @@
1
+ package expo.modules.network
2
+
3
+ import expo.modules.core.Promise
4
+ import expo.modules.core.ExportedModule
5
+ import expo.modules.core.interfaces.ExpoMethod
6
+ import expo.modules.core.interfaces.RegistryLifecycleListener
7
+
8
+ import android.util.Log
9
+ import android.os.Build
10
+ import android.os.Bundle
11
+ import android.content.Context
12
+ import android.net.NetworkInfo
13
+ import android.net.wifi.WifiInfo
14
+ import android.net.wifi.WifiManager
15
+ import android.net.ConnectivityManager
16
+ import android.net.NetworkCapabilities
17
+ import android.provider.Settings
18
+
19
+ import java.lang.Exception
20
+ import java.math.BigInteger
21
+ import java.net.InetAddress
22
+ import java.net.UnknownHostException
23
+ import java.nio.ByteOrder
24
+
25
+ private const val NAME = "ExpoNetwork"
26
+ private val TAG = NetworkModule::class.java.simpleName
27
+
28
+ class NetworkModule(private val appContext: Context) : ExportedModule(appContext), RegistryLifecycleListener {
29
+
30
+ enum class NetworkStateType(val value: String) {
31
+ NONE("NONE"),
32
+ UNKNOWN("UNKNOWN"),
33
+ CELLULAR("CELLULAR"),
34
+ WIFI("WIFI"),
35
+ BLUETOOTH("BLUETOOTH"),
36
+ ETHERNET("ETHERNET"),
37
+ WIMAX("WIMAX"),
38
+ VPN("VPN"),
39
+ OTHER("OTHER");
40
+
41
+ val isDefined: Boolean
42
+ get() = this.value != "NONE" && this.value != "UNKNOWN"
43
+ }
44
+
45
+ override fun getName() = NAME
46
+
47
+ private val wifiInfo: WifiInfo
48
+ get() = try {
49
+ val manager = appContext.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
50
+ manager.connectionInfo
51
+ } catch (e: Exception) {
52
+ Log.e(TAG, e.message ?: "Wi-Fi information could not be acquired")
53
+ throw e
54
+ }
55
+
56
+ private fun getConnectionType(netInfo: NetworkInfo?): NetworkStateType = when (netInfo?.type) {
57
+ ConnectivityManager.TYPE_MOBILE,
58
+ ConnectivityManager.TYPE_MOBILE_DUN -> NetworkStateType.CELLULAR
59
+ ConnectivityManager.TYPE_WIFI -> NetworkStateType.WIFI
60
+ ConnectivityManager.TYPE_BLUETOOTH -> NetworkStateType.BLUETOOTH
61
+ ConnectivityManager.TYPE_ETHERNET -> NetworkStateType.ETHERNET
62
+ ConnectivityManager.TYPE_WIMAX -> NetworkStateType.WIMAX
63
+ ConnectivityManager.TYPE_VPN -> NetworkStateType.VPN
64
+ else -> NetworkStateType.UNKNOWN
65
+ }
66
+
67
+ private fun getConnectionType(netCapabilities: NetworkCapabilities?): NetworkStateType =
68
+ when {
69
+ netCapabilities == null -> NetworkStateType.UNKNOWN
70
+ netCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> NetworkStateType.CELLULAR
71
+ netCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || netCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE) -> NetworkStateType.WIFI
72
+ netCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> NetworkStateType.BLUETOOTH
73
+ netCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> NetworkStateType.ETHERNET
74
+ netCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> NetworkStateType.VPN
75
+ else -> NetworkStateType.UNKNOWN
76
+ }
77
+
78
+ private fun rawIpToString(ip: Int): String {
79
+ // Convert little-endian to big-endian if needed
80
+ val ip = if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
81
+ Integer.reverseBytes(ip)
82
+ } else {
83
+ ip
84
+ }
85
+
86
+ var ipByteArray = BigInteger.valueOf(ip.toLong()).toByteArray()
87
+ if (ipByteArray.size < 4) {
88
+ ipByteArray = frontPadWithZeros(ipByteArray)
89
+ }
90
+
91
+ return try {
92
+ InetAddress.getByAddress(ipByteArray).hostAddress
93
+ } catch (e: UnknownHostException) {
94
+ "0.0.0.0"
95
+ }
96
+ }
97
+
98
+ @ExpoMethod
99
+ fun getNetworkStateAsync(promise: Promise) {
100
+ val result = Bundle()
101
+ val connectivityManager = appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
102
+
103
+ try {
104
+ if (Build.VERSION.SDK_INT < 29) { // use getActiveNetworkInfo before api level 29
105
+ val netInfo = connectivityManager.activeNetworkInfo
106
+ val connectionType = getConnectionType(netInfo)
107
+
108
+ result.apply {
109
+ putBoolean("isInternetReachable", netInfo!!.isConnected)
110
+ putString("type", connectionType.value)
111
+ putBoolean("isConnected", connectionType.isDefined)
112
+ }
113
+
114
+ promise.resolve(result)
115
+ } else {
116
+ val network = connectivityManager.activeNetwork
117
+ val isInternetReachable = network != null
118
+
119
+ val connectionType = if (isInternetReachable) {
120
+ val netCapabilities = connectivityManager.getNetworkCapabilities(network)
121
+ getConnectionType(netCapabilities)
122
+ } else {
123
+ null
124
+ }
125
+
126
+ result.apply {
127
+ putString("type", connectionType?.value ?: NetworkStateType.NONE.value)
128
+ putBoolean("isInternetReachable", isInternetReachable)
129
+ putBoolean("isConnected", connectionType != null && connectionType.isDefined)
130
+ }
131
+
132
+ promise.resolve(result)
133
+ }
134
+ } catch (e: Exception) {
135
+ promise.reject("ERR_NETWORK_NO_ACCESS_NETWORKINFO", "Unable to access network information", e)
136
+ }
137
+ }
138
+
139
+ @ExpoMethod
140
+ fun getIpAddressAsync(promise: Promise) {
141
+ try {
142
+ promise.resolve(rawIpToString(wifiInfo.ipAddress))
143
+ } catch (e: Exception) {
144
+ Log.e(TAG, e.message ?: "Could not get IP address")
145
+ promise.reject("ERR_NETWORK_IP_ADDRESS", "Unknown Host Exception", e)
146
+ }
147
+ }
148
+
149
+ @ExpoMethod
150
+ fun isAirplaneModeEnabledAsync(promise: Promise) {
151
+ val isAirplaneMode = Settings.Global.getInt(appContext.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
152
+ promise.resolve(isAirplaneMode)
153
+ }
154
+ }
@@ -0,0 +1,11 @@
1
+ package expo.modules.network
2
+
3
+ import android.content.Context
4
+
5
+ import expo.modules.core.BasePackage
6
+ import expo.modules.core.ExportedModule
7
+
8
+ class NetworkPackage : BasePackage() {
9
+ override fun createExportedModules(context: Context): List<ExportedModule> =
10
+ listOf(NetworkModule(context))
11
+ }
@@ -0,0 +1,7 @@
1
+ package expo.modules.network
2
+
3
+ internal fun frontPadWithZeros(inputArray: ByteArray): ByteArray {
4
+ val newByteArray = byteArrayOf(0, 0, 0, 0)
5
+ System.arraycopy(inputArray, 0, newByteArray, 4 - inputArray.size, inputArray.size)
6
+ return newByteArray
7
+ }
@@ -1,2 +1,3 @@
1
1
  declare const _default: import("expo-modules-core").ProxyNativeModule;
2
2
  export default _default;
3
+ //# sourceMappingURL=ExpoNetwork.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoNetwork.d.ts","sourceRoot":"","sources":["../src/ExpoNetwork.ts"],"names":[],"mappings":";AACA,wBAA8C"}
@@ -5,3 +5,4 @@ declare const _default: {
5
5
  getMacAddressAsync(): Promise<null>;
6
6
  };
7
7
  export default _default;
8
+ //# sourceMappingURL=ExpoNetwork.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoNetwork.web.d.ts","sourceRoot":"","sources":["../src/ExpoNetwork.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,MAAM,iBAAiB,CAAC;;yBAGpC,QAAQ,MAAM,CAAC;4BASZ,QAAQ,YAAY,CAAC;0BAUvB,QAAQ,IAAI,CAAC;;AApB3C,wBAuBE"}
@@ -20,7 +20,7 @@ export { NetworkState, NetworkStateType };
20
20
  */
21
21
  export declare function getNetworkStateAsync(): Promise<NetworkState>;
22
22
  /**
23
- * Gets the device's current IPv4 address. Returns `0.0.0.0`` if the IP address could not be retrieved.
23
+ * Gets the device's current IPv4 address. Returns `0.0.0.0` if the IP address could not be retrieved.
24
24
  *
25
25
  * On web, this method uses the third-party [`ipify service`](https://www.ipify.org/) to get the
26
26
  * public IP address of the current device.
@@ -53,9 +53,10 @@ export declare function getIpAddressAsync(): Promise<string>;
53
53
  */
54
54
  export declare function getMacAddressAsync(interfaceName?: string | null): Promise<string>;
55
55
  /**
56
- * __Android only.__ Tells if the device is in airplane mode.
56
+ * Tells if the device is in airplane mode.
57
57
  * @return Returns a `Promise` that fulfils with a `boolean` value for whether the device is in
58
58
  * airplane mode or not.
59
+ * @platform android
59
60
  *
60
61
  * @example
61
62
  * ```ts
@@ -64,3 +65,4 @@ export declare function getMacAddressAsync(interfaceName?: string | null): Promi
64
65
  * ```
65
66
  */
66
67
  export declare function isAirplaneModeEnabledAsync(): Promise<boolean>;
68
+ //# sourceMappingURL=Network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Network.d.ts","sourceRoot":"","sources":["../src/Network.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAG1C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAKlE;AAGD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAKzD;AAGD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAK7F;AAGD;;;;;;;;;;;GAWG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,OAAO,CAAC,CAKnE"}
package/build/Network.js CHANGED
@@ -29,7 +29,7 @@ export async function getNetworkStateAsync() {
29
29
  }
30
30
  // @needsAudit
31
31
  /**
32
- * Gets the device's current IPv4 address. Returns `0.0.0.0`` if the IP address could not be retrieved.
32
+ * Gets the device's current IPv4 address. Returns `0.0.0.0` if the IP address could not be retrieved.
33
33
  *
34
34
  * On web, this method uses the third-party [`ipify service`](https://www.ipify.org/) to get the
35
35
  * public IP address of the current device.
@@ -72,9 +72,10 @@ export async function getMacAddressAsync(interfaceName = null) {
72
72
  }
73
73
  // @needsAudit
74
74
  /**
75
- * __Android only.__ Tells if the device is in airplane mode.
75
+ * Tells if the device is in airplane mode.
76
76
  * @return Returns a `Promise` that fulfils with a `boolean` value for whether the device is in
77
77
  * airplane mode or not.
78
+ * @platform android
78
79
  *
79
80
  * @example
80
81
  * ```ts
@@ -1 +1 @@
1
- {"version":3,"file":"Network.js","sourceRoot":"","sources":["../src/Network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAgB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAgB,gBAAgB,EAAE,CAAC;AAE1C,cAAc;AACd;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE;QACrC,MAAM,IAAI,mBAAmB,CAAC,cAAc,EAAE,sBAAsB,CAAC,CAAC;KACvE;IACD,OAAO,MAAM,WAAW,CAAC,oBAAoB,EAAE,CAAC;AAClD,CAAC;AAED,cAAc;AACd;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE;QAClC,MAAM,IAAI,mBAAmB,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;KACpE;IACD,OAAO,MAAM,WAAW,CAAC,iBAAiB,EAAE,CAAC;AAC/C,CAAC;AAED,cAAc;AACd;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,gBAA+B,IAAI;IAC1E,OAAO,CAAC,IAAI,CACV,qKAAqK,CACtK,CAAC;IACF,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,cAAc;AACd;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,IAAI,CAAC,WAAW,CAAC,0BAA0B,EAAE;QAC3C,MAAM,IAAI,mBAAmB,CAAC,cAAc,EAAE,4BAA4B,CAAC,CAAC;KAC7E;IACD,OAAO,MAAM,WAAW,CAAC,0BAA0B,EAAE,CAAC;AACxD,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport ExpoNetwork from './ExpoNetwork';\nimport { NetworkState, NetworkStateType } from './Network.types';\n\nexport { NetworkState, NetworkStateType };\n\n// @needsAudit\n/**\n * Gets the device's current network connection state.\n *\n * On web, `navigator.connection.type` is not available on browsers. So if there is an active\n * network connection, the field `type` returns `NetworkStateType.UNKNOWN`. Otherwise, it returns\n * `NetworkStateType.NONE`.\n * @return A `Promise` that fulfils with a `NetworkState` object.\n *\n * @example\n * ```ts\n * await Network.getNetworkStateAsync();\n * // {\n * // type: NetworkStateType.CELLULAR,\n * // isConnected: true,\n * // isInternetReachable: true,\n * // }\n * ```\n */\nexport async function getNetworkStateAsync(): Promise<NetworkState> {\n if (!ExpoNetwork.getNetworkStateAsync) {\n throw new UnavailabilityError('expo-network', 'getNetworkStateAsync');\n }\n return await ExpoNetwork.getNetworkStateAsync();\n}\n\n// @needsAudit\n/**\n * Gets the device's current IPv4 address. Returns `0.0.0.0`` if the IP address could not be retrieved.\n *\n * On web, this method uses the third-party [`ipify service`](https://www.ipify.org/) to get the\n * public IP address of the current device.\n * @return A `Promise` that fulfils with a `string` of the current IP address of the device's main\n * network interface. Can only be IPv4 address.\n *\n * @example\n * ```ts\n * await Network.getIpAddressAsync();\n * // \"92.168.32.44\"\n * ```\n */\nexport async function getIpAddressAsync(): Promise<string> {\n if (!ExpoNetwork.getIpAddressAsync) {\n throw new UnavailabilityError('expo-network', 'getIpAddressAsync');\n }\n return await ExpoNetwork.getIpAddressAsync();\n}\n\n// @needsAudit\n/**\n * Gets the specified network interface's MAC address.\n *\n * > Beginning with iOS 7 and Android 11, non-system applications can no longer access the device's\n * MAC address. In SDK 41 and above, this method will always resolve to a predefined value that\n * isn't useful.\n *\n * If you need to identify the device, use the `getIosIdForVendorAsync()` method / `androidId`\n * property of the `expo-application` unimodule instead.\n *\n * @deprecated This method is deprecated and will be removed in a future SDK version.\n *\n * @param interfaceName A string representing interface name (`eth0`, `wlan0`) or `null` (default),\n * meaning the method should fetch the MAC address of the first available interface.\n *\n * @return A `Promise` that fulfils with the value `'02:00:00:00:00:00'`.\n */\nexport async function getMacAddressAsync(interfaceName: string | null = null): Promise<string> {\n console.warn(\n 'Network.getMacAddressAsync has been deprecated and will be removed in a future SDK version. To uniquely identify a device, use the expo-application module instead.'\n );\n return '02:00:00:00:00:00';\n}\n\n// @needsAudit\n/**\n * __Android only.__ Tells if the device is in airplane mode.\n * @return Returns a `Promise` that fulfils with a `boolean` value for whether the device is in\n * airplane mode or not.\n *\n * @example\n * ```ts\n * await Network.isAirplaneModeEnabledAsync();\n * // false\n * ```\n */\nexport async function isAirplaneModeEnabledAsync(): Promise<boolean> {\n if (!ExpoNetwork.isAirplaneModeEnabledAsync) {\n throw new UnavailabilityError('expo-network', 'isAirplaneModeEnabledAsync');\n }\n return await ExpoNetwork.isAirplaneModeEnabledAsync();\n}\n"]}
1
+ {"version":3,"file":"Network.js","sourceRoot":"","sources":["../src/Network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAgB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAgB,gBAAgB,EAAE,CAAC;AAE1C,cAAc;AACd;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE;QACrC,MAAM,IAAI,mBAAmB,CAAC,cAAc,EAAE,sBAAsB,CAAC,CAAC;KACvE;IACD,OAAO,MAAM,WAAW,CAAC,oBAAoB,EAAE,CAAC;AAClD,CAAC;AAED,cAAc;AACd;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE;QAClC,MAAM,IAAI,mBAAmB,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;KACpE;IACD,OAAO,MAAM,WAAW,CAAC,iBAAiB,EAAE,CAAC;AAC/C,CAAC;AAED,cAAc;AACd;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,gBAA+B,IAAI;IAC1E,OAAO,CAAC,IAAI,CACV,qKAAqK,CACtK,CAAC;IACF,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,cAAc;AACd;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,IAAI,CAAC,WAAW,CAAC,0BAA0B,EAAE;QAC3C,MAAM,IAAI,mBAAmB,CAAC,cAAc,EAAE,4BAA4B,CAAC,CAAC;KAC7E;IACD,OAAO,MAAM,WAAW,CAAC,0BAA0B,EAAE,CAAC;AACxD,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport ExpoNetwork from './ExpoNetwork';\nimport { NetworkState, NetworkStateType } from './Network.types';\n\nexport { NetworkState, NetworkStateType };\n\n// @needsAudit\n/**\n * Gets the device's current network connection state.\n *\n * On web, `navigator.connection.type` is not available on browsers. So if there is an active\n * network connection, the field `type` returns `NetworkStateType.UNKNOWN`. Otherwise, it returns\n * `NetworkStateType.NONE`.\n * @return A `Promise` that fulfils with a `NetworkState` object.\n *\n * @example\n * ```ts\n * await Network.getNetworkStateAsync();\n * // {\n * // type: NetworkStateType.CELLULAR,\n * // isConnected: true,\n * // isInternetReachable: true,\n * // }\n * ```\n */\nexport async function getNetworkStateAsync(): Promise<NetworkState> {\n if (!ExpoNetwork.getNetworkStateAsync) {\n throw new UnavailabilityError('expo-network', 'getNetworkStateAsync');\n }\n return await ExpoNetwork.getNetworkStateAsync();\n}\n\n// @needsAudit\n/**\n * Gets the device's current IPv4 address. Returns `0.0.0.0` if the IP address could not be retrieved.\n *\n * On web, this method uses the third-party [`ipify service`](https://www.ipify.org/) to get the\n * public IP address of the current device.\n * @return A `Promise` that fulfils with a `string` of the current IP address of the device's main\n * network interface. Can only be IPv4 address.\n *\n * @example\n * ```ts\n * await Network.getIpAddressAsync();\n * // \"92.168.32.44\"\n * ```\n */\nexport async function getIpAddressAsync(): Promise<string> {\n if (!ExpoNetwork.getIpAddressAsync) {\n throw new UnavailabilityError('expo-network', 'getIpAddressAsync');\n }\n return await ExpoNetwork.getIpAddressAsync();\n}\n\n// @needsAudit\n/**\n * Gets the specified network interface's MAC address.\n *\n * > Beginning with iOS 7 and Android 11, non-system applications can no longer access the device's\n * MAC address. In SDK 41 and above, this method will always resolve to a predefined value that\n * isn't useful.\n *\n * If you need to identify the device, use the `getIosIdForVendorAsync()` method / `androidId`\n * property of the `expo-application` unimodule instead.\n *\n * @deprecated This method is deprecated and will be removed in a future SDK version.\n *\n * @param interfaceName A string representing interface name (`eth0`, `wlan0`) or `null` (default),\n * meaning the method should fetch the MAC address of the first available interface.\n *\n * @return A `Promise` that fulfils with the value `'02:00:00:00:00:00'`.\n */\nexport async function getMacAddressAsync(interfaceName: string | null = null): Promise<string> {\n console.warn(\n 'Network.getMacAddressAsync has been deprecated and will be removed in a future SDK version. To uniquely identify a device, use the expo-application module instead.'\n );\n return '02:00:00:00:00:00';\n}\n\n// @needsAudit\n/**\n * Tells if the device is in airplane mode.\n * @return Returns a `Promise` that fulfils with a `boolean` value for whether the device is in\n * airplane mode or not.\n * @platform android\n *\n * @example\n * ```ts\n * await Network.isAirplaneModeEnabledAsync();\n * // false\n * ```\n */\nexport async function isAirplaneModeEnabledAsync(): Promise<boolean> {\n if (!ExpoNetwork.isAirplaneModeEnabledAsync) {\n throw new UnavailabilityError('expo-network', 'isAirplaneModeEnabledAsync');\n }\n return await ExpoNetwork.isAirplaneModeEnabledAsync();\n}\n"]}
@@ -59,3 +59,4 @@ export declare enum NetworkStateType {
59
59
  */
60
60
  OTHER = "OTHER"
61
61
  }
62
+ //# sourceMappingURL=Network.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Network.types.d.ts","sourceRoot":"","sources":["../src/Network.types.ts"],"names":[],"mappings":"AACA,oBAAY,YAAY,GAAG;IACzB;;;OAGG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAGF;;GAEG;AACH,oBAAY,gBAAgB;IAC1B;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,OAAO,YAAY;IACnB;;;OAGG;IACH,QAAQ,aAAa;IACrB;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,SAAS,cAAc;IACvB;;OAEG;IACH,QAAQ,aAAa;IACrB;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,GAAG,QAAQ;IACX;;OAEG;IACH,KAAK,UAAU;CAChB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-network",
3
- "version": "4.0.3",
3
+ "version": "4.2.0",
4
4
  "description": "Provides useful information about the device's network such as its IP address, MAC address, and airplane mode status",
5
5
  "main": "build/Network.js",
6
6
  "types": "build/Network.d.ts",
@@ -29,11 +29,12 @@
29
29
  "author": "650 Industries, Inc.",
30
30
  "license": "MIT",
31
31
  "homepage": "https://docs.expo.dev/versions/latest/sdk/network/",
32
- "dependencies": {
33
- "expo-modules-core": "~0.4.4"
34
- },
32
+ "dependencies": {},
35
33
  "devDependencies": {
36
34
  "expo-module-scripts": "^2.0.0"
37
35
  },
38
- "gitHead": "4fa0497a180ae707fa860cb03858630ab7af19f4"
36
+ "peerDependencies": {
37
+ "expo": "*"
38
+ },
39
+ "gitHead": "22dce752354bb429c84851bc4389abe47a766b1f"
39
40
  }
package/src/Network.ts CHANGED
@@ -33,7 +33,7 @@ export async function getNetworkStateAsync(): Promise<NetworkState> {
33
33
 
34
34
  // @needsAudit
35
35
  /**
36
- * Gets the device's current IPv4 address. Returns `0.0.0.0`` if the IP address could not be retrieved.
36
+ * Gets the device's current IPv4 address. Returns `0.0.0.0` if the IP address could not be retrieved.
37
37
  *
38
38
  * On web, this method uses the third-party [`ipify service`](https://www.ipify.org/) to get the
39
39
  * public IP address of the current device.
@@ -80,9 +80,10 @@ export async function getMacAddressAsync(interfaceName: string | null = null): P
80
80
 
81
81
  // @needsAudit
82
82
  /**
83
- * __Android only.__ Tells if the device is in airplane mode.
83
+ * Tells if the device is in airplane mode.
84
84
  * @return Returns a `Promise` that fulfils with a `boolean` value for whether the device is in
85
85
  * airplane mode or not.
86
+ * @platform android
86
87
  *
87
88
  * @example
88
89
  * ```ts
@@ -1,199 +0,0 @@
1
- package expo.modules.network;
2
-
3
- import android.app.Activity;
4
- import android.content.Context;
5
- import android.content.pm.PackageManager;
6
- import android.net.ConnectivityManager;
7
- import android.net.Network;
8
- import android.net.NetworkCapabilities;
9
- import android.net.NetworkInfo;
10
- import android.net.wifi.WifiInfo;
11
- import android.net.wifi.WifiManager;
12
- import android.os.Build;
13
- import android.os.Bundle;
14
- import android.provider.Settings;
15
- import android.util.Log;
16
-
17
- import expo.modules.core.ExportedModule;
18
- import expo.modules.core.ModuleRegistry;
19
- import expo.modules.core.Promise;
20
- import expo.modules.core.interfaces.ActivityProvider;
21
- import expo.modules.core.interfaces.ExpoMethod;
22
- import expo.modules.core.interfaces.RegistryLifecycleListener;
23
-
24
- import java.math.BigInteger;
25
- import java.net.InetAddress;
26
- import java.net.NetworkInterface;
27
- import java.net.UnknownHostException;
28
- import java.nio.ByteOrder;
29
- import java.util.Collections;
30
- import java.util.List;
31
-
32
- public class NetworkModule extends ExportedModule implements RegistryLifecycleListener {
33
- private static final String NAME = "ExpoNetwork";
34
- private static final String TAG = NetworkModule.class.getSimpleName();
35
- private Context mContext;
36
- private ModuleRegistry mModuleRegistry;
37
- private ActivityProvider mActivityProvider;
38
- private Activity mActivity;
39
-
40
- public static enum NetworkStateType {
41
- NONE("NONE"),
42
- UNKNOWN("UNKNOWN"),
43
- CELLULAR("CELLULAR"),
44
- WIFI("WIFI"),
45
- BLUETOOTH("BLUETOOTH"),
46
- ETHERNET("ETHERNET"),
47
- WIMAX("WIMAX"),
48
- VPN("VPN"),
49
- OTHER("OTHER");
50
-
51
- private final String value;
52
-
53
- NetworkStateType(String value) {
54
- this.value = value;
55
- }
56
-
57
- public String getValue() {
58
- return value;
59
- }
60
-
61
- public boolean equal(String value) {
62
- return this.value.equals(value);
63
- }
64
- }
65
-
66
- public NetworkModule(Context context) {
67
- super(context);
68
- mContext = context;
69
- }
70
-
71
- @Override
72
- public String getName() {
73
- return NAME;
74
- }
75
-
76
- @Override
77
- public void onCreate(ModuleRegistry moduleRegistry) {
78
- mModuleRegistry = moduleRegistry;
79
- mActivityProvider = moduleRegistry.getModule(ActivityProvider.class);
80
- mActivity = mActivityProvider.getCurrentActivity();
81
- }
82
-
83
- private WifiInfo getWifiInfo() {
84
- try {
85
- WifiManager manager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
86
- return manager.getConnectionInfo();
87
- } catch (Exception e) {
88
- Log.e(TAG, e.getMessage());
89
- throw e;
90
- }
91
- }
92
-
93
- private NetworkStateType getConnectionType(NetworkInfo netinfo) {
94
- switch (netinfo.getType()) {
95
- case ConnectivityManager.TYPE_MOBILE:
96
- case ConnectivityManager.TYPE_MOBILE_DUN:
97
- return NetworkStateType.CELLULAR;
98
- case ConnectivityManager.TYPE_WIFI:
99
- return NetworkStateType.WIFI;
100
- case ConnectivityManager.TYPE_BLUETOOTH:
101
- return NetworkStateType.BLUETOOTH;
102
- case ConnectivityManager.TYPE_ETHERNET:
103
- return NetworkStateType.ETHERNET;
104
- case ConnectivityManager.TYPE_WIMAX:
105
- return NetworkStateType.WIMAX;
106
- case ConnectivityManager.TYPE_VPN:
107
- return NetworkStateType.VPN;
108
- default:
109
- return NetworkStateType.UNKNOWN;
110
- }
111
- }
112
-
113
- private NetworkStateType getConnectionType(NetworkCapabilities nc) {
114
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) return NetworkStateType.CELLULAR;
115
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE))
116
- return NetworkStateType.WIFI;
117
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) return NetworkStateType.BLUETOOTH;
118
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) return NetworkStateType.ETHERNET;
119
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) return NetworkStateType.VPN;
120
- return NetworkStateType.UNKNOWN;
121
- }
122
-
123
- private String rawIpToString(Integer ip) {
124
- // Convert little-endian to big-endian if needed
125
- if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
126
- ip = Integer.reverseBytes(ip);
127
- }
128
- byte[] ipByteArray = BigInteger.valueOf(ip).toByteArray();
129
- if (ipByteArray.length < 4) {
130
- ipByteArray = frontPadWithZeros(ipByteArray);
131
- }
132
- try {
133
- return InetAddress.getByAddress(ipByteArray).getHostAddress();
134
- } catch (UnknownHostException e) {
135
- return "0.0.0.0";
136
- }
137
- }
138
-
139
- private static byte[] frontPadWithZeros(byte [] inputArray) {
140
- byte[] newByteArray = { 0, 0, 0, 0 };
141
- System.arraycopy(inputArray, 0, newByteArray, 4 - inputArray.length, inputArray.length);
142
- return newByteArray;
143
- }
144
-
145
- @ExpoMethod
146
- public void getNetworkStateAsync(Promise promise) {
147
- Bundle result = new Bundle();
148
- ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
149
- //use getActiveNetworkInfo before api level 29
150
- if (Build.VERSION.SDK_INT < 29) {
151
- try {
152
- NetworkInfo netInfo = cm.getActiveNetworkInfo();
153
- result.putBoolean("isInternetReachable", netInfo.isConnected());
154
- NetworkStateType mConnectionType = getConnectionType(netInfo);
155
- result.putString("type", mConnectionType.getValue());
156
- result.putBoolean("isConnected", !mConnectionType.equal("NONE") && !mConnectionType.equal("UNKNOWN"));
157
- promise.resolve(result);
158
- } catch (Exception e) {
159
- promise.reject("ERR_NETWORK_NO_ACCESS_NETWORKINFO", "Unable to access network information", e);
160
- }
161
- } else {
162
- try {
163
- Network network = cm.getActiveNetwork();
164
- boolean isInternetReachable = network != null;
165
- NetworkStateType connectionType = null;
166
- if (isInternetReachable) {
167
- NetworkCapabilities nc = cm.getNetworkCapabilities(network);
168
- connectionType = getConnectionType(nc);
169
- result.putString("type", connectionType.getValue());
170
- } else {
171
- result.putString("type", NetworkStateType.NONE.getValue());
172
- }
173
- result.putBoolean("isInternetReachable", isInternetReachable);
174
- result.putBoolean("isConnected", connectionType != null && !connectionType.equal("NONE") && !connectionType.equal("UNKNOWN"));
175
- promise.resolve(result);
176
- } catch (Exception e) {
177
- promise.reject("ERR_NETWORK_NO_ACCESS_NETWORKINFO", "Unable to access network information", e);
178
- }
179
- }
180
- }
181
-
182
- @ExpoMethod
183
- public void getIpAddressAsync(Promise promise) {
184
- try {
185
- Integer ipAddress = getWifiInfo().getIpAddress();
186
- String ipAddressString = rawIpToString(ipAddress);
187
- promise.resolve(ipAddressString);
188
- } catch (Exception e) {
189
- Log.e(TAG, e.getMessage());
190
- promise.reject("ERR_NETWORK_IP_ADDRESS", "Unknown Host Exception", e);
191
- }
192
- }
193
-
194
- @ExpoMethod
195
- public void isAirplaneModeEnabledAsync(Promise promise) {
196
- boolean isAirPlaneMode = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
197
- promise.resolve(isAirPlaneMode);
198
- }
199
- }
@@ -1,16 +0,0 @@
1
- package expo.modules.network;
2
-
3
- import android.content.Context;
4
-
5
- import expo.modules.core.BasePackage;
6
- import expo.modules.core.ExportedModule;
7
-
8
- import java.util.Collections;
9
- import java.util.List;
10
-
11
- public class NetworkPackage extends BasePackage {
12
- @Override
13
- public List<ExportedModule> createExportedModules(Context context) {
14
- return Collections.singletonList((ExportedModule) new NetworkModule(context));
15
- }
16
- }