package com.almalence.sony.cameraremote.utils; import java.util.ArrayList; import java.util.List; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.util.Log; public class WifiHandler { private Context mContext; private WifiManager mWifiManager; private WifiInfo lastWifiConnected; private NetworkInfo.State cameraWifiState; private List<WifiListener> listeners; public WifiHandler(Context context) { this.mContext = context; mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); listeners = new ArrayList<WifiListener>(); cameraWifiState = State.UNKNOWN; } public void checkForConnection() { cameraWifiState = State.DISCONNECTED; WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); if(wifiInfo != null) { String ssid = parseSSID(wifiInfo.getSSID()); if(isSonyCameraSSID(ssid)) { // Don't need to check more, camera is already connected connected(ssid); return; } } for(WifiListener listener : listeners) { listener.onWifiStartScan(); } mContext.registerReceiver(scanResultsBroadcastReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); mWifiManager.startScan(); } public void createIfNeededThenConnectToWifi(String networkSSID, String networkPassword) { mWifiManager.setWifiEnabled(true); int netId = -1; List<WifiConfiguration> list = mWifiManager.getConfiguredNetworks(); if(list != null) { for( WifiConfiguration i : list ) { // In the case of network is already registered if(i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) { // In case password changed since last time i.preSharedKey = "\""+ networkPassword +"\""; mWifiManager.saveConfiguration(); netId = i.networkId; break; } } } // In the case of network is not registered create it and join it if(netId == -1) { netId = createWPAWifi(networkSSID, networkPassword); } connectToNetworkId(netId); } public void connectToNetworkId(int netId) { List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks(); for(WifiConfiguration wc : configuredNetworks) { if(wc.networkId != netId) { continue; } cameraWifiState = State.CONNECTING; WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); if(wifiInfo != null) { String ssid = parseSSID(mWifiManager.getConnectionInfo().getSSID()); if(!isSonyCameraSSID(ssid)) { lastWifiConnected = mWifiManager.getConnectionInfo(); } } // Connect only if network id exist mWifiManager.enableNetwork(netId, true); for(WifiListener listener : listeners) { listener.onWifiConnecting(wc.SSID); } } } private int createWPAWifi(String networkSSID, String networkPassword) { WifiConfiguration wc = new WifiConfiguration(); wc.SSID = "\"" + networkSSID + "\""; wc.preSharedKey = "\""+ networkPassword +"\""; wc.hiddenSSID = true; wc.status = WifiConfiguration.Status.ENABLED; wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN); int netId = mWifiManager.addNetwork(wc); mWifiManager.saveConfiguration(); return netId; } public void reconnectToLastWifi() { if(lastWifiConnected != null) { mWifiManager.enableNetwork(lastWifiConnected.getNetworkId(), true); // Maybe remove comment on this line for more logic //lastWifiConnected = null; } } private static boolean isSonyCameraSSID(String ssid) { return ssid != null && ssid.matches("^DIRECT-\\w{4}:.*$"); } private WifiConfiguration getWifiConfigurationFromSSID(String SSID) { List<WifiConfiguration> knownNetworks = mWifiManager.getConfiguredNetworks(); if(knownNetworks == null) { return null; } for(WifiConfiguration net : knownNetworks) { if(net.SSID != null && net.SSID.equals("\""+SSID+"\"")) { return net; } } return null; } public void addListener(WifiListener listener) { if(listeners.contains(listener)) { return; } listeners.add(listener); } public void removeListener(WifiListener listener) { if(!listeners.contains(listener)) { return; } listeners.remove(listener); } private void connected(String ssid) { cameraWifiState = State.CONNECTED; for(WifiListener listener : listeners) { listener.onWifiConnected(ssid); } } private void disconnected() { cameraWifiState = State.DISCONNECTED; for(WifiListener listener : listeners) { listener.onWifiDisconnected(); } } private BroadcastReceiver wifiBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { NetworkInfo networkInfo = null; try { networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); } catch (Exception e) { e.printStackTrace(); return; } if(networkInfo == null || networkInfo.getType() != ConnectivityManager.TYPE_WIFI) { return; } WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); NetworkInfo.State state = networkInfo.getState(); if(cameraWifiState == State.CONNECTED && state == State.DISCONNECTED) { disconnected(); } if(state == State.CONNECTED && wifiInfo != null) { String ssid = parseSSID(wifiInfo.getSSID()); if(!isSonyCameraSSID(ssid)) { return; } connected(ssid); } } }; private BroadcastReceiver scanResultsBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { List<WifiConfiguration> sonyCameraWifiConfiguration = new ArrayList<WifiConfiguration>(); List<ScanResult> sonyCameraScanResults = new ArrayList<ScanResult>(); List<ScanResult> results = mWifiManager.getScanResults(); for(ScanResult sr : results) { if(!isSonyCameraSSID(sr.SSID)) { continue; } sonyCameraScanResults.add(sr); WifiConfiguration wc = getWifiConfigurationFromSSID(sr.SSID); if(wc == null) { continue; } sonyCameraWifiConfiguration.add(wc); } for(WifiListener listener : listeners) { listener.onWifiScanFinished(sonyCameraScanResults, sonyCameraWifiConfiguration); } context.unregisterReceiver(scanResultsBroadcastReceiver); } }; public void register() { final IntentFilter filters = new IntentFilter(); filters.addAction("android.net.wifi.WIFI_STATE_CHANGED"); filters.addAction("android.net.wifi.STATE_CHANGE"); mContext.registerReceiver(wifiBroadcastReceiver, filters); } public void unregister() { try { mContext.unregisterReceiver(wifiBroadcastReceiver); mContext.unregisterReceiver(scanResultsBroadcastReceiver); } catch (IllegalArgumentException e) { } } public State getCameraWifiState() { return cameraWifiState; } private String parseSSID(String ssid) { if(ssid != null && ssid.length() >= 2 && ssid.charAt(0) == '"' && ssid.charAt(ssid.length()-1) == '"') { return ssid.substring(1, ssid.length()-1); } return ssid; } }