EDIT: Quindi, ulteriori ricerche per chi fosse interessato, sembra essere una caratteristica aggiunta in versioni Samsung TouchWiz sulla base di 4.3. Internamente, l'impostazione è denominata "wifi_watchdog_connectivity_check". Uso ancora il codice qui sotto per vedere se sono in grado di verificare sicuro indipendentemente dal fatto che l'impostazione sia abilitata, ma altrimenti dovrei presumere che sia attiva.
Quindi, quello che ho scoperto è che, dopo aver tentato di stabilire una connessione e il sistema operativo si allontana dalla rete, la configurazione Wi-Fi è nello stato "disabilitato". Quindi, dopo che si è verificato il problema, è possibile rilevare con certezza che è successo controllando lo stato della configurazione da WifiManager
.
WifiManager m = (WifiManger) getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> networks = m.getConfiguredNetworks();
String mySsid = "My Network";
mySsid = "\"" + mySsid + "\"";
boolean isDisabled = false;
for (WifiConfiguration config : networks) {
if (mySsid.equals(config.SSID)) {
if (config.status = WifiConfiguration.Status.DISABLED) {
isDisabled = true;
break;
}
}
}
//If isDisabled is true, the network was disabled by the OS
Si può quindi provare a risolvere il nome dell'impostazione dall'applicazione delle impostazioni di sistema:
/** Gets the resources of another installed application */
private static Resources getExternalResources(Context ctx, String namespace) {
PackageManager pm = ctx.getPackageManager();
try {
return (pm == null) ? null : pm.getResourcesForApplication(namespace);
} catch (PackageManager.NameNotFoundException ex) {
return null;
}
}
/** Gets a resource ID from another installed application */
private static int getExternalIdentifier(Context ctx, String namespace,
String key, String type) {
Resources res = getExternalResources(ctx, namespace);
return (res == null) ? 0 : res.getIdentifier(key, type, namespace);
}
/** Gets a String resource from another installed application */
public static String getExternalString(Context ctx, String namespace,
String key, String defVal) {
int resId = getExternalIdentifier(ctx, namespace, key, "string");
if (resId != 0) {
Resources res = getExternalResources(ctx, namespace);
return res.getString(resId);
} else {
return defVal;
}
}
quindi utilizzarlo per ottenere la stringa:
String autoNetworkSwitch = getExternalString(this, "com.android.settings",
"wifi_watchdog_connectivity_check", "Unknown");
Ciò restituirà un stringa localizzata per la lingua dell'utente corrente, se la stringa esiste.
Per chiunque sia interessato ai risultati di questo, si scopre che questa opzione è in realtà un ambiente Android magazzino, ma sembra essere più aggressivo su questi dispositivi Samsung. L'impostazione è nascosta trovata in android.provider.Settings.java
:
/**
* Setting to turn off poor network avoidance on Wi-Fi. Feature is enabled by default and
* the setting needs to be set to 0 to disable it.
* @hide
*/
public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
"wifi_watchdog_poor_network_test_enabled";
che è in Settings$Secure
per API == 15 || API == 16
, o Settings$Global
per API >= 17
. Questa non è un'impostazione che può essere abilitata o disabilitata da applicazioni di terze parti; tuttavia, è possibile rilevare e metterlo in guardia.La mia soluzione è questa:
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
/**
* Checks whether the "Avoid poor networks" setting (named "Auto network switch" on
* some Samsung devices) is enabled, which can in some instances interfere with Wi-Fi.
*
* @return true if the "Avoid poor networks" or "Auto network switch" setting is enabled
*/
public static boolean isPoorNetworkAvoidanceEnabled (Context ctx) {
final int SETTING_UNKNOWN = -1;
final int SETTING_ENABLED = 1;
final String AVOID_POOR = "wifi_watchdog_poor_network_test_enabled";
final String WATCHDOG_CLASS = "android.net.wifi.WifiWatchdogStateMachine";
final String DEFAULT_ENABLED = "DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED";
final ContentResolver cr = ctx.getContentResolver();
int result;
if (SDK_INT >= JELLY_BEAN_MR1) {
//Setting was moved from Secure to Global as of JB MR1
result = Settings.Global.getInt(cr, AVOID_POOR, SETTING_UNKNOWN);
} else if (SDK_INT >= ICE_CREAM_SANDWICH_MR1) {
result = Settings.Secure.getInt(cr, AVOID_POOR, SETTING_UNKNOWN);
} else {
//Poor network avoidance not introduced until ICS MR1
//See android.provider.Settings.java
return false;
}
//Exit here if the setting value is known
if (result != SETTING_UNKNOWN) {
return (result == SETTING_ENABLED);
}
//Setting does not exist in database, so it has never been changed.
//It will be initialized to the default value.
if (SDK_INT >= JELLY_BEAN_MR1) {
//As of JB MR1, a constant was added to WifiWatchdogStateMachine to determine
//the default behavior of the Avoid Poor Networks setting.
try {
//In the case of any failures here, take the safe route and assume the
//setting is disabled to avoid disrupting the user with false information
Class wifiWatchdog = Class.forName(WATCHDOG_CLASS);
Field defValue = wifiWatchdog.getField(DEFAULT_ENABLED);
if (!defValue.isAccessible()) defValue.setAccessible(true);
return defValue.getBoolean(null);
} catch (IllegalAccessException ex) {
return false;
} catch (NoSuchFieldException ex) {
return false;
} catch (ClassNotFoundException ex) {
return false;
} catch (IllegalArgumentException ex) {
return false;
}
} else {
//Prior to JB MR1, the default for the Avoid Poor Networks setting was
//to enable it unless explicitly disabled
return true;
}
}
Per buona misura, quindi è possibile indirizzare gli utenti alle Impostazioni Wi-Fi avanzate mediante Intent
:
/**
* Ensure that an Activity is available to receive the given Intent
*/
public static boolean activityExists (Context ctx, Intent intent) {
final PackageManager mgr = ctx.getPackageManager();
final ResolveInfo info = mgr.resolveActivity(i, PackageManager.MATCH_DEFAULT_ONLY);
return (info != null);
}
public static void showAdvancedWifiIfAvailable (Context ctx) {
final Intent i = new Intent(Settings.ACTION_WIFI_IP_SETTINGS);
if (activityExists(ctx, i)) {
ctx.startActivity(i);
}
}
curiosità interessante: Questo Intent
porta in primo piano la stessa Activity
come andare in Impostazioni> Wi-Fi> Avanzate, ma lo mostrerà con un titolo diverso (Impostazioni IP, vs Wi-Fi avanzato).
Potresti avere più fortuna con i forum Samsung, se non li hai già provati: http://developer.samsung.com/forum/en – CommonsWare
Lo faremo, grazie per il link. :) – kcoppock