Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Commit c284de4

Browse files
authored
Merge pull request #10 from edpaget/ep-develop-bind-networks
Add bindToNetwork and unbindNetwork methods
2 parents 4374eff + 586f8f9 commit c284de4

File tree

12 files changed

+716
-320
lines changed

12 files changed

+716
-320
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,7 @@ index.android.bundle
6363
*.project
6464

6565
*.settings/
66+
67+
example/android/app/bin/
68+
69+
android/bin/

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ iOS:
3232
```javascript
3333
import Wifi from "react-native-iot-wifi";
3434

35-
Wifi.isAvaliable((avaliable) => {
36-
console.log(avaliable ? 'avaliable' : 'failed');
35+
Wifi.isApiAvailable((available) => {
36+
console.log(available ? 'available' : 'failed');
3737
});
3838

3939
Wifi.getSSID((SSID) => {

android/src/main/java/com/tadasr/IOTWifi/IOTWifiModule.java

Lines changed: 176 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import com.facebook.react.bridge.*;
44

55
import android.net.ConnectivityManager;
6+
import android.net.Network;
7+
import android.net.NetworkCapabilities;
68
import android.net.NetworkInfo;
9+
import android.net.NetworkRequest;
710
import android.net.wifi.WifiInfo;
811
import android.net.wifi.WifiManager;
912
import android.net.wifi.WifiConfiguration;
@@ -13,47 +16,104 @@
1316

1417
import java.util.List;
1518

19+
20+
class FailureCodes {
21+
static int SYSTEM_ADDED_CONFIG_EXISTS = 1;
22+
static int FAILED_TO_CONNECT = 2;
23+
static int FAILED_TO_ADD_CONFIG = 3;
24+
static int FAILED_TO_BIND_CONFIG = 4;
25+
}
26+
1627
public class IOTWifiModule extends ReactContextBaseJavaModule {
17-
WifiManager wifiManager;
18-
ConnectivityManager connectivityManager;
19-
ReactApplicationContext context;
20-
28+
private WifiManager wifiManager;
29+
private ConnectivityManager connectivityManager;
30+
private ReactApplicationContext context;
31+
2132
public IOTWifiModule(ReactApplicationContext reactContext) {
2233
super(reactContext);
23-
wifiManager = (WifiManager) getReactApplicationContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
24-
connectivityManager = (ConnectivityManager) getReactApplicationContext().getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
34+
wifiManager = (WifiManager) getReactApplicationContext().getApplicationContext()
35+
.getSystemService(Context.WIFI_SERVICE);
36+
connectivityManager = (ConnectivityManager) getReactApplicationContext().getApplicationContext()
37+
.getSystemService(Context.CONNECTIVITY_SERVICE);
2538
context = getReactApplicationContext();
2639
}
27-
40+
41+
private String errorFromCode(int errorCode) {
42+
return "ErrorCode: " + errorCode;
43+
}
44+
2845
@Override
2946
public String getName() {
3047
return "IOTWifi";
3148
}
32-
49+
3350
@ReactMethod
34-
public void isAvaliable(Callback callback) {
51+
public void isApiAvailable(final Callback callback) {
3552
callback.invoke(true);
3653
}
3754

3855
@ReactMethod
39-
public void connect(String ssid, Callback callback) {
40-
connectSecure(ssid, "", false, callback);
56+
public void connect(String ssid, Boolean bindNetwork, Callback callback) {
57+
connectSecure(ssid, "", false, bindNetwork, callback);
4158
}
4259

4360
@ReactMethod
44-
public void connectSecure(final String ssid, final String passphrase, final Boolean isWEP, final Callback callback) {
61+
public void connectSecure(final String ssid, final String passphrase, final Boolean isWEP,
62+
final Boolean bindNetwork, final Callback callback) {
4563
new Thread(new Runnable() {
4664
public void run() {
47-
connectToWifi(ssid, passphrase, isWEP, callback);
65+
connectToWifi(ssid, passphrase, isWEP, bindNetwork, callback);
4866
}
4967
}).start();
5068
}
5169

52-
private void connectToWifi(String ssid, String passphrase, Boolean isWEP, Callback callback) {
70+
private void connectToWifi(String ssid, String passphrase, Boolean isWEP, Boolean bindNetwork, Callback callback) {
5371
if (Build.VERSION.SDK_INT > 28) {
54-
callback.invoke("Fail");
72+
callback.invoke("Not supported on Android Q");
5573
return;
5674
}
75+
if (!removeSSID(ssid)) {
76+
callback.invoke(errorFromCode(FailureCodes.SYSTEM_ADDED_CONFIG_EXISTS));
77+
return;
78+
}
79+
80+
WifiConfiguration configuration = createWifiConfiguration(ssid, passphrase, isWEP);
81+
int networkId = wifiManager.addNetwork(configuration);
82+
83+
if (networkId != -1) {
84+
// Enable it so that android can connect
85+
wifiManager.disconnect();
86+
boolean success = wifiManager.enableNetwork(networkId, true);
87+
if (!success) {
88+
callback.invoke(errorFromCode(FailureCodes.FAILED_TO_ADD_CONFIG));
89+
return;
90+
}
91+
success = wifiManager.reconnect();
92+
if (!success) {
93+
callback.invoke(errorFromCode(FailureCodes.FAILED_TO_CONNECT));
94+
return;
95+
}
96+
boolean connected = pollForValidSSSID(10, ssid);
97+
if (!connected) {
98+
callback.invoke(errorFromCode(FailureCodes.FAILED_TO_CONNECT));
99+
return;
100+
}
101+
if (!bindNetwork) {
102+
callback.invoke();
103+
return;
104+
}
105+
try {
106+
bindToNetwork(ssid, callback);
107+
} catch (Exception e) {
108+
Log.d("IoTWifi", "Failed to bind to Wifi: " + ssid);
109+
callback.invoke();
110+
}
111+
} else {
112+
callback.invoke(errorFromCode(FailureCodes.FAILED_TO_ADD_CONFIG));
113+
}
114+
}
115+
116+
private WifiConfiguration createWifiConfiguration(String ssid, String passphrase, Boolean isWEP) {
57117
WifiConfiguration configuration = new WifiConfiguration();
58118
configuration.SSID = String.format("\"%s\"", ssid);
59119

@@ -71,70 +131,136 @@ private void connectToWifi(String ssid, String passphrase, Boolean isWEP, Callba
71131
if (!wifiManager.isWifiEnabled()) {
72132
wifiManager.setWifiEnabled(true);
73133
}
134+
return configuration;
135+
}
74136

75-
removeSSID(ssid);
137+
private boolean pollForValidSSSID(int maxSeconds, String expectedSSID) {
138+
try {
139+
for (int i = 0; i < maxSeconds; i++) {
140+
String ssid = this.getWifiSSID();
141+
if (ssid != null && ssid.equalsIgnoreCase(expectedSSID)) {
142+
return true;
143+
}
144+
Thread.sleep(1000);
145+
}
146+
} catch (InterruptedException e) {
147+
return false;
148+
}
149+
return false;
150+
}
76151

77-
// Add configuration to Android wifi manager settings...
78-
int networkId = wifiManager.addNetwork(configuration);
152+
private void bindToNetwork(final String ssid, final Callback callback) {
153+
NetworkRequest.Builder builder = new NetworkRequest.Builder();
154+
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
155+
connectivityManager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
79156

80-
if (networkId != -1) {
81-
// Enable it so that android can connect
82-
wifiManager.disconnect();
83-
wifiManager.enableNetwork(networkId, true);
84-
boolean success = wifiManager.reconnect();
85-
if (!success) {
86-
callback.invoke("Fail");
87-
return;
157+
private boolean bound = false;
158+
159+
@Override
160+
public void onAvailable(Network network) {
161+
String offeredSSID = getWifiSSID();
162+
163+
if (!bound && offeredSSID.equals(ssid)) {
164+
try {
165+
bindProcessToNetwork(network);
166+
bound = true;
167+
callback.invoke();
168+
return;
169+
} catch (Exception e) {
170+
e.printStackTrace();
171+
}
172+
}
173+
callback.invoke(errorFromCode(FailureCodes.FAILED_TO_BIND_CONFIG));
88174
}
89-
try {
90-
Thread.sleep(3000);
91-
callback.invoke();
92-
} catch (InterruptedException e) {
93-
callback.invoke("Fail");
175+
176+
@Override
177+
public void onLost(Network network) {
178+
if (bound) {
179+
bindProcessToNetwork(null);
180+
connectivityManager.unregisterNetworkCallback(this);
181+
}
94182
}
183+
});
184+
}
185+
186+
private void bindProcessToNetwork(final Network network) {
187+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
188+
connectivityManager.bindProcessToNetwork(network);
95189
} else {
96-
callback.invoke("Failed to add network configuration");
190+
ConnectivityManager.setProcessDefaultNetwork(network);
97191
}
98192
}
99193

100194
@ReactMethod
101-
public void removeSSID(String ssid, Callback callback) {
102-
removeSSID(ssid);
195+
public void removeSSID(String ssid, Boolean unbind, Callback callback) {
196+
if (!removeSSID(ssid)) {
197+
callback.invoke(errorFromCode(FailureCodes.SYSTEM_ADDED_CONFIG_EXISTS));
198+
return;
199+
}
200+
if (unbind) {
201+
bindProcessToNetwork(null);
202+
}
203+
103204
callback.invoke();
104205
}
105206

106-
public void removeSSID(String ssid) {
107-
// Remove the existing configuration for this netwrok
108-
List<WifiConfiguration> configList = wifiManager.getConfiguredNetworks();
109-
String comparableSSID = ('"' + ssid + '"'); // Add quotes because wifiConfig.SSID has them
110-
if (configList != null) {
111-
for (WifiConfiguration wifiConfig : configList) {
112-
if (wifiConfig.SSID.equals(comparableSSID)) {
113-
Log.d("wifi", wifiConfig.toString());
114-
int networkId = wifiConfig.networkId;
115-
wifiManager.removeNetwork(networkId);
116-
wifiManager.saveConfiguration();
117-
}
118-
}
207+
208+
private boolean removeSSID(String ssid) {
209+
boolean success = true;
210+
// Remove the existing configuration for this network
211+
WifiConfiguration existingNetworkConfigForSSID = getExistingNetworkConfig(ssid);
212+
213+
//No Config found
214+
if (existingNetworkConfigForSSID == null) {
215+
return success;
216+
}
217+
int existingNetworkId = existingNetworkConfigForSSID.networkId;
218+
if (existingNetworkId == -1) {
219+
return success;
119220
}
221+
success = wifiManager.removeNetwork(existingNetworkId) && wifiManager.saveConfiguration();
222+
//If not our config then success would be false
223+
return success;
120224
}
121225

122226
@ReactMethod
123227
public void getSSID(Callback callback) {
228+
String ssid = this.getWifiSSID();
229+
callback.invoke(ssid);
230+
}
231+
232+
private String getWifiSSID() {
124233
WifiInfo info = wifiManager.getConnectionInfo();
125234
String ssid = info.getSSID();
126235

127-
if (ssid == null || ssid == "<unknown ssid>") {
236+
if (ssid == null || ssid.equalsIgnoreCase("<unknown ssid>")) {
128237
NetworkInfo nInfo = connectivityManager.getActiveNetworkInfo();
129238
if (nInfo != null && nInfo.isConnected()) {
130239
ssid = nInfo.getExtraInfo();
131240
}
132241
}
133242

134-
if (ssid.startsWith("\"") && ssid.endsWith("\"")) {
243+
if (ssid != null && ssid.startsWith("\"") && ssid.endsWith("\"")) {
135244
ssid = ssid.substring(1, ssid.length() - 1);
136245
}
137246

138-
callback.invoke(ssid);
247+
return ssid;
248+
}
249+
250+
private WifiConfiguration getExistingNetworkConfig(String ssid) {
251+
WifiConfiguration existingNetworkConfigForSSID = null;
252+
List<WifiConfiguration> configList = wifiManager.getConfiguredNetworks();
253+
String comparableSSID = ('"' + ssid + '"'); // Add quotes because wifiConfig.SSID has them
254+
if (configList != null) {
255+
for (WifiConfiguration wifiConfig : configList) {
256+
if (wifiConfig.SSID.equals(comparableSSID)) {
257+
Log.d("IoTWifi", "Found Matching Wifi: "+ wifiConfig.toString());
258+
existingNetworkConfigForSSID = wifiConfig;
259+
break;
260+
261+
}
262+
}
263+
}
264+
return existingNetworkConfigForSSID;
139265
}
140266
}

example/App.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import React, {Component} from 'react';
10-
import {Platform, StyleSheet, Text, View} from 'react-native';
10+
import {StyleSheet, Text, View} from 'react-native';
1111
import Wifi from "react-native-iot-wifi";
1212

1313
const ssid = 'your wifi ssid';
@@ -30,7 +30,7 @@ export default class App extends Component {
3030
return (
3131
<View style={styles.container}>
3232
<Text style={styles.instructions}>{"\n"}
33-
API avaliable: {this.state.isApiAvaliable ? "yes" : "no"} {"\n"}
33+
API available: {this.state.isApiAvaliable ? "yes" : "no"} {"\n"}
3434
~{"\n"}
3535
SSID: {this.state.ssid} {"\n"}
3636
~{"\n"}
@@ -42,11 +42,11 @@ export default class App extends Component {
4242
}
4343

4444
testWifi(){
45-
Wifi.isAvaliable((avaliable) => {
45+
Wifi.isApiAvailable((available) => {
4646

47-
this.setState({isApiAvaliable: avaliable});
47+
this.setState({isApiAvaliable: available});
4848

49-
if (!avaliable) {
49+
if (!available) {
5050
return;
5151
}
5252

example/android/settings.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ rootProject.name = 'example'
33
include ':app'
44

55
include ':react-native-iot-wifi'
6-
project(':react-native-iot-wifi').projectDir = new File(rootProject.projectDir, '../../android')
6+
project(':react-native-iot-wifi').projectDir = new File(rootProject.projectDir, '../../react-native-iot-wifi/android')

0 commit comments

Comments
 (0)