// /* // * Copyright 2018 Myles McNamara // * // * Licensed under the Apache License, Version 2.0 (the "License"); // * you may not use this file except in compliance with the License. // * You may obtain a copy of the License at // * // * http://www.apache.org/licenses/LICENSE-2.0 // * Unless required by applicable law or agreed to in writing, software // * distributed under the License is distributed on an "AS IS" BASIS, // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // * See the License for the specific language governing permissions and // * limitations under the License. // */ // package wifiwizard2; // import org.apache.cordova.*; // import java.util.List; // import java.lang.InterruptedException; // import org.json.JSONArray; // import org.json.JSONException; // import org.json.JSONObject; // import android.annotation.SuppressLint; // import android.app.PendingIntent; // import android.content.pm.PackageManager; // import android.content.BroadcastReceiver; // import android.content.Intent; // import android.content.IntentFilter; // import android.net.Network; // import android.net.NetworkCapabilities; // import android.net.NetworkInfo; // import android.net.NetworkRequest; // import android.net.DhcpInfo; // import android.net.wifi.WifiManager; // import android.net.wifi.WifiConfiguration; // import android.net.wifi.ScanResult; // import android.net.wifi.WifiInfo; // import android.net.wifi.SupplicantState; // import android.net.wifi.WifiNetworkSpecifier; // import android.net.ConnectivityManager; // import android.content.Context; // import android.os.AsyncTask; // import android.util.Log; // import android.os.Build.VERSION; // import android.os.PatternMatcher; // import java.net.URL; // import java.net.InetAddress; // import java.net.Inet4Address; // import java.net.InterfaceAddress; // import java.net.NetworkInterface; // import java.net.HttpURLConnection; // import java.net.UnknownHostException; // public class WifiWizard2 extends CordovaPlugin { // private boolean hiddenSSID = false; // private static final String TAG = "WifiWizard2"; // private static final int API_VERSION = VERSION.SDK_INT; // private static final String ADD_NETWORK = "add"; // private static final String REMOVE_NETWORK = "remove"; // private static final String CONNECT_NETWORK = "connect"; // private static final String DISCONNECT_NETWORK = "disconnectNetwork"; // private static final String DISCONNECT = "disconnect"; // private static final String LIST_NETWORKS = "listNetworks"; // private static final String START_SCAN = "startScan"; // private static final String GET_SCAN_RESULTS = "getScanResults"; // private static final String GET_CONNECTED_SSID = "getConnectedSSID"; // private static final String GET_CONNECTED_BSSID = "getConnectedBSSID"; // private static final String GET_CONNECTED_NETWORKID = "getConnectedNetworkID"; // private static final String IS_WIFI_ENABLED = "isWifiEnabled"; // private static final String SET_WIFI_ENABLED = "setWifiEnabled"; // private static final String SCAN = "scan"; // private static final String ENABLE_NETWORK = "enable"; // private static final String DISABLE_NETWORK = "disable"; // private static final String GET_SSID_NET_ID = "getSSIDNetworkID"; // private static final String REASSOCIATE = "reassociate"; // private static final String RECONNECT = "reconnect"; // private static final String REQUEST_FINE_LOCATION = "requestFineLocation"; // private static final String GET_WIFI_IP_ADDRESS = "getWifiIP"; // private static final String GET_WIFI_ROUTER_IP_ADDRESS = "getWifiRouterIP"; // private static final String CAN_PING_WIFI_ROUTER = "canPingWifiRouter"; // private static final String CAN_CONNECT_TO_ROUTER = "canConnectToRouter"; // private static final String CAN_CONNECT_TO_INTERNET = "canConnectToInternet"; // private static final String IS_CONNECTED_TO_INTERNET = "isConnectedToInternet"; // private static final String RESET_BIND_ALL = "resetBindAll"; // private static final String SET_BIND_ALL = "setBindAll"; // private static final String GET_WIFI_IP_INFO = "getWifiIPInfo"; // private static final int SCAN_RESULTS_CODE = 0; // Permissions request code for getScanResults() // private static final int SCAN_CODE = 1; // Permissions request code for scan() // private static final int LOCATION_REQUEST_CODE = 2; // Permissions request code // private static final int WIFI_SERVICE_INFO_CODE = 3; // private static final String ACCESS_FINE_LOCATION = android.Manifest.permission.ACCESS_FINE_LOCATION; // private static int LAST_NET_ID = -1; // // This is for when SSID or BSSID is requested but permissions have not been granted for location // // we store whether or not BSSID was requested, to recall the getWifiServiceInfo fn after permissions are granted // private static boolean bssidRequested = false; // private WifiManager wifiManager; // private CallbackContext callbackContext; // private JSONArray passedData; // private ConnectivityManager connectivityManager; // private ConnectivityManager.NetworkCallback networkCallback; // // Store AP, previous, and desired wifi info // private AP previous, desired; // private PendingIntent pending_intent_net_req_received; // private final BroadcastReceiver networkChangedReceiver = new NetworkChangedReceiver(); // private static final IntentFilter NETWORK_STATE_CHANGED_FILTER = new IntentFilter(); // static { // NETWORK_STATE_CHANGED_FILTER.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); // } // /** // * WEP has two kinds of password, a hex value that specifies the key or a character string used to // * generate the real hex. This checks what kind of password has been supplied. The checks // * correspond to WEP40, WEP104 & WEP232 // */ // private static boolean getHexKey(String s) { // if (s == null) { // return false; // } // int len = s.length(); // if (len != 10 && len != 26 && len != 58) { // return false; // } // for (int i = 0; i < len; ++i) { // char c = s.charAt(i); // if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { // return false; // } // } // return true; // } // @Override // public void initialize(CordovaInterface cordova, CordovaWebView webView) { // super.initialize(cordova, webView); // this.wifiManager = (WifiManager) cordova.getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE); // this.connectivityManager = (ConnectivityManager) cordova.getActivity().getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); // } // @Override // public boolean execute(String action, JSONArray data, CallbackContext callbackContext) // throws JSONException { // this.callbackContext = callbackContext; // this.passedData = data; // // Actions that do not require WiFi to be enabled // if (action.equals(IS_WIFI_ENABLED)) { // this.isWifiEnabled(callbackContext); // return true; // } else if (action.equals(SET_WIFI_ENABLED)) { // this.setWifiEnabled(callbackContext, data); // return true; // } else if (action.equals(REQUEST_FINE_LOCATION)) { // this.requestLocationPermission(LOCATION_REQUEST_CODE); // return true; // } else if (action.equals(GET_WIFI_ROUTER_IP_ADDRESS)) { // String ip = getWiFiRouterIP(); // if ( ip == null || ip.equals("0.0.0.0")) { // callbackContext.error("NO_VALID_ROUTER_IP_FOUND"); // return true; // } else { // callbackContext.success(ip); // return true; // } // } else if (action.equals(GET_WIFI_IP_ADDRESS) || action.equals(GET_WIFI_IP_INFO)) { // String[] ipInfo = getWiFiIPAddress(); // String ip = ipInfo[0]; // String subnet = ipInfo[1]; // if (ip == null || ip.equals("0.0.0.0")) { // callbackContext.error("NO_VALID_IP_IDENTIFIED"); // return true; // } // // Return only IP address // if( action.equals( GET_WIFI_IP_ADDRESS ) ){ // callbackContext.success(ip); // return true; // } // // Return Wifi IP Info (subnet and IP as JSON object) // JSONObject result = new JSONObject(); // result.put("ip", ip); // result.put("subnet", subnet); // callbackContext.success(result); // return true; // } // boolean wifiIsEnabled = verifyWifiEnabled(); // if (!wifiIsEnabled) { // callbackContext.error("WIFI_NOT_ENABLED"); // return true; // Even though enable wifi failed, we still return true and handle error in callback // } // // Actions that DO require WiFi to be enabled // if (action.equals(ADD_NETWORK)) { // this.add(callbackContext, data); // } else if (action.equals(IS_CONNECTED_TO_INTERNET)) { // this.canConnectToInternet(callbackContext, true); // } else if (action.equals(CAN_CONNECT_TO_INTERNET)) { // this.canConnectToInternet(callbackContext, false); // } else if (action.equals(CAN_PING_WIFI_ROUTER)) { // this.canConnectToRouter(callbackContext, true); // } else if (action.equals(CAN_CONNECT_TO_ROUTER)) { // this.canConnectToRouter(callbackContext, false); // } else if (action.equals(ENABLE_NETWORK)) { // this.enable(callbackContext, data); // } else if (action.equals(DISABLE_NETWORK)) { // this.disable(callbackContext, data); // } else if (action.equals(GET_SSID_NET_ID)) { // this.getSSIDNetworkID(callbackContext, data); // } else if (action.equals(REASSOCIATE)) { // this.reassociate(callbackContext); // } else if (action.equals(RECONNECT)) { // this.reconnect(callbackContext); // } else if (action.equals(SCAN)) { // this.scan(callbackContext, data); // } else if (action.equals(REMOVE_NETWORK)) { // this.remove(callbackContext, data); // } else if (action.equals(CONNECT_NETWORK)) { // this.connect(callbackContext, data); // } else if (action.equals(DISCONNECT_NETWORK)) { // this.disconnectNetwork(callbackContext, data); // } else if (action.equals(LIST_NETWORKS)) { // this.listNetworks(callbackContext); // } else if (action.equals(START_SCAN)) { // this.startScan(callbackContext); // } else if (action.equals(GET_SCAN_RESULTS)) { // this.getScanResults(callbackContext, data); // } else if (action.equals(DISCONNECT)) { // this.disconnect(callbackContext); // } else if (action.equals(GET_CONNECTED_SSID)) { // this.getConnectedSSID(callbackContext); // } else if (action.equals(GET_CONNECTED_BSSID)) { // this.getConnectedBSSID(callbackContext); // } else if (action.equals(GET_CONNECTED_NETWORKID)) { // this.getConnectedNetworkID(callbackContext); // } else if (action.equals(RESET_BIND_ALL)) { // this.resetBindAll(callbackContext); // } else if (action.equals(SET_BIND_ALL)) { // this.setBindAll(callbackContext); // } else { // callbackContext.error("Incorrect action parameter: " + action); // // The ONLY time to return FALSE is when action does not exist that was called // // Returning false results in an INVALID_ACTION error, which translates to an error callback invoked on the JavaScript side // // All other errors should be handled with the fail callback (callbackContext.error) // // @see https://cordova.apache.org/docs/en/latest/guide/platforms/android/plugin.html // return false; // } // return true; // } // /** // * Scans networks and sends the list back on the success callback // * // * @param callbackContext A Cordova callback context // * @param data JSONArray with [0] == JSONObject // * @return true // */ // private boolean scan(final CallbackContext callbackContext, final JSONArray data) { // Log.v(TAG, "Entering startScan"); // final ScanSyncContext syncContext = new ScanSyncContext(); // final BroadcastReceiver receiver = new BroadcastReceiver() { // public void onReceive(Context context, Intent intent) { // Log.v(TAG, "Entering onReceive"); // synchronized (syncContext) { // if (syncContext.finished) { // Log.v(TAG, "In onReceive, already finished"); // return; // } // syncContext.finished = true; // context.unregisterReceiver(this); // } // Log.v(TAG, "In onReceive, success"); // getScanResults(callbackContext, data); // } // }; // final Context context = cordova.getActivity().getApplicationContext(); // Log.v(TAG, "Submitting timeout to threadpool"); // cordova.getThreadPool().submit(new Runnable() { // public void run() { // Log.v(TAG, "Entering timeout"); // final int TEN_SECONDS = 10000; // try { // Thread.sleep(TEN_SECONDS); // } catch (InterruptedException e) { // Log.e(TAG, "Received InterruptedException e, " + e); // // keep going into error // } // Log.v(TAG, "Thread sleep done"); // synchronized (syncContext) { // if (syncContext.finished) { // Log.v(TAG, "In timeout, already finished"); // return; // } // syncContext.finished = true; // context.unregisterReceiver(receiver); // } // Log.v(TAG, "In timeout, error"); // callbackContext.error("TIMEOUT_WAITING_FOR_SCAN"); // } // }); // Log.v(TAG, "Registering broadcastReceiver"); // context.registerReceiver( // receiver, // new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) // ); // if (!wifiManager.startScan()) { // Log.v(TAG, "Scan failed"); // callbackContext.error("SCAN_FAILED"); // return false; // } // Log.v(TAG, "Starting wifi scan"); // return true; // } // /** // * This methods adds a network to the list of available WiFi networks. If the network already // * exists, then it updates it. // * // * @return true if add successful, false if add fails // * @params callbackContext A Cordova callback context. // * @params data JSON Array with [0] == SSID, [1] == password // */ // private boolean add(CallbackContext callbackContext, JSONArray data) { // Log.d(TAG, "WifiWizard2: add entered."); // try { // // data's order for ANY object is // // 0: SSID // // 1: authentication algorithm, // // 2: authentication information // // 3: whether or not the SSID is hidden // String newSSID = data.getString(0); // String newPass = data.getString(2); // String authType = data.getString(1); // boolean isHiddenSSID = data.getBoolean(3); // if(API_VERSION >= 29){ // // Remove Double Quotes // newSSID = newSSID.replace("\"", ""); // newPass = newPass.replace("\"", ""); // this.networkCallback = new ConnectivityManager.NetworkCallback() { // @Override // public void onAvailable(Network network) { // connectivityManager.bindProcessToNetwork(network); // Log.d(TAG, "onAvailable"); // callbackContext.success("onAvailable"); // } // @Override // public void onUnavailable() { // super.onUnavailable(); // Log.d(TAG, "onUnavailable"); // callbackContext.error("onUnavailable"); // } // }; // // Connect Wifi using WifiNetworkSpecifier // WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder(); // builder.setIsHiddenSsid(this.hiddenSSID); // if (newSSID.endsWith("#")) { // newSSID = newSSID.replace("#", ""); // builder.setSsidPattern(new PatternMatcher(newSSID, PatternMatcher.PATTERN_PREFIX)); // }else { // builder.setSsid(newSSID); // } // builder.setWpa2Passphrase(newPass); // WifiNetworkSpecifier wifiNetworkSpecifier = builder.build(); // NetworkRequest.Builder networkRequestBuilder1 = new NetworkRequest.Builder(); // networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); // //removeCapability added for hotspots without internet // networkRequestBuilder1.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); // networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier); // NetworkRequest nr = networkRequestBuilder1.build(); // //timeout add because "No devices found" wasn't handled correct and doesn't throw Unavailable // connectivityManager.requestNetwork(nr, this.networkCallback, 30000); // }else{ // // Initialize the WifiConfiguration object // WifiConfiguration wifi = new WifiConfiguration(); // wifi.hiddenSSID = this.hiddenSSID; // wifi.SSID = newSSID; // wifi.preSharedKey = newPass; // wifi.status = WifiConfiguration.Status.ENABLED; // wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); // wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); // wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); // wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); // wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); // wifi.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // wifi.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // wifi.networkId = ssidToNetworkId(newSSID); // // Set network to highest priority (deprecated in API >= 26) // if(API_VERSION < 26) { // wifi.priority = getMaxWifiPriority(wifiManager) + 1; // } // // After processing authentication types, add or update network // if(wifi.networkId == -1) { // -1 means SSID configuration does not exist yet // int newNetId = wifiManager.addNetwork(wifi); // if( newNetId > -1 ){ // callbackContext.success( newNetId ); // } else { // callbackContext.error( "ERROR_ADDING_NETWORK" ); // } // } else { // int updatedNetID = wifiManager.updateNetwork(wifi); // if(updatedNetID == -1) // updatedNetID = wifiManager.addNetwork(wifi); // if(updatedNetID > -1) { // callbackContext.success( updatedNetID ); // } else { // callbackContext.error("ERROR_UPDATING_NETWORK"); // } // } // // WifiManager configurations are presistent for API 26+ // if(API_VERSION < 26) { // wifiManager.saveConfiguration(); // Call saveConfiguration for older < 26 API // } // } // return true; // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // } // /** // * This method connects a network. // * // * @param callbackContext A Cordova callback context // * @param data JSON Array, with [0] being SSID to connect // */ // private void enable(CallbackContext callbackContext, JSONArray data) { // Log.d(TAG, "WifiWizard2: enable entered."); // if (!validateData(data)) { // callbackContext.error("ENABLE_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: enable invalid data."); // return; // } // String ssidToEnable = ""; // String bindAll = "false"; // String waitForConnection = "false"; // try { // ssidToEnable = data.getString(0); // bindAll = data.getString(1); // waitForConnection = data.getString(2); // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return; // } // int networkIdToEnable = ssidToNetworkId(ssidToEnable); // try { // if(networkIdToEnable > -1) { // Log.d(TAG, "Valid networkIdToEnable: attempting connection"); // // Bind all requests to WiFi network (only necessary for Lollipop+ - API 21+) // if(bindAll.equals("true")) { // registerBindALL(networkIdToEnable); // } // if(wifiManager.enableNetwork(networkIdToEnable, true)) { // if( waitForConnection.equals("true") ){ // callbackContext.success("NETWORK_ENABLED"); // return; // } else { // new ConnectAsync().execute(callbackContext, networkIdToEnable); // return; // } // } else { // callbackContext.error("ERROR_ENABLING_NETWORK"); // return; // } // } else { // callbackContext.error("UNABLE_TO_ENABLE"); // return; // } // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return; // } // } // /** // * This method disables a network. // * // * @param callbackContext A Cordova callback context // * @param data JSON Array, with [0] being SSID to connect // * @return true if network disconnected, false if failed // */ // private boolean disable(CallbackContext callbackContext, JSONArray data) { // Log.d(TAG, "WifiWizard2: disable entered."); // if (!validateData(data)) { // callbackContext.error("DISABLE_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: disable invalid data"); // return false; // } // String ssidToDisable = ""; // try { // ssidToDisable = data.getString(0); // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // int networkIdToDisconnect = ssidToNetworkId(ssidToDisable); // try { // if (networkIdToDisconnect > 0) { // if(wifiManager.disableNetwork(networkIdToDisconnect)){ // maybeResetBindALL(); // callbackContext.success("Network " + ssidToDisable + " disabled!"); // } else { // callbackContext.error("UNABLE_TO_DISABLE"); // } // return true; // } else { // callbackContext.error("DISABLE_NETWORK_NOT_FOUND"); // Log.d(TAG, "WifiWizard2: Network not found to disable."); // return false; // } // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // } // /** // * This method removes a network from the list of configured networks. // * // * @param callbackContext A Cordova callback context // * @param data JSON Array, with [0] being SSID to remove // * @return true if network removed, false if failed // */ // private boolean remove(CallbackContext callbackContext, JSONArray data) { // Log.d(TAG, "WifiWizard2: remove entered."); // if (!validateData(data)) { // callbackContext.error("REMOVE_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: remove data invalid"); // return false; // } // // TODO: Verify the type of data! // try { // String ssidToDisconnect = data.getString(0); // if(API_VERSION >= 29){ // if (networkCallback != null) { // connectivityManager.unregisterNetworkCallback(networkCallback); // networkCallback = null; // } // connectivityManager.releaseNetworkRequest(pending_intent_net_req_received); // // WifiNetworkSuggestion wifiNetworkSuggestion = new WifiNetworkSuggestion.Builder() // // .setSsid(ssidToDisconnect) // // .build(); // // List list = new ArrayList(); // // list.add(wifiNetworkSuggestion); // // wifiManager.removeNetworkSuggestions(list); // callbackContext.success("NETWORK_REMOVED"); // return true; // } // int networkIdToRemove = ssidToNetworkId(ssidToDisconnect); // if (networkIdToRemove > -1) { // if( wifiManager.removeNetwork(networkIdToRemove) ){ // // Configurations persist by default in API 26+ // if (API_VERSION < 26) { // wifiManager.saveConfiguration(); // } // callbackContext.success("NETWORK_REMOVED"); // } else { // callbackContext.error( "UNABLE_TO_REMOVE" ); // } // return true; // } else { // callbackContext.error("REMOVE_NETWORK_NOT_FOUND"); // Log.d(TAG, "WifiWizard2: Network not found, can't remove."); // return false; // } // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // } // /** // * This method connects a network. // * // * @param callbackContext A Cordova callback context // * @param data JSON Array, with [0] being SSID to connect // */ // private void connect(CallbackContext callbackContext, JSONArray data) { // Log.d(TAG, "WifiWizard2: connect entered."); // if(API_VERSION >= 29){ // // No need to connect, its already connected via WifiNetworkSpecifier at add(...) method // callbackContext.success("NETWORK_CONNECTION_COMPLETED"); // return; // } // if (!validateData(data)) { // callbackContext.error("CONNECT_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: connect invalid data."); // return; // } // String ssidToConnect = ""; // String bindAll = "false"; // try { // ssidToConnect = data.getString(0); // bindAll = data.getString(1); // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return; // } // int networkIdToConnect = ssidToNetworkId(ssidToConnect); // if (networkIdToConnect > -1) { // // We disable the network before connecting, because if this was the last connection before // // a disconnect(), this will not reconnect. // Log.d(TAG, "Valid networkIdToConnect: attempting connection"); // // Bind all requests to WiFi network (only necessary for Lollipop+ - API 21+) // if( bindAll.equals("true") ){ // registerBindALL(networkIdToConnect); // } // if (API_VERSION >= 26) { // // wifiManager.disconnect(); // } else { // wifiManager.disableNetwork(networkIdToConnect); // } // wifiManager.enableNetwork(networkIdToConnect, true); // if (API_VERSION >= 26) { // // wifiManager.reassociate(); // } // new ConnectAsync().execute(callbackContext, networkIdToConnect); // return; // } else { // callbackContext.error("INVALID_NETWORK_ID_TO_CONNECT"); // return; // } // } // /** // * Wait for connection before returning error or success // * // * This method will wait up to 60 seconds for WiFi connection to specified network ID be in COMPLETED state, otherwise will return error. // * // * @param callbackContext // * @param networkIdToConnect // * @return // */ // private class ConnectAsync extends AsyncTask { // CallbackContext callbackContext; // @Override // protected void onPostExecute(String[] results) { // String error = results[0]; // String success = results[1]; // if (error != null) { // this.callbackContext.error(error); // } else { // this.callbackContext.success(success); // } // } // @Override // protected String[] doInBackground(Object... params) { // this.callbackContext = (CallbackContext) params[0]; // int networkIdToConnect = (Integer) params[1]; // final int TIMES_TO_RETRY = 15; // for (int i = 0; i < TIMES_TO_RETRY; i++) { // WifiInfo info = wifiManager.getConnectionInfo(); // NetworkInfo.DetailedState connectionState = info // .getDetailedStateOf(info.getSupplicantState()); // boolean isConnected = // // need to ensure we're on correct network because sometimes this code is // // reached before the initial network has disconnected // info.getNetworkId() == networkIdToConnect && ( // connectionState == NetworkInfo.DetailedState.CONNECTED || // // Android seems to sometimes get stuck in OBTAINING_IPADDR after it has received one // (connectionState == NetworkInfo.DetailedState.OBTAINING_IPADDR // && info.getIpAddress() != 0) // ); // if (isConnected) { // return new String[]{ null, "NETWORK_CONNECTION_COMPLETED" }; // } // Log.d(TAG, "WifiWizard: Got " + connectionState.name() + " on " + (i + 1) + " out of " + TIMES_TO_RETRY); // final int ONE_SECOND = 1000; // try { // Thread.sleep(ONE_SECOND); // } catch (InterruptedException e) { // Log.e(TAG, e.getMessage()); // return new String[]{ "INTERRUPT_EXCEPT_WHILE_CONNECTING", null }; // } // } // Log.d(TAG, "WifiWizard: Network failed to finish connecting within the timeout"); // return new String[]{ "CONNECT_FAILED_TIMEOUT", null }; // } // } // /** // * This method disconnects a network. // * // * @param callbackContext A Cordova callback context // * @param data JSON Array, with [0] being SSID to connect // * @return true if network disconnected, false if failed // */ // private boolean disconnectNetwork(CallbackContext callbackContext, JSONArray data) { // Log.d(TAG, "WifiWizard2: disconnectNetwork entered."); // if (!validateData(data)) { // callbackContext.error("DISCONNECT_NET_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: disconnectNetwork invalid data"); // return false; // } // String ssidToDisconnect = ""; // // TODO: Verify type of data here! // try { // ssidToDisconnect = data.getString(0); // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // if(API_VERSION < 29){ // int networkIdToDisconnect = ssidToNetworkId(ssidToDisconnect); // if(networkIdToDisconnect > 0) { // if(wifiManager.disableNetwork(networkIdToDisconnect)) { // maybeResetBindALL(); // // We also remove the configuration from the device (use "disable" to keep config) // if( wifiManager.removeNetwork(networkIdToDisconnect) ){ // callbackContext.success("Network " + ssidToDisconnect + " disconnected and removed!"); // } else { // callbackContext.error("DISCONNECT_NET_REMOVE_ERROR"); // Log.d(TAG, "WifiWizard2: Unable to remove network!"); // return false; // } // } else { // callbackContext.error("DISCONNECT_NET_DISABLE_ERROR"); // Log.d(TAG, "WifiWizard2: Unable to disable network!"); // return false; // } // return true; // } else { // callbackContext.error("DISCONNECT_NET_ID_NOT_FOUND"); // Log.d(TAG, "WifiWizard2: Network not found to disconnect."); // return false; // } // } else { // try{ // ConnectivityManager cm = (ConnectivityManager) cordova.getActivity().getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); // cm.unregisterNetworkCallback(this.networkCallback); // connectivityManager.bindProcessToNetwork(null); // return true; // } // catch(Exception e) { // callbackContext.error(e.getMessage()); // return false; // } // } // } // /** // * This method disconnects the currently connected network. // * // * @param callbackContext A Cordova callback context // * @return true if network disconnected, false if failed // */ // private boolean disconnect(CallbackContext callbackContext) { // Log.d(TAG, "WifiWizard2: disconnect entered."); // if (wifiManager.disconnect()) { // maybeResetBindALL(); // callbackContext.success("Disconnected from current network"); // return true; // } else { // callbackContext.error("ERROR_DISCONNECT"); // return false; // } // } // /** // * Reconnect Network // *

