zona usar una tengo redes que puedo portatil porque moviles movil los instalar gris datos conectarse conectar conecta como celular ala abierta android networking android-wifi mobile-data android-connectivitymanager

usar - porque no me puedo conectar a una red wifi abierta android



¿Cómo manejar el cambio de red entre wifi y datos móviles? (4)

La respuesta que estás buscando es un BroadcastReceiver . Revisa el enlace de abajo.

BroadcastReceiver cuando el estado de la red wifi o 3g cambió

Espero que le ayude a resolver su problema y, de ser así, considere cerrar su pregunta.

Estoy creando una aplicación VoIP. Durante una llamada VoIP, cuando el usuario cambia de WiFi a datos móviles, tengo un problema al manejar el escenario.

En la actividad de mi pantalla de llamada, me he registrado en Receiver, que me ayuda a recibir notificaciones sobre los escenarios de cambio de red.

Este es el código que estoy usando para detectar cambios en las redes en el Método onRecieve. conn_name es una variable de nivel de clase privada que contiene el nombre de conexión anterior.

ConnectivityManager connectivity_mgr = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)); NetworkInfo net_info = connectivity_mgr.getActiveNetworkInfo(); if (net_info != null && net_info.isConnectedOrConnecting() && !conn_name.equalsIgnoreCase("")) { new_con = net_info.getExtraInfo(); if (new_con != null && !new_con.equalsIgnoreCase(conn_name)) network_changed = true; conn_name = (new_con == null) ? "" : new_con; connectionStatus ="connected"; } else { if (net_info != null && conn_name.equalsIgnoreCase("")){ conn_name = net_info.getExtraInfo(); connectionStatus ="connected"; network_changed = true; }else if(!new_con.equals(conn_name)) { conn_name = ""; connectionStatus ="disconnected"; network_changed = true; } }

Así que usando el método anterior puedo detectar cambios en la red. Pero una cosa peculiar sucede cuando estoy conectado con WiFi. Cuando mi aplicación se inicia inicialmente, está conectada con datos móviles. Cuando el usuario ingresa a su área de WiFi conocida, se conecta a su WiFi conocida. Dado que WiFi siempre se elige como ruta predeterminada, Android cambia a WiFi y recibo la notificación de red de que WiFi se ha activado.

Así que actualizo la dirección IP de mis aplicaciones a la dirección IP de WiFi, así que no hay problemas aquí. Pero aún así, los datos móviles aún están conectados al mismo tiempo, pero getActiveNetworkInfo () me dice que estoy conectado con WiFi claramente, incluso si antes estaba conectado a datos móviles.

Entonces, el problema es cuando el usuario apaga el botón de WiFi, y los datos móviles aún están conectados, pero aún recibo la notificación de que se apaga WiFi. Me indica que la red está desconectada incluso cuando mi teléfono todavía está conectado a datos móviles.

Pero después de un segundo recibo una notificación de que los datos móviles están conectados. Pero una vez que recibo la red desconectada, he cerrado mi llamada VoIP. Entonces, cuando recibo una notificación de WiFi desactivada, ¿cómo puedo asegurarme de que los datos móviles aún estén conectados?

Intenté getActiveNetworkInfo () pero resulta que es nulo cuando recibo la notificación de WiFi desactivada.

He seguido estos enlaces:

Llamada a la API de Android para determinar la configuración del usuario "Datos habilitados"
¿Cómo saber si ''Datos de red móvil'' está habilitado o deshabilitado (incluso cuando está conectado por WiFi)?

Al usar el enlace anterior, puedo detectar que el botón de datos móviles se ha habilitado cuando el usuario se ha conectado con mobiledata.it me da la verdad. Pero el problema ocurre cuando ocurre este caso particular.

Ahora, cuando wifi está deshabilitado, recibo una notificación, pero muestra que los datos móviles están deshabilitados incluso cuando mis datos móviles están habilitados. No puedo manejar esta situación ya que desconecto mis llamadas cuando recibo mi notificación de desconexión.


Mi implementación con RxJava

class ConnectivityMonitor : ConnectivityManager.NetworkCallback() { var networkTimeout: Disposable? = null override fun onAvailable(network: Network?) { super.onAvailable(network) Timber.d("Network available") networkTimeout?.dispose() } override fun onLosing(network: Network?, maxMsToLive: Int) { super.onLosing(network, maxMsToLive) Timber.d("onLosing") } override fun onLost(network: Network?) { super.onLost(network) Timber.d("onLost") networkTimeout = Single.timer(5, TimeUnit.SECONDS) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { _ -> Timber.d("Network lost") } } override fun onUnavailable() { super.onUnavailable() Timber.d("Network unavailable") } }

