我正在尝试创建一个应用程序将连接到Wi-Fi的应用程序。 它在Android 6下面的所有Android设备中连接到Wifi。但是在Android 6中,它会在10-20秒之后连接并丢弃。以下是完整的Wifi Manager代码。
我在下面的代码中做错了什么。 我要求运行时LOCATION权限,并要求打开位置。所有清单权限都在Manifest中添加。 ACCESS_WIFI_STATE,CHANGE_WIFI_STATE,CHANGE_NETWORK_STATE,ACCESS_NETWORK_STATE, ACCESS_COARSE_LOCATION,ACCESS_FINE_LOCATION。
public class WifiManager implements Handler.Callback {
private static final String TAG = WifiManager.class.getSimpleName();
private Handler handler;
private Context reactContext;
private static final String WIFI_EVENT_NAME = "WiFiStatusEvent";
private static final String WIFI_STATUS = "WiFiStatus";
private static final int STATE_UNKNOWN = 0;
private static final int STATE_WIFI_OFF = 1;
private static final int STATE_WIFI_ON = 2;
private static final int STATE_SSID_VISIBLE = 3;
private static final int STATE_SSID_CONFIGURED = 4;
private static final int STATE_SSID_ASSOCIATING = 5;
private static final int STATE_SSID_ASSOCIATED = 6;
// A slight delay after the wifi says it is connected before we return to the calling app.
// (Sometimes the wifi isn't quite ready yet, even though it says it is)
private static final long DELAY_AFTER_CONNECTION_TIMEOUT = 1000 * 2;
// ESSID connect default timeout
private static final long DEFAULT_TARGET_NETWORK_CONNECT_TIMEOUT = 15 * 1000;
// Internal connection progress states
private int state = STATE_UNKNOWN;
// The system wifi manager
private android.net.wifi.WifiManager wifi;
// The application context to use for system functions
private String targetSSID = null;
// The given callback to message when we are done
private Handler timeoutHandler = null;
private static long timeout = 500000;
public WifiManager(Context reactContext) {
this.reactContext = reactContext;
wifi = (android.net.wifi.WifiManager) reactContext.getApplicationContext().getSystemService(WIFI_SERVICE);
}
public void connectToHost(Context context, String host, String password) {
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = host;
//wc.preSharedKey = password;
int netId = wifi.addNetwork(wc);
try {
wifi.enableNetwork(netId, true);
wifi.setWifiEnabled(true);
System.out.println("enabled network");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public void connectToHost2(Context context, String host, String password) {
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = host;
//wc.preSharedKey = password;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
int netId = wifi.addNetwork(wc);
WifiConfiguration wifiConfig = setWifiConfiguration(targetSSID, WifiConfiguration.KeyMgmt.NONE);
int networkId = wifi.addNetwork(wifiConfig);
logInfo(TAG, "networkId :: " + networkId);
wifi.saveConfiguration();
try {
wifi.enableNetwork(netId, true);
wifi.setWifiEnabled(true);
System.out.println("enabled network");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public void connectToWifi() {
try {
WifiConfiguration wc = new WifiConfiguration();
WifiInfo wifiInfo = wifi.getConnectionInfo();
wc.SSID = "\"WIFI_SSID\"";
wc.priority = 1;
//wc.preSharedKey = "\"PASSWORD\"";
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
int netId = wifi.addNetwork(wc);
if (netId == -1) {
netId = getExistingNetworkId(wc.SSID);
}
wifi.disconnect();
wifi.enableNetwork(netId, true);
wifi.reconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
private int getExistingNetworkId(String SSID) {
List<WifiConfiguration> configuredNetworks = wifi.getConfiguredNetworks();
if (configuredNetworks != null) {
for (WifiConfiguration existingConfig : configuredNetworks) {
if (existingConfig.SSID.equals(SSID)) {
return existingConfig.networkId;
}
}
}
return -1;
}
public void connectToWifi(String wifiSSID) {
logInfo(TAG, "Connecting to " + wifiSSID);
if (null == handler) {
handler = new Handler(this);
}
if (null == wifiSSID || wifiSSID.isEmpty()) {
return;
}
displayLocationSettingsRequest(reactContext);
this.targetSSID = wifiSSID;
//removeNetwork();
connectToTargetNetwork();
}
//@ReactMethod
public void isConnected(String wifiSSID) {
this.targetSSID = wifiSSID;
}
@Override
public boolean handleMessage(Message msg) {
if (null == msg) {
logError(TAG, "Callback, error");
return false;
}
if (null == msg.obj) {
logError(TAG, "Callback, error");
return false;
}
WifiStatus wifiStatus = (WifiStatus) msg.obj;
if (null != wifiStatus) {
logInfo(TAG, "ID :: " + wifiStatus.getId());
}
return false;
}
/**
* WIFI state callback - Listening for WIFI on/off transitions
*/
private BroadcastReceiver wifiStateReceiver = new BroadcastReceiver() {
public void onReceive(Context c, Intent intent) {
logInfo(TAG, "WifiStateReceiver - onReceive" + intent.getPackage());
ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo currentNetworkInfo = cm.getActiveNetworkInfo();
if (currentNetworkInfo != null && "WIFI".equals(currentNetworkInfo.getTypeName())) {
logInfo(TAG, "NetworkInfo - TypeName = " + currentNetworkInfo.getTypeName() + ", state = " + currentNetworkInfo.getState());
if (currentNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
if (isConnectedToTargetNetwork()) {
sendCallbackMessage(handler, WifiStatus.ASSOCIATED);
delayBeforeFinish();
return;
}
}
// We are connected
if (!isConnectedToTargetNetwork()) {
state = STATE_WIFI_ON;
logInfo(TAG, "Starting wifi scan...");
wifi.startScan();
}
}
}
};
/**
* WIFI state callback - Listening for network scan completion
*/
private BroadcastReceiver wifiScanResultsReceiver = new BroadcastReceiver() {
public void onReceive(Context c, Intent intent) {
Logger.logWarning(TAG, "WifiScanResultsReceiver - onReceive");
// Don't care unless wifi is on
if (state != STATE_WIFI_ON) {
return;
}
// Check if we are already connected to target network
if (isConnectedToTargetNetwork()) {
sendCallbackMessage(handler, WifiStatus.ASSOCIATED);
delayBeforeFinish();
return;
}
// Check if the target network showed up in the scan
if (isOurNetworkVisible()) {
logInfo(TAG, "Scan found our ESSID:" + targetSSID);
connectToVisibleNetwork();
} else {
logInfo(TAG, "Scan DID NOT FIND ESSID:" + targetSSID);
}
}
};
/**
* method to return the current WIFI connectivity state
*
* @param targetSSID the network SSID we are hoping to be associated with
* @return connection status
*/
public WifiStatus getStatus(String targetSSID) {
// Get a temporary WiFiManager instance since this is a static method
// Check if wifi is on
if (!wifi.isWifiEnabled()) {
return WifiStatus.WIFI_OFF;
}
// Check if associated to anything
WifiInfo wifiInfo = wifi.getConnectionInfo();
if (wifiInfo == null || wifiInfo.getSSID() == null) {
return WifiStatus.WIFI_ON;
}
// Check if associated to given SSID
if (wifiInfo.getSSID().equals(targetSSID)) {
return WifiStatus.ASSOCIATED;
}
// Check if given SSID is visible
List<ScanResult> wifiList = wifi.getScanResults();
for (ScanResult info : wifiList) {
if (targetSSID.equals(info.SSID)) {
return WifiStatus.SSID_VISIBLE;
}
}
return WifiStatus.SSID_NOT_VISIBLE;
}
/**
* Method to turn off WiFi
*
* @param context the callers application context
* @return true if successful
*/
public boolean turnOffWifi(Context context) {
// Get a temporary WiFiManager instance since this is a static method
return wifi.setWifiEnabled(false);
}
/**
* Sends a message to the callback.
*
* @param callback the callback to send to
*/
private static void sendCallbackMessage(Handler callback, WifiStatus status) {
if (null != callback) {
Message message = callback.obtainMessage();
if (null != message) {
message.obj = status;
callback.sendMessage(message);
}
}
}
/**
* Connects to the given ESSID. Turns on WiFi if necessary.
* Once the operation is complete (whether successful or not),
* it sends a message to the given Handler with the state of the WiFi connection.
*/
public void connectToTargetNetwork() {
// Add timeout override to get out no matter what happens...
timeoutHandler = new Handler();
timeoutHandler.postDelayed(masterCompletionTimeout, timeout);
state = STATE_UNKNOWN;
// Check if we are already connected to target network
if (isConnectedToTargetNetwork()) {
sendCallbackMessage(handler, WifiStatus.ASSOCIATED);
return;
}
registerReceivers();
// Check if WIFI is turned on
// Not enabled, turn it on!
if (!wifi.isWifiEnabled()) {
logInfo(TAG, "Enabling WIFI...");
state = STATE_WIFI_OFF;
boolean success = wifi.setWifiEnabled(true);
if (!success) {
sendCallbackMessage(handler, WifiStatus.WIFI_OFF);
}
// Wait for connection callback
return;
}
// We are connected, check if target SSID is visible
state = STATE_WIFI_ON;
logInfo(TAG, "Starting wifi scan...");
wifi.startScan();
}
public void registerReceivers() {
// Register system WIFI state callbacks
reactContext.getApplicationContext().registerReceiver(wifiStateReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
reactContext.getApplicationContext().registerReceiver(wifiScanResultsReceiver, new IntentFilter(android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
}
/**
* Perform internal cleanup before returning response to caller
*/
public void cleanupConnectToTargetNetwork() {
logInfo(TAG, "cleanupConnectToTargetNetwork");
// Unregister all internal WiFi state receivers
if (reactContext.getApplicationContext() != null) {
// Unregister all our WIFI status receivers
try {
if (null != wifiStateReceiver) {
reactContext.getApplicationContext().unregisterReceiver(wifiStateReceiver);
}
} catch (Exception e) {
logError(TAG, e.getMessage());
}
try {
if (null != wifiScanResultsReceiver) {
reactContext.getApplicationContext().unregisterReceiver(wifiScanResultsReceiver);
}
} catch (Exception e) {
logError(TAG, e.getMessage());
}
}
// Cancel our master timeout
if (timeoutHandler != null) {
try {
timeoutHandler.removeCallbacks(masterCompletionTimeout);
} catch (Exception e) {
logError(TAG, e.getMessage());
}
timeoutHandler = null;
}
try {
state = STATE_UNKNOWN;
// Get the final WiFi status and send it back to the caller
WifiStatus status = getStatus(targetSSID);
logInfo(TAG, "cleanupConnectToTargetNetwork - WiFi status=" + status.getName());
sendCallbackMessage(handler, status);
} catch (Exception e) {
logError(TAG, "Error IN Wifi :: " + e);
}
}
/**
* Provides a slight delay before sending a results message to the caller.
* This method is used when the requested network connection has been made successfully.
* We have seen that when the OS reports the WiFi is ready, it might actually not be for a couple more seconds.
* So we impart a slight delay to cover this.
*/
private void delayBeforeFinish() {
if (timeoutHandler != null) {
timeoutHandler.removeCallbacks(masterCompletionTimeout);
}
if (timeoutHandler == null) {
timeoutHandler = new Handler();
}
timeoutHandler.postDelayed(masterCompletionTimeout, DELAY_AFTER_CONNECTION_TIMEOUT);
}
/**
* Connect to our target SSID.
* A prerequisite to calling this function is that the SSID is visible from a network scan.
*/
private void connectToVisibleNetwork() {
logInfo(TAG, "connectToVisibleNetwork");
// SSID is visible, check if it is configured
state = STATE_SSID_VISIBLE;
if (state == STATE_SSID_ASSOCIATING) {
logError(TAG, "Associating now...");
return;
}
// Check if the target SSID is configured on this device
int networkId = isNetworkConfigured(targetSSID);
logInfo(TAG, "Our network is configured returned:" + networkId);
if (networkId < 0) {
// Network not configured, Add the network
logInfo(TAG, "Adding our network to configuration...");
WifiConfiguration wifiConfig = setWifiConfiguration(targetSSID, WifiConfiguration.KeyMgmt.NONE);
networkId = wifi.addNetwork(wifiConfig);
logInfo(TAG, "addNetwork returned: " + networkId);
if (networkId < 0) {
return;
}
// Network added, save the changes
wifi.saveConfiguration();
}
setWifiConfiguration(targetSSID, WifiConfiguration.KeyMgmt.NONE);
wifi.disconnect();
//wifi.saveConfiguration();
// Network is configured on this device
state = STATE_SSID_CONFIGURED;
// Connect to network
state = STATE_SSID_ASSOCIATING;
boolean success = wifi.enableNetwork(networkId, true);
//c2();
wifi.reconnect();
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// ConnectivityManager.setProcessDefaultNetwork(networkId);
// }
//ConnectivityManager.
logInfo(TAG, "Enable our SSID returned:" + success);
if (success) {
logInfo(TAG, "connectToVisibleNetwork, Success...");
}
//connectToHost2(getReactApplicationContext(), targetSSID, "");
return;
}
@NonNull
private WifiConfiguration setWifiConfiguration(String targetSSID, int none) {
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = formatSSIDWithQuotes(targetSSID);
wc.hiddenSSID = false;
/* wifiConfig.priority = 1;
wifiConfig.allowedKeyManagement.set(none);
wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wifiConfig.allowedKeyManagement.set(none);
wifiConfig.status = WifiConfiguration.Status.ENABLED;*/
wc.status = WifiConfiguration.Status.ENABLED;
wc.priority = 1;
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedAuthAlgorithms.set(0);
wc.status = 2;
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
assignHighestPriority(wc);
//wifi.updateNetwork(wc);
return wc;
}
/**
* Check if our target SSID is visible to the WIFI radio
*
* @return true if visible
*/
public boolean isOurNetworkVisible() {
// Get a list of visible SSID's and iterate through them
List<ScanResult> wifiList = wifi.getScanResults();
for (ScanResult info : wifiList) {
Logger.logWarning(TAG, "Scan found ESSID:" + info.SSID + ", Strength :: " + info.level);
// Check if each one is ours
if (null != targetSSID && targetSSID.equals(info.SSID)) {
return true;
}
}
return false;
}
/* Check the strength of the WiFi
0-3, 3=good
*/
public boolean isInRange() {
// Get a list of visible SSID's and iterate through them
List<ScanResult> wifiList = wifi.getScanResults();
for (ScanResult info : wifiList) {
if (null != targetSSID && targetSSID.equals(info.SSID)) {
int rssi = wifi.getConnectionInfo().getRssi();
int level = wifi.calculateSignalLevel(rssi, 3);
Logger.logWarning(TAG, "Scan found ESSID:" + info.SSID + ", Strength :: " + info.level + " , Calculated Level :: " + level);
return level > 0;
}
}
return false;
}
/**
* Check if we are connected to the target SSID
*
* @return
*/
private boolean isConnectedToTargetNetwork() {
try {
wifi = (android.net.wifi.WifiManager) reactContext.getApplicationContext().getSystemService(WIFI_SERVICE);
if (null == wifi) {
return false;
}
if (!wifi.isWifiEnabled()) {
return false;
}
WifiInfo wifiInfo = wifi.getConnectionInfo();
if (null != targetSSID) {
targetSSID = targetSSID.replaceAll("\"", "");
}
String ssid = wifiInfo.getSSID();
if (null != ssid) {
ssid = ssid.replaceAll("\"", "");
}
return wifiInfo != null && wifiInfo.getSSID() != null && ssid.equals(targetSSID);
} catch (Exception e) {
logError(TAG, "<< isConnectedToTargetNetwork >> " + e);
return false;
}
}
/**
* Check if the given network is configured on this device
*
* @param ssid the SSID to check
* @return the networkId of this SSID or -1 if not found
*/
private int isNetworkConfigured(String ssid) {
logInfo(TAG, "isNetworkConfigured for >" + ssid + "<");
// The SSID's returned by the system have quotes around them
String formattedSSID = formatSSIDWithQuotes(ssid);
try {
// Get the configured networks (SSID's) and iterate though them
List<WifiConfiguration> networksList = wifi.getConfiguredNetworks();
for (WifiConfiguration config : networksList) {
logInfo(TAG, "Config - essid =: " + config.SSID + ", id =" + config.networkId);
// Is this our SSID?
if (formattedSSID.equals(config.SSID)) {
logInfo(TAG, "Network IS configured - essid=:" + config.SSID + ", id=" + config.networkId);
wifi.saveConfiguration();
// Return the internal network id of this SSID
return config.networkId;
}
}
} catch (Exception e) {
logInfo(TAG, "isNetworkConfigured exception - " + e.getMessage());
}
// The given SSID was not found
return -1;
}
private String formatSSIDWithQuotes(String ssid) {
return "\"" + ssid + "\"";
}
public static void displayLocationSettingsRequest(final Context activity) {
final Message message = new Message();
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(activity)
.addApi(LocationServices.API).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
message.arg1 = 1;
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
message.arg1 = 0;
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
// try {
// // Show the dialog by calling startResolutionForResult(),
// // and check the result in onActivityResult().
// //status.startResolutionForResult(activity, 1000);
// } catch (IntentSender.SendIntentException ignored) {}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
message.arg1 = 0;
break;
}
}
});
}
//To tell OS to give preference to this network
private void assignHighestPriority(WifiConfiguration config) {
List<WifiConfiguration> configuredNetworks = wifi.getConfiguredNetworks();
if (configuredNetworks != null) {
for (WifiConfiguration existingConfig : configuredNetworks) {
if (config.priority <= existingConfig.priority) {
config.priority = existingConfig.priority + 1;
}
}
}
}
/////
}
答案 0 :(得分:0)
我找到决定。您必须每隔1秒为不同的站点添加一个流量。