// * Reconnect to the currently active access point, if we are currently disconnected. This may // * result in the asynchronous delivery of state change events. // */ // private boolean reconnect(CallbackContext callbackContext) { // Log.d(TAG, "WifiWizard2: reconnect entered."); // if (wifiManager.reconnect()) { // callbackContext.success("Reconnected network"); // return true; // } else { // callbackContext.error("ERROR_RECONNECT"); // return false; // } // } // /** // * Reassociate Network // *

// * Reconnect to the currently active access point, even if we are already connected. This may // * result in the asynchronous delivery of state change events. // */ // private boolean reassociate(CallbackContext callbackContext) { // Log.d(TAG, "WifiWizard2: reassociate entered."); // if (wifiManager.reassociate()) { // callbackContext.success("Reassociated network"); // return true; // } else { // callbackContext.error("ERROR_REASSOCIATE"); // return false; // } // } // /** // * This method uses the callbackContext.success method to send a JSONArray of the currently // * configured networks. // * // * @param callbackContext A Cordova callback context // * @return true if network disconnected, false if failed // */ // private boolean listNetworks(CallbackContext callbackContext) { // Log.d(TAG, "WifiWizard2: listNetworks entered."); // @SuppressLint("MissingPermission") List wifiList = wifiManager.getConfiguredNetworks(); // JSONArray returnList = new JSONArray(); // for (WifiConfiguration wifi : wifiList) { // returnList.put(wifi.SSID); // } // callbackContext.success(returnList); // return true; // } // /** // * This method uses the callbackContext.success method to send a JSONArray of the scanned // * networks. // * // * @param callbackContext A Cordova callback context // * @param data JSONArray with [0] == JSONObject // * @return true // */ // private boolean getScanResults(CallbackContext callbackContext, JSONArray data) { // if (cordova.hasPermission(ACCESS_FINE_LOCATION)) { // List scanResults = wifiManager.getScanResults(); // JSONArray returnList = new JSONArray(); // Integer numLevels = null; // if (!validateData(data)) { // callbackContext.error("GET_SCAN_RESULTS_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: getScanResults invalid data"); // return false; // } else if (!data.isNull(0)) { // try { // JSONObject options = data.getJSONObject(0); // if (options.has("numLevels")) { // Integer levels = options.optInt("numLevels"); // if (levels > 0) { // numLevels = levels; // } else if (options.optBoolean("numLevels", false)) { // // use previous default for {numLevels: true} // numLevels = 5; // } // } // } catch (JSONException e) { // e.printStackTrace(); // callbackContext.error(e.toString()); // return false; // } // } // for (ScanResult scan : scanResults) { // /* // * @todo - breaking change, remove this notice when tidying new release and explain changes, e.g.: // * 0.y.z includes a breaking change to WifiWizard2.getScanResults(). // * Earlier versions set scans' level attributes to a number derived from wifiManager.calculateSignalLevel. // * This update returns scans' raw RSSI value as the level, per Android spec / APIs. // * If your application depends on the previous behaviour, we have added an options object that will modify behaviour: // * - if `(n == true || n < 2)`, `*.getScanResults({numLevels: n})` will return data as before, split in 5 levels; // * - if `(n > 1)`, `*.getScanResults({numLevels: n})` will calculate the signal level, split in n levels; // * - if `(n == false)`, `*.getScanResults({numLevels: n})` will use the raw signal level; // */ // int level; // if (numLevels == null) { // level = scan.level; // } else { // level = wifiManager.calculateSignalLevel(scan.level, numLevels); // } // JSONObject lvl = new JSONObject(); // try { // lvl.put("level", level); // lvl.put("SSID", scan.SSID); // lvl.put("BSSID", scan.BSSID); // lvl.put("frequency", scan.frequency); // lvl.put("capabilities", scan.capabilities); // lvl.put("timestamp", scan.timestamp); // if (API_VERSION >= 23) { // Marshmallow // lvl.put("channelWidth", scan.channelWidth); // lvl.put("centerFreq0", scan.centerFreq0); // lvl.put("centerFreq1", scan.centerFreq1); // } else { // lvl.put("channelWidth", JSONObject.NULL); // lvl.put("centerFreq0", JSONObject.NULL); // lvl.put("centerFreq1", JSONObject.NULL); // } // returnList.put(lvl); // } catch (JSONException e) { // e.printStackTrace(); // callbackContext.error(e.toString()); // return false; // } // } // callbackContext.success(returnList); // return true; // } else { // requestLocationPermission(SCAN_RESULTS_CODE); // return true; // } // } // /** // * This method uses the callbackContext.success method. It starts a wifi scanning // * // * @param callbackContext A Cordova callback context // * @return true if started was successful // */ // private boolean startScan(CallbackContext callbackContext) { // if (wifiManager.startScan()) { // callbackContext.success(); // return true; // } else { // callbackContext.error("STARTSCAN_FAILED"); // return false; // } // } // /** // * This method returns the connected WiFi network ID (if connected) // * // * @return -1 if no network connected, or network id if connected // */ // private int getConnectedNetId() { // int networkId = -1; // WifiInfo info = wifiManager.getConnectionInfo(); // if (info == null) { // Log.d(TAG, "Unable to read wifi info"); // return networkId; // } // networkId = info.getNetworkId(); // if (networkId == -1) { // Log.d(TAG, "NO_CURRENT_NETWORK_FOUND"); // } // return networkId; // } // /** // * Get Network ID from SSID // * // * @param callbackContext A Cordova callback context // * @param data JSON Array, with [0] being SSID to connect // * @return true if network connected, false if failed // */ // private boolean getSSIDNetworkID(CallbackContext callbackContext, JSONArray data) { // Log.d(TAG, "WifiWizard2: getSSIDNetworkID entered."); // if (!validateData(data)) { // callbackContext.error("GET_SSID_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: getSSIDNetworkID invalid data."); // return false; // } // String ssidToGetNetworkID = ""; // try { // ssidToGetNetworkID = data.getString(0); // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // int networkIdToConnect = ssidToNetworkId(ssidToGetNetworkID); // callbackContext.success(networkIdToConnect); // return true; // } // /** // * This method returns the connected WiFi network ID (if connected) // * // * @param callbackContext A Cordova callback context // * @return -1 if no network connected, or network id if connected // */ // private boolean getConnectedNetworkID(CallbackContext callbackContext) { // int networkId = getConnectedNetId(); // if (networkId == -1) { // callbackContext.error("GET_CONNECTED_NET_ID_ERROR"); // return false; // } // callbackContext.success(networkId); // return true; // } // /** // * This method retrieves the SSID for the currently connected network // * // * @param callbackContext A Cordova callback context // * @return true if SSID found, false if not. // */ // private boolean getConnectedSSID(CallbackContext callbackContext) { // return getWifiServiceInfo(callbackContext, false); // } // /** // * This method retrieves the BSSID for the currently connected network // * // * @param callbackContext A Cordova callback context // * @return true if SSID found, false if not. // */ // private boolean getConnectedBSSID(CallbackContext callbackContext) { // return getWifiServiceInfo(callbackContext, true); // } // /** // * This method retrieves the WifiInformation for the (SSID or BSSID) currently connected network. // * // * @param callbackContext A Cordova callback context // * @param basicIdentifier A flag to get BSSID if true or SSID if false. // * @return true if SSID found, false if not. // */ // private boolean getWifiServiceInfo(CallbackContext callbackContext, boolean basicIdentifier) { // if (API_VERSION >= 23 && !cordova.hasPermission(ACCESS_FINE_LOCATION)) { //Android 9 (Pie) or newer // requestLocationPermission(WIFI_SERVICE_INFO_CODE); // bssidRequested = basicIdentifier; // return true; // } else { // WifiInfo info = wifiManager.getConnectionInfo(); // if (info == null) { // callbackContext.error("UNABLE_TO_READ_WIFI_INFO"); // return false; // } // // Only return SSID or BSSID when actually connected to a network // SupplicantState state = info.getSupplicantState(); // if (!state.equals(SupplicantState.COMPLETED)) { // callbackContext.error("CONNECTION_NOT_COMPLETED"); // return false; // } // String serviceInfo; // if (basicIdentifier) { // serviceInfo = info.getBSSID(); // } else { // serviceInfo = info.getSSID(); // } // if (serviceInfo == null || serviceInfo.isEmpty() || serviceInfo == "0x") { // callbackContext.error("WIFI_INFORMATION_EMPTY"); // return false; // } // // http://developer.android.com/reference/android/net/wifi/WifiInfo.html#getSSID() // if (serviceInfo.startsWith("\"") && serviceInfo.endsWith("\"")) { // serviceInfo = serviceInfo.substring(1, serviceInfo.length() - 1); // } // callbackContext.success(serviceInfo); // return true; // } // } // /** // * This method retrieves the current WiFi status // * // * @param callbackContext A Cordova callback context // * @return true if WiFi is enabled, fail will be called if not. // */ // private boolean isWifiEnabled(CallbackContext callbackContext) { // boolean isEnabled = wifiManager.isWifiEnabled(); // callbackContext.success(isEnabled ? "1" : "0"); // return isEnabled; // } // /** // * This method takes a given String, searches the current list of configured WiFi networks, and // * returns the networkId for the network if the SSID matches. If not, it returns -1. // */ // private int ssidToNetworkId(String ssid) { // try { // int maybeNetId = Integer.parseInt(ssid); // Log.d(TAG, "ssidToNetworkId passed SSID is integer, probably a Network ID: " + ssid); // return maybeNetId; // } catch (NumberFormatException e) { // List currentNetworks = wifiManager.getConfiguredNetworks(); // int networkId = -1; // // For each network in the list, compare the SSID with the given one // for (WifiConfiguration test : currentNetworks) { // if (test.SSID != null && test.SSID.equals(ssid)) { // networkId = test.networkId; // } // } // return networkId; // } // } // /** // * This method enables or disables the wifi // */ // private boolean setWifiEnabled(CallbackContext callbackContext, JSONArray data) { // if (!validateData(data)) { // callbackContext.error("SETWIFIENABLED_INVALID_DATA"); // Log.d(TAG, "WifiWizard2: setWifiEnabled invalid data"); // return false; // } // String status = ""; // try { // status = data.getString(0); // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // if (wifiManager.setWifiEnabled(status.equals("true"))) { // callbackContext.success(); // return true; // } else { // callbackContext.error("ERROR_SETWIFIENABLED"); // return false; // } // } // /** // * This method will check if WiFi is enabled, and enable it if not, waiting up to 10 seconds for // * it to enable // * // * @return True if wifi is enabled, false if unable to enable wifi // */ // private boolean verifyWifiEnabled() { // Log.d(TAG, "WifiWizard2: verifyWifiEnabled entered."); // if (!wifiManager.isWifiEnabled()) { // Log.i(TAG, "Enabling wi-fi..."); // if (wifiManager.setWifiEnabled(true)) { // Log.i(TAG, "Wi-fi enabled"); // } else { // Log.e(TAG, "VERIFY_ERROR_ENABLE_WIFI"); // return false; // } // // This happens very quickly, but need to wait for it to enable. A little busy wait? // int count = 0; // while (!wifiManager.isWifiEnabled()) { // if (count >= 10) { // Log.i(TAG, "Took too long to enable wi-fi, quitting"); // return false; // } // Log.i(TAG, "Still waiting for wi-fi to enable..."); // try { // Thread.sleep(1000L); // } catch (InterruptedException ie) { // // continue // } // count++; // } // // If we make it this far, wifi should be enabled by now // return true; // } else { // return true; // } // } // /** // * Format and return WiFi IPv4 Address // * @return // */ // private String[] getWiFiIPAddress() { // WifiInfo wifiInfo = wifiManager.getConnectionInfo(); // int ip = wifiInfo.getIpAddress(); // String ipString = formatIP(ip); // String subnet = ""; // try { // InetAddress inetAddress = InetAddress.getByName(ipString); // subnet = getIPv4Subnet(inetAddress); // } catch (Exception e) { // } // return new String[]{ipString, subnet}; // } // /** // * Get WiFi Router IP from DHCP // * @return // */ // private String getWiFiRouterIP() { // DhcpInfo dhcp = wifiManager.getDhcpInfo(); // int ip = dhcp.gateway; // return formatIP(ip); // } // /** // * Format IPv4 Address // * @param ip // * @return // */ // private String formatIP(int ip) { // return String.format( // "%d.%d.%d.%d", // (ip & 0xff), // (ip >> 8 & 0xff), // (ip >> 16 & 0xff), // (ip >> 24 & 0xff) // ); // } // /** // * Get IPv4 Subnet // * @param inetAddress // * @return // */ // public static String getIPv4Subnet(InetAddress inetAddress) { // try { // NetworkInterface ni = NetworkInterface.getByInetAddress(inetAddress); // List intAddrs = ni.getInterfaceAddresses(); // for (InterfaceAddress ia : intAddrs) { // if (!ia.getAddress().isLoopbackAddress() && ia.getAddress() instanceof Inet4Address) { // return getIPv4SubnetFromNetPrefixLength(ia.getNetworkPrefixLength()).getHostAddress() // .toString(); // } // } // } catch (Exception e) { // } // return ""; // } // /** // * Get Subnet from Prefix Length // * @param netPrefixLength // * @return // */ // public static InetAddress getIPv4SubnetFromNetPrefixLength(int netPrefixLength) { // try { // int shift = (1 << 31); // for (int i = netPrefixLength - 1; i > 0; i--) { // shift = (shift >> 1); // } // String subnet = // Integer.toString((shift >> 24) & 255) + "." + Integer.toString((shift >> 16) & 255) + "." // + Integer.toString((shift >> 8) & 255) + "." + Integer.toString(shift & 255); // return InetAddress.getByName(subnet); // } catch (Exception e) { // } // return null; // } // /** // * Validate JSON data // */ // private boolean validateData(JSONArray data) { // try { // if (data == null || data.get(0) == null) { // callbackContext.error("DATA_IS_NULL"); // return false; // } // return true; // } catch (Exception e) { // callbackContext.error(e.getMessage()); // } // return false; // } // /** // * Request ACCESS_FINE_LOCATION Permission // * @param requestCode // */ // protected void requestLocationPermission(int requestCode) { // cordova.requestPermission(this, requestCode, ACCESS_FINE_LOCATION); // } // /** // * Handle Android Permission Requests // */ // public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) // throws JSONException { // for (int r : grantResults) { // if (r == PackageManager.PERMISSION_DENIED) { // callbackContext.error( "PERMISSION_DENIED" ); // return; // } // } // switch (requestCode) { // case SCAN_RESULTS_CODE: // getScanResults(callbackContext, passedData); // Call method again after permissions approved // break; // case SCAN_CODE: // scan(callbackContext, passedData); // Call method again after permissions approved // break; // case LOCATION_REQUEST_CODE: // callbackContext.success("PERMISSION_GRANTED"); // break; // case WIFI_SERVICE_INFO_CODE: // getWifiServiceInfo(callbackContext, bssidRequested); // break; // } // } // /** // * Figure out what the highest priority network in the network list is and return that priority // */ // private static int getMaxWifiPriority(final WifiManager wifiManager) { // final List configurations = wifiManager.getConfiguredNetworks(); // int maxPriority = 0; // for (WifiConfiguration config : configurations) { // if (config.priority > maxPriority) { // maxPriority = config.priority; // } // } // Log.d(TAG, "WifiWizard: Found max WiFi priority of " // + maxPriority); // return maxPriority; // } // /** // * Check if device is connected to Internet // */ // private boolean canConnectToInternet(CallbackContext callbackContext, boolean doPing) { // try { // if ( hasInternetConnection(doPing) ) { // // Send success as 1 to return true from Promise (handled in JS) // callbackContext.success("1"); // return true; // } else { // callbackContext.success("0"); // return false; // } // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // } // /** // * Check if we can conenct to router via HTTP connection // * // * @param callbackContext // * @param doPing // * @return boolean // */ // private boolean canConnectToRouter(CallbackContext callbackContext, boolean doPing) { // try { // if (hasConnectionToRouter(doPing)) { // // Send success as 1 to return true from Promise (handled in JS) // callbackContext.success("1"); // return true; // } else { // callbackContext.success("0"); // return false; // } // } catch (Exception e) { // callbackContext.error(e.getMessage()); // Log.d(TAG, e.getMessage()); // return false; // } // } // /** // * Check if The Device Is Connected to Internet // * // * @return true if device connect to Internet or return false if not // */ // public boolean hasInternetConnection(boolean doPing) { // if (connectivityManager != null) { // NetworkInfo info = connectivityManager.getActiveNetworkInfo(); // if (info != null) { // if (info.isConnected()) { // if( doPing ){ // return pingCmd("8.8.8.8"); // } else { // return isHTTPreachable("http://www.google.com/"); // } // } // } // } // return false; // } // /** // * Check for connection to router by pinging router IP // * @return // */ // public boolean hasConnectionToRouter( boolean doPing ) { // String ip = getWiFiRouterIP(); // if ( ip == null || ip.equals("0.0.0.0") || connectivityManager == null) { // return false; // } else { // NetworkInfo info = connectivityManager.getActiveNetworkInfo(); // if (info != null && info.isConnected()) { // if( doPing ){ // return pingCmd(ip); // } else { // return isHTTPreachable("http://" + ip + "/"); // } // } else { // return false; // } // } // } // /** // * Check if HTTP connection to URL is reachable // * // * @param checkURL // * @return boolean // */ // public static boolean isHTTPreachable(String checkURL) { // try { // // make a URL to a known source // URL url = new URL(checkURL); // // open a connection to that source // HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection(); // // trying to retrieve data from the source. If there // // is no connection, this line will fail // Object objData = urlConnect.getContent(); // } catch (Exception e) { // e.printStackTrace(); // return false; // } // return true; // } // /** // * Method to Ping IP Address // * // * @param addr IP address you want to ping it // * @return true if the IP address is reachable // */ // public boolean pingCmd(String addr) { // try { // String ping = "ping -c 1 -W 3 " + addr; // Runtime run = Runtime.getRuntime(); // Process pro = run.exec(ping); // try { // pro.waitFor(); // } catch (InterruptedException e) { // Log.e(TAG, "InterruptedException error.", e); // } // int exit = pro.exitValue(); // Log.d(TAG, "pingCmd exitValue" + exit); // if (exit == 0) { // return true; // } else { // // ip address is not reachable // return false; // } // } catch (UnknownHostException e) { // Log.d(TAG, "UnknownHostException: " + e.getMessage()); // } catch (Exception e) { // Log.d(TAG, e.getMessage()); // } // return false; // } // /** // * Network Changed Broadcast Receiver // */ // private class NetworkChangedReceiver extends BroadcastReceiver { // @Override // public void onReceive(final Context context, final Intent intent) { // if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) { // Log.d(TAG, "NETWORK_STATE_CHANGED_ACTION"); // NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); // WifiInfo info = WifiWizard2.this.wifiManager.getConnectionInfo(); // // Checks that you're connected to the desired network // if (networkInfo.isConnected() && info.getNetworkId() > -1) { // final String ssid = info.getSSID().replaceAll("\"", ""); // final String bssid = info.getBSSID(); // Log.d(TAG, "Connected to '" + ssid + "' @ " + bssid); // // Verify the desired network ID is what we actually connected to // if ( desired != null && info.getNetworkId() == desired.apId ) { // onSuccessfulConnection(); // } else { // Log.e(TAG, "Could not connect to the desired ssid: " + ssid); // } // } // } // } // } // /** // * Register Receiver for Network Changed to handle BindALL // * @param netID // */ // private void registerBindALL(int netID){ // // Bind all requests to WiFi network (only necessary for Lollipop+ - API 21+) // if( API_VERSION > 21 ){ // Log.d(TAG, "registerBindALL: registering net changed receiver"); // desired = new AP(netID,null,null); // cordova.getActivity().getApplicationContext().registerReceiver(networkChangedReceiver, NETWORK_STATE_CHANGED_FILTER); // } else { // Log.d(TAG, "registerBindALL: API older than 21, bindall ignored."); // } // } // /** // * Maybe reset bind all after disconnect/disable // * // * This method unregisters the network changed receiver, as well as setting null for // * bindProcessToNetwork or setProcessDefaultNetwork to prevent future sockets from application // * being routed through Wifi. // */ // private void maybeResetBindALL(){ // Log.d(TAG, "maybeResetBindALL"); // // desired should have a value if receiver is registered // if( desired != null ){ // if( API_VERSION > 21 ){ // try { // // Unregister net changed receiver -- should only be registered in API versions > 21 // cordova.getActivity().getApplicationContext().unregisterReceiver(networkChangedReceiver); // } catch (Exception e) {} // } // // Lollipop OS or newer // if ( API_VERSION >= 23 ) { // connectivityManager.bindProcessToNetwork(null); // } else if( API_VERSION >= 21 && API_VERSION < 23 ){ // connectivityManager.setProcessDefaultNetwork(null); // } // if ( API_VERSION > 21 && networkCallback != null) { // try { // // Same behavior as releaseNetworkRequest // connectivityManager.unregisterNetworkCallback(networkCallback); // Added in API 21 // } catch (Exception e) {} // } // networkCallback = null; // previous = null; // desired = null; // } // } // /** // * Will un-bind to network (use Cellular network) // * // * @param callbackContext A Cordova callback context // */ // private void resetBindAll(CallbackContext callbackContext) { // Log.d(TAG, "WifiWizard2: resetBindALL"); // try { // maybeResetBindALL(); // callbackContext.success("Successfully reset BindALL"); // } catch (Exception e) { // Log.e(TAG, "InterruptedException error.", e); // callbackContext.error("ERROR_NO_BIND_ALL"); // } // } // /** // * Will bind to network (use Wifi network) // * // * @param callbackContext A Cordova callback context // */ // private void setBindAll(CallbackContext callbackContext) { // Log.d(TAG, "WifiWizard2: setBindALL"); // try { // int networkId = getConnectedNetId(); // registerBindALL(networkId); // callbackContext.success("Successfully bindAll to network"); // } catch (Exception e) { // Log.e(TAG, "InterruptedException error.", e); // callbackContext.error("ERROR_CANT_BIND_ALL"); // } // } // /** // * Called after successful connection to WiFi when using BindAll feature // * // * This method is called by the NetworkChangedReceiver after network changed action, and confirming that we are in fact connected to wifi, // * and the wifi we're connected to, is the correct network set in enable, or connect. // */ // private void onSuccessfulConnection() { // // On Lollipop+ the OS routes network requests through mobile data // // when phone is attached to a wifi that doesn't have Internet connection // // We use the ConnectivityManager to force bind all requests from our process // // to the wifi without internet // // see https://android-developers.googleblog.com/2016/07/connecting-your-app-to-wi-fi-device.html // // Marshmallow OS or newer // if ( API_VERSION >= 23 ) { // Log.d(TAG, "BindALL onSuccessfulConnection API >= 23"); // // Marshmallow (API 23+) or newer uses bindProcessToNetwork // final NetworkRequest request = new NetworkRequest.Builder() // .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) // .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability added for hotspots without internet // .build(); // networkCallback = new ConnectivityManager.NetworkCallback() { // @Override // public void onAvailable(Network network) { // if( connectivityManager.bindProcessToNetwork(network) ){ // Log.d(TAG, "bindProcessToNetwork TRUE onSuccessfulConnection"); // } else { // Log.d(TAG, "bindProcessToNetwork FALSE onSuccessfulConnection"); // } // } // }; // connectivityManager.requestNetwork(request, networkCallback); // // Only lollipop (API 21 && 22) use setProcessDefaultNetwork, API < 21 already does this by default // } else if( API_VERSION >= 21 && API_VERSION < 23 ){ // Log.d(TAG, "BindALL onSuccessfulConnection API >= 21 && < 23"); // // Lollipop (API 21-22) use setProcessDefaultNetwork (deprecated in API 23 - Marshmallow) // final NetworkRequest request = new NetworkRequest.Builder() // .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) // .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability addded for hotspots without internet // .build(); // networkCallback = new ConnectivityManager.NetworkCallback() { // @Override // public void onAvailable(Network network) { // connectivityManager.setProcessDefaultNetwork(network); // } // }; // connectivityManager.requestNetwork(request, networkCallback); // } else { // // Technically we should never reach this with older API, but just in case // Log.d(TAG, "BindALL onSuccessfulConnection API older than 21, no need to do any binding"); // networkCallback = null; // previous = null; // desired = null; // } // } // /** // * Class to store finished boolean in // */ // private class ScanSyncContext { // public boolean finished = false; // } // /** // * Used for storing access point information // */ // private static class AP { // final String ssid, bssid; // final int apId; // AP(int apId, final String ssid, final String bssid) { // this.apId = apId; // this.ssid = ssid; // this.bssid = bssid; // } // } // }