5

Una vez que tuve un problema, ustedes fueron realmente útiles. Así que aquí estoy otra vez con otro problema en el que he caído ...:/getBoolean (EXTRA_NO_CONNECTIVITY) siempre devuelve falso

Estoy ejecutando un NetworkReceiver personalizado que amplía BroadcastReceiver. Quiero detectar cuando el teléfono tiene una conexión a Internet para poder comenzar un servicio siempre que lo haga. He leído un montón de temas y todos los temas de más o menos inmediata al siguiente código, que no funciona para mí:

public class NetworkReceiver extends BroadcastReceiver { 

private static final String tag = NetworkReceiver.class.getSimpleName(); 

@Override 
public void onReceive(Context context, Intent intent) { 
    Log.i(tag,"****** NetworkReceiver // onReceive()"); 

    boolean noConnection = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 

    if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 
     Log.i(tag,"****** NetworkReceiver // Network Down?: " + intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)); 
    } 

    // TODO Bug: Never stops the service. Stays always connected! 
    if(noConnection) { 
     Log.i(tag,"****** NetworkReceiver // Stopping Service..."); 
     context.stopService(new Intent(context, FetchService.class)); 
    } else { 
     Log.i(tag,"****** NetworkReceiver // Starting Service!"); 
     context.startService(new Intent(context, FetchService.class)); 
    } 
} 

El problema que tengo es que el Logcat siempre devuelve NetworkDown?: false y el servicio nunca se detiene (se se reinicia todo el tiempo). Lo probé en el emulador presionando F8 y también lo probé en mi teléfono dev (no tiene tarjeta SIM, el acceso a internet está en mi enrutador wifi) apagando el enrutador -> ¡no hay acceso a Internet garantizado!

Mi manifiesto incluye las siguientes líneas:

... 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

<receiver android:name=".NetworkReceiver"> 
    <intent-filter> 
     <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
    </intent-filter> 
</receiver> 
... 

También debo señalar que también he intentado <action android:name="android.net.ConnectivityManager.CONNECTIVITY_ACTION" /> en mi archivo de manifiesto, sin cambio y que cuando alteré la línea: intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false) a intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true) el resultado siempre fue cierto, y por lo tanto, siempre trató de detener mi servicio y nunca iniciarlo.

Sospecho que los extras de la intención no se leen en absoluto y es por eso que el valor predeterminado de getBooleanExtra() siempre regresa.

PS. Estoy en Android 2.1

¡Gracias!

Respuesta

3

No estoy seguro de los Extras que no se pueden leer dentro del BroadcastReceiver, pero puedo mostrarle la forma en que uso el BroadcastReceiver para un propósito similar al suyo.

Mi receptor solo capta los cambios de conectividad, pero NO evalúa el estado de la conectividad. Informa al Service en su lugar como en ambos casos (conectado o no) este servicio tendrá algo que ver. Este servicio se puede ejecutar o no en ese momento, por lo que o bien se inicia o se "informó" (recordemos que you can safely call startService() several times, estas llamadas no anidan):

public class ConnectivityReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     final Intent intentService = new Intent(context, MyService.class); 
     intentService.putExtra(MyService.INTENT_HANDLE_CONNECTIVITY_CHANGE, ""); 

     context.startService(intentService); 
    } 
} 

Entonces, en mi servicio, yo no evalúan la conectividad y luego actuar en consecuencia. Nótese que no evalúan el estado de conexión de la misma manera como lo hace, y esto podría ser el motivo por el código de abajo obras, pero no el suyo (a continuación es sólo el código correspondiente):

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if (intent != null) { 
     final Bundle bundle = intent.getExtras(); 

     // Handle the intent INTENT_HANDLE_CONNECTIVITY_CHANGEif any 
     if ((bundle != null) && (bundle.get(INTENT_HANDLE_CONNECTIVITY_CHANGE) != null)) {   
      handleConnectivity(); 
     } 
    } 

    return START_STICKY; 
} 

private void handleConnectivity() { 
    final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    final NetworkInfo netInfo = cm.getActiveNetworkInfo(); 

    if(netInfo != null && netInfo.isConnected()) { 
     // WE ARE CONNECTED: DO SOMETHING 
    } 
    else { 
     // WE ARE NOT: DO SOMETHING ELSE  
    } 
} 

Esto funciona bien, en virtud de Android-7 (2.1) también.

+0

Conozco el método que ha utilizado. Sin embargo, estaba un poco sorprendido de que mucha gente recomendara el código que he usado (¡también lo leí en un libro de O'Reilly que compré recientemente en Android!) Si no puedo encontrar una solución con la transmisión CONNECTIVITY_ACTION, creo que seguiré su ejemplo y verificará en mi Servicio los métodos de ConnectivityManager. Gracias por la respuesta :) – snoopaki

+0

Eres bienvenido @snoopaki - en realidad hubiera preferido una solución usando tu método, pero simplemente no veo qué está pasando y por qué. – Shlublu

+1

En realidad, cambié mi servicio a un servicio de intención y el manejo en el servicio del cambio de conectividad tenía más sentido. ¡¡Así que debería elegir tu respuesta como la correcta !! THX :) – snoopaki

2

no sabemos acerca de la bandera NO_CONNECTIVITY extraño, pero se puede recuperar la red activa de la intención:

(NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 

probablemente puede llamar isConnected() en este objeto.

+1

Gracias por la respuesta, lo tendré en cuenta. Para la tarea actual, utilicé la respuesta anterior y funciona bastante bien atm :) – snoopaki

+1

Esta constante está en desuso en este momento. –

Cuestiones relacionadas