android - problemas - mi celular reconoce el wifi pero no se conecta
¿Cómo detectar cuándo se ha establecido la conexión WIFI en Android? (11)
Necesito detectar cuando tengo conectividad de red a través de WIFI. Qué transmisión se envía para establecer que se ha realizado una conexión de red válida. Necesito validar que existe una conexión de red válida para HTTP. ¿Qué debo escuchar y qué pruebas adicionales debo hacer para saber que existe una conexión válida?
Aquí hay un ejemplo de mi código, que tiene en cuenta la preferencia de los usuarios de solo permitir las comunicaciones cuando están conectadas a Wifi.
Estoy llamando a este código desde dentro de un servicio de IntentService
antes de intentar descargar cosas.
Tenga en cuenta que NetworkInfo
será null
si no hay conexión de red de ningún tipo.
private boolean canConnect()
{
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
boolean canConnect = false;
boolean wifiOnly = SharedPreferencesUtils.wifiOnly();
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null)
{
if(networkInfo.isConnected())
{
if((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) ||
(networkInfo.getType() != ConnectivityManager.TYPE_WIFI && !wifiOnly))
{
canConnect = true;
}
}
}
return canConnect;
}
Este código no requiere permiso en absoluto. Está restringido solo a los cambios de estado de conectividad de la red Wi-Fi (no se tiene en cuenta ninguna otra red). El receptor está publicado estáticamente en el archivo AndroidManifest.xml y no necesita ser exportado ya que será invocado por la protected broadcast
por el sistema, WifiManager.NETWORK_STATE_CHANGED_ACTION , en cada cambio de estado de conectividad de red.
AndroidManifest:
<receiver
android:name=".WifiReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<!--protected-broadcast: Special broadcast that only the system can send-->
<!--Corresponds to: android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION-->
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
Clase BroadcastReceiver:
public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
/*
Tested (I didn''t test with the WPS "Wi-Fi Protected Setup" standard):
In API15 (ICE_CREAM_SANDWICH) this method is called when the new Wi-Fi network state is:
DISCONNECTED, OBTAINING_IPADDR, CONNECTED or SCANNING
In API19 (KITKAT) this method is called when the new Wi-Fi network state is:
DISCONNECTED (twice), OBTAINING_IPADDR, VERIFYING_POOR_LINK, CAPTIVE_PORTAL_CHECK
or CONNECTED
(Those states can be obtained as NetworkInfo.DetailedState objects by calling
the NetworkInfo object method: "networkInfo.getDetailedState()")
*/
/*
* NetworkInfo object associated with the Wi-Fi network.
* It won''t be null when "android.net.wifi.STATE_CHANGE" action intent arrives.
*/
NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.isConnected()) {
// TODO: Place the work here, like retrieving the access point''s SSID
/*
* WifiInfo object giving information about the access point we are connected to.
* It shouldn''t be null when the new Wi-Fi network state is CONNECTED, but it got
* null sometimes when connecting to a "virtualized Wi-Fi router" in API15.
*/
WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
String ssid = wifiInfo.getSSID();
}
}
}
Permisos:
None
La respuesta dada por el usuario @JPM y @usman son realmente muy útiles. Funciona bien, pero en mi caso viene en onReceive
varias veces en mi caso 4 veces para que mi código se ejecute varias veces.
Hago algunas modificaciones y hago según mi requisito y ahora viene solo 1 vez
Aquí está la clase Java para Broadcast.
public class WifiReceiver extends BroadcastReceiver {
String TAG = getClass().getSimpleName();
private Context mContext;
@Override
public void onReceive(Context context, Intent intent) {
mContext = context;
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI &&
networkInfo.isConnected()) {
// Wifi is connected
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();
Log.e(TAG, " -- Wifi connected --- " + " SSID " + ssid );
}
}
else if (intent.getAction().equalsIgnoreCase(WifiManager.WIFI_STATE_CHANGED_ACTION))
{
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
if (wifiState == WifiManager.WIFI_STATE_DISABLED)
{
Log.e(TAG, " ----- Wifi Disconnected ----- ");
}
}
}
}
En AndroidManifest
<receiver android:name=".util.WifiReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Lo mejor que funcionó para mí:
AndroidManifest
<receiver android:name="com.AEDesign.communication.WifiReceiver" >
<intent-filter android:priority="100">
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
Clase BroadcastReceiver
public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if(info != null && info.isConnected()) {
// Do your work.
// e.g. To check the Network Name or other info:
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();
}
}
}
Permisos
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Para detectar el estado de conexión WIFI, he usado CONNECTIVITY_ACTION de la clase ConnectivityManager de modo que:
IntentFilter filter=new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(receiver, filter);
y de su BroadCastReceiver:
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
int networkType = intent.getIntExtra(
android.net.ConnectivityManager.EXTRA_NETWORK_TYPE, -1);
if (ConnectivityManager.TYPE_WIFI == networkType) {
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (networkInfo != null) {
if (networkInfo.isConnected()) {
// TODO: wifi is connected
} else {
// TODO: wifi is not connected
}
}
}
}
ps: funciona bien para mí :)
Para mí solo funciona WifiManager.NETWORK_STATE_CHANGED_ACTION
.
Registre un receptor de difusión:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
y recibir:
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
boolean connected = info.isConnected();
//call your method
}
}
Para todos aquellos que disfrutan de la transmisión CONECTIVIDAD_CHANGE , tenga en cuenta que esto no se dispara más cuando la aplicación está en segundo plano en Android O.
https://developer.android.com/about/versions/o/background.html
Puede iniciar una conexión wifi si le da al usuario la opción de anular el comportamiento normal de preguntar cada vez.
Elijo usar tres métodos ...
public boolean isOnline()
{
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
Esto es una comprobación rápida si hay una conexión a Internet ya sea Wifi o CellData. Desde aquí puede elegir qué acción desea realizar. Está en modo avión también necesita ser revisado.
En un hilo separado. Establecí una variable IpAddress a = "" Y sondeé hasta que tenga una dirección IP válida.
WifiManager wifi;
wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifi.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = null;
ip = String.format("%d.%d.%d.%d",
(ipAddress & 0xff),
(ipAddress >> 8 & 0xff),
(ipAddress >> 16 & 0xff),
(ipAddress >> 24 & 0xff));
Log.e(" >>IP number Begin ",ip);
Otro fragmento de código ... Si no está encendido, actívelo (con permiso previo de los usuarios)
if(wifi.isWifiEnabled()!=true)wifi.setWifiEnabled(true);
Usé este código:
public class MainActivity extends Activity
{
.
.
.
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
.
.
.
}
@Override
protected void onResume()
{
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
}
@Override
protected void onPause()
{
super.onPause();
unregisterReceiver(broadcastReceiver);
}
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
final String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION))
{
if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false))
{
// wifi is enabled
}
else
{
// wifi is disabled
}
}
}
};
}
Tengo dos métodos para detectar la conexión WIFI que recibe el contexto de la aplicación:
1) mi viejo método
public boolean isConnectedWifi1(Context context) {
try {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
NetworkInfo[] netInfo = connectivityManager.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI"))
&& ni.isConnected()) {
return true;
}
}
}
return false;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return false;
}
2) mi nuevo método (actualmente estoy usando este método):
public boolean isConnectedWifi(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return networkInfo.isConnected();
}
Puede registrar un BroadcastReceiver
para recibir una notificación cuando se establece una conexión WiFi (o si la conexión ha cambiado).
Registre el BroadcastReceiver
:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
Y luego en su BroadcastReceiver
haga algo como esto:
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)){
//do stuff
} else {
// wifi connection was lost
}
}
}
Para obtener más información, consulte la documentación de BroadcastReceiver
y WifiManager
Por supuesto, debe verificar si el dispositivo ya está conectado a WiFi antes de esto.
EDITAR: Gracias a la ban-geoingeniería, aquí hay un método para verificar si el dispositivo ya está conectado:
private boolean isConnectedViaWifi() {
ConnectivityManager connectivityManager = (ConnectivityManager) appObj.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return mWifi.isConnected();
}