Configuración del oyente:

private fun setupListeners() { // connection listener val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { connectivityManager.registerDefaultNetworkCallback(connectivityMonitor) } else { val builder = NetworkRequest.Builder() connectivityManager.registerNetworkCallback(builder.build(), connectivityMonitor) } }

El uso del temporizador / desechable permite retrasos entre los tipos de conexión de conmutación.


Puede usar BroadcastReceiver y registrar NETWORK_STATE_CHANGED_ACTION & WIFI_STATE_CHANGED_ACTION .

private boolean isConnected; final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent == null || intent.getAction() == null) return; switch (intent.getAction()){ case WifiManager.NETWORK_STATE_CHANGED_ACTION : case WifiManager.WIFI_STATE_CHANGED_ACTION : if (!isConnected && isOnline(BaseActivity.this)) { isConnected = true; // do stuff when connected Log.i("Network status: ","Connected"); }else{ isConnected = isOnline(BaseActivity.this); Log.i("Network status: ","Disconnected"); } break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { isConnected = isOnline(this); final IntentFilter filters = new IntentFilter(); filters.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filters.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); registerReceiver(broadcastReceiver, filters); } public static boolean isOnline(Context ctx) { ConnectivityManager cm = (ConnectivityManager) ctx .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm != null ? cm.getActiveNetworkInfo() : null; return netInfo != null && netInfo.isConnectedOrConnecting(); }

Actualizar No olvide anular el registroReceptor BroadcastReceiver onDestroy

@Override protected void onDestroy() { unregisterReceiver(broadcastReceiver); super.onDestroy(); }


Puede utilizar las API de ConnectivityManager : especialmente en su caso de uso, está interesado en registerDefaultNetworkCallback() :

public class TestActivity extends AppCompatActivity { private ConnectivityManager manager; private final ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { super.onAvailable(network); // this ternary operation is not quite true, because non-metered doesn''t yet mean, that it''s wifi // nevertheless, for simplicity let''s assume that''s true Log.i("vvv", "connected to " + (manager.isActiveNetworkMetered() ? "LTE" : "WIFI")); } @Override public void onLost(Network network) { super.onLost(network); Log.i("vvv", "losing active connection"); } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); manager.registerDefaultNetworkCallback(networkCallback); } @Override protected void onDestroy() { super.onDestroy(); manager.unregisterNetworkCallback(networkCallback); } }

Mi dispositivo se conecta a LTE en aproximadamente medio segundo.

Esto significa que no puede saber de antemano si el dispositivo se conectará a LTE o no en el momento en que se desconecte el WIFI. Por lo tanto, puede adoptar el siguiente enfoque: publicar una acción en un controlador para que ocurra en un segundo y, dentro de esta acción, cancelar la llamada. Si la conexión aparece en un futuro cercano, anule la acción previamente publicada. Si terminas en el código de Runnable , la conexión no se estableció rápidamente, lo que significa que debes terminar la llamada.

public class TestActivity extends AppCompatActivity { private ConnectivityManager manager; private final Handler handler = new Handler(); private final ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { super.onAvailable(network); Log.i("vvv", "connected to " + (manager.isActiveNetworkMetered() ? "LTE" : "WIFI")); // we''ve got a connection, remove callbacks (if we have posted any) handler.removeCallbacks(endCall); } @Override public void onLost(Network network) { super.onLost(network); Log.i("vvv", "losing active connection"); // Schedule an event to take place in a second handler.postDelayed(endCall, 1000); } }; private final Runnable endCall = new Runnable() { @Override public void run() { // if execution has reached here - feel free to cancel the call // because no connection was established in a second } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); manager.registerDefaultNetworkCallback(networkCallback); } @Override protected void onDestroy() { super.onDestroy(); manager.unregisterNetworkCallback(networkCallback); handler.removeCallbacks(endCall); } }

La desventaja de este enfoque es que registerDefaultNetworkCallback() está disponible a partir de la API 24. Tampoco existe una alternativa en ConnectivityManagerCompat . En su lugar, puede usar registerNetworkCallback() que está disponible en API 21.