Estoy viendo que mi hilo de llamada cuelga en código nativo al llamar a WifiManager.enableNetwork(). Hasta ahora, solo he podido reproducir este truco en la tableta Motorola Xoom con Android 3.2.1. He probado en muchos otros teléfonos y tabletas (todos funcionan con Froyo o Gingerbread) y no he visto el problema. El Xoom es el único dispositivo dual-core que tengo que probar (y he reproducido el problema en 2 Xooms diferentes), así que me siento como si estuviera tropezando con algunos requisitos de subprocesamiento de Android muy sutiles cuando se conecta con WifiManager. El seguimiento de la pila donde mi hilo llamando cuelga es:Thread cuelgue en la red de WifiManager.enableNetwork()
BinderProxy.transact(int, Parcel, Parcel, int) line: not available [native method]
IWifiManager$Stub$Proxy.enableNetwork(int, boolean) line: 513
WifiManager.enableNetwork(int, boolean) line: 587
Mi aplicación está intentando conectarse a un punto de acceso wifi conocido, realizar algunas pruebas, a continuación, volver a conectar el dispositivo a su punto de acceso original (si estaba previamente conectado). Antes de establecer la conexión, ya hemos verificado que wifi está habilitado y hemos realizado una exploración para verificar que se encuentre nuestro SSID del punto de acceso. Este código para establecer la conexión se está ejecutando en un AsyncTask y se ve algo como esto:
...
private WifiManager mWifiManager;
private List<WifiConfiguration> mConfiguredNets = new ArrayList<WifiConfiguration>();
private Object mConnectMonitor = new Object();
private NetworkInfo.State mNetworkState = State.UNKNOWN;
private final BroadcastReceiver mConnectionStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context inContext, final Intent inIntent) {
final String action = inIntent.getAction();
if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
NetworkInfo ni =
(NetworkInfo)inIntent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
State state = ni.getState();
if (state == State.CONNECTED) {
synchronized (mConnectMonitor) {
mNetworkState = state;
mConnectMonitor.notify();
}
}
}
}
};
public void runninInAsyncTask(Context activityContext, int networkID) {
mWifiManager = (WifiManager)activityContext.getSystemService(Context.WIFI_SERVICE);
// Register our broadcast receiver to get network state change events
IntentFilter ifilter = new IntentFilter();
ifilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
activityContext.registerReceiver(mConnectionStateReceiver, ifilter);
// Get a list of our currently configured networks so we can re-enable
// them after connecting to the desired network
mConfiguredNets = mWifiManager.getConfiguredNetworks();
// Enable our network and disable all others
mWifiManager.enableNetwork(networkId, true);
// Start the reconnection process to connect to our desired network
synchronized (mConnectMonitor) {
mWifiManager.reconnect();
mConnectMonitor.wait(60000);
if (mNetworkState != State.CONNECTED) {
Log.e(TAG, "Problems connecting to desired network!");
}
else {
Log.e(TAG, "Successfully connected to desired network!");
}
}
// Re-enable all of our previously configured networks
for (WifiConfiguration wifiConfig : mConfiguredNets)
{
if (wifiConfig.status != Status.ENABLED) {
mWifiManager.enableNetwork(wifiConfig.networkId, false);
}
}
}
...
Este código se basa en el código de menú de configuración WiFi en el código de fuente abierta Android Gingerbread. ¿Hay algo acerca de llamar a WifiManager.enableNetwork() que me falta? ¿Tiene que ejecutarse en un hilo en particular? He intentado garantizar que enableNetwork() se invoque en la secuencia de la interfaz de usuario (trasladando la lógica al receptor de difusión). Esto pareció ayudar un poco, pero aún así pude reproducir el truco. Tal vez esto es algo específico de Honeycomb? En este momento, estos 2 Xooms son los únicos dispositivos Honeycomb que tengo disponibles para probar, por lo que son los únicos puntos de datos que tengo.
G
¿Alguna suerte en eso? Tengo el mismo problema. Acabo de encontrar información que quizás connectNetwork debería usarse en su lugar, pero aún no hay AIDL oficial para eso, así que tendrías que hackearla :( – pprzemek
Sí, tenía que hacer exactamente eso. Utilicé la reflexión para acceder al "oculto" "API (solo para Honeycomb y posterior) y nunca he tenido un problema desde. –
He planteado [informe de error] (http://code.google.com/p/android/issues/detail?id=34070). –