porque - wifi sin acceso a internet android
Forzar a Android a usar la red wifi sin internet (5)
¿Podría intentar establecer la configuración global captive_portal_detection_enabled en 0 (falso)?
Lo que realmente está sucediendo es que, de forma predeterminada, cada vez que se conecta a una wifi, el FW probará contra un servidor (normalmente google) para ver si es una wifi cautiva (se necesita iniciar sesión). Así que si tu wifi no está conectado a google, esta comprobación fallará. Después de eso, el dispositivo sabe que el wifi no tiene conexión a internet y simplemente no se conectará automáticamente.
Al establecer esta configuración en 0, se evitará esta comprobación.
Programáticamente: Settings.Global.putInt(getContentResolver(), Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 0);
Edición: es posible que necesite usar la cadena "captive_portal_detection_enabled" directamente, en lugar de la constante que no es visible según la versión de Android.
Estoy creando una aplicación de Android que necesita comunicarse a través de una red WiFi que no tendrá acceso a Internet. El problema es que incluso cuando el WiFi está conectado, Android elige utilizar datos móviles / celulares cuando no hay conexión a Internet en la red wifi.
He leído muchas publicaciones sobre el tema, muchas de las cuales involucran el enraizamiento del dispositivo, pero eso no es posible con una aplicación de producción (los dispositivos de enraizamiento no son una opción). otra solución (como mi código de abajo) sugiere usar bindProcessToNetwork()
que funciona perfectamente en mi Sony Z2 pero no en otros dispositivos que he probado (todos ejecutados en 6.0.1)
private void bindToNetwork() {
final ConnectivityManager connectivityManager = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new NetworkRequest.Builder();
//set the transport type do WIFI
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
connectivityManager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(null);
if (barCodeData.getSsid().contains("screenspace")) {
connectivityManager.bindProcessToNetwork(network);
}
} else {
//This method was deprecated in API level 23
ConnectivityManager.setProcessDefaultNetwork(null);
if (barCodeData.getSsid().contains("screenspace")) {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}
connectivityManager.unregisterNetworkCallback(this);
}
});
}
}
Estás en el camino correcto, la solución es de hecho con ConnectivityManager.bindProcessToNetwork(network) . Esta información se publicó en el Blog de desarrolladores de Android en este artículo: Conexión de su aplicación a un dispositivo Wi-Fi .
Buscando en su código, este barCodeData.getSsid()
no parece tener el SSID de la red wifi conectada actualmente. Si ese es el caso, su código nunca se enlazará con éxito a la red.
Intenta reemplazar tu declaración if
if (barCodeData.getSsid().contains("screenspace"))
Con
if (getNetworkSsid(context).equals("screenspace"))
Método auxiliar en kotlin para recuperar el SSID de la red wifi conectada
private fun getNetworkSsid(context: Context?): String {
// WiFiManager must use application context (not activity context) otherwise a memory leak can occur
val mWifiManager = context?.applicationContext?.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiInfo: WifiInfo? = mWifiManager.connectionInfo
if (wifiInfo?.supplicantState == SupplicantState.COMPLETED) {
return wifiInfo.ssid.removeSurrounding("/"")
}
return ""
}
Si aún no funciona, siga mi solución completa, donde utilicé el mismo método pero con algunas comprobaciones adicionales. Lo probé en las versiones de Android 5.1.1, 6.0, 6.0.1, 7.1.1 y 8.1.0.
Puede verificar si el wifi está conectado y luego mostrar un diálogo al usuario pidiéndole que se conecte a una red wifi
Dado que el método NetworkInfo.isConnected () ahora está en desuso en API-23, aquí hay un método que detecta si el adaptador de Wi-Fi está encendido y también está conectado a un punto de acceso usando WifiManager en su lugar:
private boolean checkWifiOnAndConnected() {
WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (wifiMgr.isWifiEnabled()) { // Wi-Fi adapter is ON
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
if( wifiInfo.getNetworkId() == -1 ){
return false; // Not connected to an access point
}
return true; // Connected to an access point
}
else {
return false; // Wi-Fi adapter is OFF
}
}
Solución en Kotlin
class ConnectWithoutInternetTest constructor(
private val mContext: Context,
private val connectivityManager: ConnectivityManager,
private val wifiManager: WifiManager
) {
private val mWifiBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
WifiManager.NETWORK_STATE_CHANGED_ACTION -> {
val info = intent.getParcelableExtra<NetworkInfo>(WifiManager.EXTRA_NETWORK_INFO)
val isConnected = info.isConnected
val ssid: String? = normalizeAndroidWifiSsid(wifiManager.connectionInfo?.ssid)
if (isConnected) {
val builder = NetworkRequest.Builder()
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
connectivityManager.registerNetworkCallback(
builder.build(),
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
val networkInfo = connectivityManager.getNetworkInfo(network)
val networkSsid = networkInfo.extraInfo
if (networkSsid == ssid) {
connectivityManager.unregisterNetworkCallback(this)
}
}
})
}
}
}
}
}
private fun init() {
val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
mContext.registerReceiver(mWifiBroadcastReceiver, intentFilter)
}
private fun destroy() {
mContext.unregisterReceiver(mWifiBroadcastReceiver)
}
private fun normalizeAndroidWifiSsid(ssid: String?): String? {
return ssid?.replace("/"", "") ?: ssid
}
fun connectToWifi(ssidParam: String, password: String?) {
init()
val ssid = "/"$ssidParam/""
val config = wifiManager.configuredNetworks.find { it.SSID == ssid }
val netId = if (config != null) {
config.networkId
} else {
val wifiConfig = WifiConfiguration()
wifiConfig.SSID = ssid
password?.let { wifiConfig.preSharedKey = "/"$password/"" }
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
wifiManager.addNetwork(wifiConfig)
}
wifiManager.disconnect()
val successful = wifiManager.enableNetwork(netId, true)
}
tendría que deshabilitar los datos móviles en la Configuración (no está seguro, si esto se puede hacer mediante programación, lo que podría ser una opción posible), o eliminar la USIM;
de lo contrario, el comportamiento común es que siempre recurrirá a la mejor conexión disponible (aunque es preferible una conexión con una puerta de enlace de Internet, ya que es utilizada por la mayoría de las aplicaciones).
También vea esta answer .