8

Sto usando questo pezzo di codice per rilevare le modifiche dello stato della connessione Internet. Funziona bene su Android 5.0 <, ma su API 21 questo:ConnectivityManager.EXTRA_NO_CONNECTIVITY è sempre falso su Android Lollipop

è sempre false. Come far funzionare questo codice su Android 5.0?

mio BroadcastReceiver:

public class NetworkStateReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(final Context context, final Intent intent) { 
     if(intent.getExtras()!=null) { 
      final ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 
      final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 
      if(networkInfo != null && networkInfo.isConnectedOrConnecting()) { 
       Log.d("receiver test", "detected on"); 
      } 
     } 
     Log.d("receiver test", Boolean.toString(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY))); 
     if(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) { 
      Log.d("receiver test", "detected off"); 
     } 
    } 
} 

risposta

18

È possibile utilizzare NetworkRequest aggiunti nel livello di API 21.

creare un'azione intento personalizzato:

public static final String CONNECTIVITY_ACTION_LOLLIPOP = "com.example.CONNECTIVITY_ACTION_LOLLIPOP"; 

Creare il nuovo metodo di registerConnectivityActionLollipop:

@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
private void registerConnectivityActionLollipop() { 

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) 
     return; 

    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkRequest.Builder builder = new NetworkRequest.Builder(); 

    connectivityManager.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback() { 
     @Override 
     public void onAvailable(Network network) { 
      Intent intent = new Intent(CONNECTIVITY_ACTION_LOLLIPOP); 
      intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 

      sendBroadcast(intent); 
     } 

     @Override 
     public void onLost(Network network) { 
      Intent intent = new Intent(CONNECTIVITY_ACTION_LOLLIPOP); 
      intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 

      sendBroadcast(intent); 
     } 
    }); 
} 

Aggiungere la nuova azione intento di filtro intento e chiamano registerConnectivityActionLollipop:

IntentFilter intentFilter = new IntentFilter(); 
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 
intentFilter.addAction(CONNECTIVITY_ACTION_LOLLIPOP); 

registerReceiver(mBroadcastReceiver, intentFilter); 
registerConnectivityActionLollipop(); 

Modificare il BroadcastReceiver per supportare la nuova azione intento:

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION) || 
       Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && TextUtils.equals(intent.getAction(), CONNECTIVITY_ACTION_LOLLIPOP)) { 

      if (intent.getExtras() != null) { 
       final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
       final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 
       if (networkInfo != null && networkInfo.isConnectedOrConnecting()) { 
        Log.d("receiver test", "detected on"); 
       } 
      } 

      Log.d("receiver test", Boolean.toString(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY))); 
      if (intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) { 
       Log.d("receiver test", "detected off"); 
      } 
     } 
    } 
}; 
+1

Grazie. Ho dovuto modificare la tua soluzione un po 'per soddisfare le mie esigenze, ma mi ha dato un'idea eccessiva su come risolvere il problema con Android 5.0 – fragon

+1

@MattiaMaestrini: il tuo codice non è invertito? Non dovrebbe essere 'intent.putExtra (ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);' in 'onAvailable'? – Jim

+2

@Jim Hai ragione. Grazie per averlo indicato, ho appena corretto la risposta. –