Android isNetworkConnected如何判断APP连接到了无网络热点

在开发移动应用时,处理网络状态是一项基础且关键的任务。尤其是辨别出设备是否连接到了一个实际上没有互联网接入的WiFi热点(比如需要登录或者付费才能上网的公共Wi-Fi),对于保持良好用户体验非常重要。

第一步:基本网络连接检测

我们从最基础的开始——检查设备是否连接到了网络。这个方法适用于所有Android设备,可以通过ConnectivityManager服务来实现。下面是如何进行基本检查的代码示例:

    public static boolean isNetworkConnected(Context context) {if (context == null) {return false;}ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);if (Build.VERSION.SDK_INT < 23) {NetworkInfo networkInfo = cm.getActiveNetworkInfo();//return null != networkInfo && networkInfo.isConnected();if (networkInfo != null) {if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {//WIFIreturn true;} else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {//移动数据return true;}}} else {Network network = cm.getActiveNetwork();if (network != null) {NetworkCapabilities nc = cm.getNetworkCapabilities(network);if (nc != null) {if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {//WIFIreturn true;} else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {//移动数据return true;}}}}return false;}

这段代码帮助我们确认设备至少连接到了某种类型的网络,但它并不能告诉我们这个网络是否真正连通互联网。即使该方法返回true,也并不意味着设备实际上可以访问互联网。比如,在您的场景中,如果手机连接到了一个没有互联网连接的Wi-Fi热点,getActiveNetworkInfo().isConnected()仍然会返回true,因为设备确实成功建立了网络连接,只是这个网络自身没有接入互联网。

因此,如果您需要判断设备是否能够访问互联网(而不仅是连接到了某个网络),那么仅仅依靠isNetworkConnected方法是不够的。
一种简单但有效的方法是尝试发送一个网络请求到一个可靠的外部服务器(例如Google的公共DNS服务器8.8.8.8或者某个稳定的HTTP服务),并检查是否能收到响应:

public boolean isInternetAvailable() {try {InetAddress address = InetAddress.getByName("google.com");return !address.equals("");} catch (UnknownHostException e) {// Log error}return false;
}

这种方法可能会增加应用的网络使用量,并且对于每次检查都会有一定的延迟,所以不应频繁调用。

当遇到“伪联网”热点时的补救方案

要准确地检测设备是否真正能够访问互联网,特别是在网络环境复杂、某些服务可能被限制访问的情况下,我们需要一种更灵活且响应更快的方法。可以采用以下几种策略之一:

1. 使用HTTP HEAD请求检测

相比于下载完整的网页或文件,发送一个HTTP HEAD请求到一个可靠的网站通常更快。HEAD请求只会请求资源的头部信息,并不返回实际的内容,因此响应时间更短。您可以选择一个在目标用户群体中访问速度较快且稳定的网站,例如国内用户可以使用www.baidu.com

public static boolean isInternetAvailable() {try {HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.baidu.com").openConnection());urlc.setRequestProperty("User-Agent", "Android");urlc.setRequestProperty("Connection", "close");urlc.setConnectTimeout(1500); // 设置超时时间urlc.connect();return (urlc.getResponseCode() == 200);} catch (IOException e) {Log.e("Connectivity", "Error checking internet connection", e);}return false;
}

2. 使用ICMP Ping

尽管这种方法在某些设备上可能需要root权限,或者根本不支持,但它是另一种检测网络连通性的方法。您可以尝试ping一个公共服务器(例如阿里云或腾讯云的公共DNS)。

public static boolean isInternetAvailable() {Runtime runtime = Runtime.getRuntime();try {Process ipProcess = runtime.exec("/system/bin/ping -c 1 223.5.5.5"); // 阿里云公共DNSint exitValue = ipProcess.waitFor();return (exitValue == 0);} catch (IOException | InterruptedException e) {e.printStackTrace();}return false;
}

3. 使用DNS解析

直接使用InetAddress.getByName()进行DNS解析可能比直接ping命令更加高效和通用。您可以选择一个稳定的域名进行解析:

public static boolean isInternetAvailable() {try {InetAddress inetAddress = InetAddress.getByName("www.baidu.com");// 如果地址有效,且不是回送地址,则认为有外网连接return !inetAddress.equals("") && !inetAddress.isLoopbackAddress();} catch (UnknownHostException e) {// DNS解析失败}return false;
}
方法速度稳定性
HTTP HEAD请求通常情况下相当快高。通过选择适合目标用户群的网站提高稳定性(如www.baidu.comwww.cloudflare.com)。
ICMP Ping通常较快,但受多因素影响取决于目标服务器可达性。某些网络配置可能导致ping失败。
DNS解析通常非常快高。稳定性依赖于DNS服务的可靠性。建议选择全球性或大型DNS服务。

总结与建议

在考虑网络检测方法时,速度稳定性是两个重要的考量因素。开发者需要基于应用的具体需求和目标用户所在地的网络环境来选择最适合的方案。

  • 对于需要快速反馈且目标用户遍布全球的应用,使用DNS解析可能是最优的选择,尤其是当选择如Google DNS或Cloudflare DNS这样的全球性服务时。然而,在特定地区(例如中国大陆),为了确保最佳的访问速度和稳定性,选择本地DNS服务可能更加合适。
  • 对于主要面向特定地区用户的应用,例如中国大陆,采用HTTP HEAD请求并选择本地流行且稳定的网站(如www.baidu.com)作为检测目标能够提供更好的用户体验。

在实际应用中,还可以根据具体情况组合使用这些方法,以实现更准确和灵活的网络可达性检测。无论选择哪种方法,请确保这些检测操作在异步执行,避免阻塞主线程,从而维持应用的流畅运行。

注意事项

  • 在实际应用中,应该异步执行这些检查操作,避免阻塞主线程并影响用户体验。
  • 网络状态可以随时变化,所以即使当前判断为可访问互联网,也不能保证未来一直如此。因此,在进行重要的网络交互时,最好还是捕获并处理好相关的异常情况。

3. 使用DNS方式的具体实现

如果你的项目中集成了OkHttp,那么可以利用OkHttp进行异步网络请求来检查网络连接。不过,由于OkHttp主要是用于HTTP请求,并且我们这里讨论的是使用DNS解析来检测网络可达性,我们将稍微变通一下,通过尝试发起一个实际的HTTP请求到一个全球性可靠的域名,以此来间接验证DNS解析及网络连通性。

示例代码

下面是如何使用OkHttp库来异步检查网络连接的示例代码:

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;import java.io.IOException;public class NetworkCheckUtil {private static final OkHttpClient client = new OkHttpClient();public interface ConnectionCallback {void onResult(boolean isConnected);}public static void checkInternetConnection(final ConnectionCallback callback) {// 使用HEAD请求减少数据传输Request request = new Request.Builder().url("http://www.google.com").head() // 使用HEAD而非GET来减少响应体大小.build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {// 请求失败,可能是网络问题e.printStackTrace();callback.onResult(false);}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {// HTTP状态码为200-299表示成功响应callback.onResult(true);} else {// 其他情况,如404等,视为无法访问互联网callback.onResult(false);}}});}
}

如何使用

在你的Activity或任何需要检查网络连接的地方,调用checkInternetConnection方法:

NetworkCheckUtil.checkInternetConnection(new NetworkCheckUtil.ConnectionCallback() {@Overridepublic void onResult(boolean isConnected) {if (isConnected) {// 网络连接可用System.out.println("Internet is available");} else {// 网络连接不可用System.out.println("No internet connection");}}
});

注意事项

  • 该方法使用了OkHttp的异步回调机制,避免阻塞主线程。
  • 这里采用http://www.google.com作为测试URL。根据你的用户群体和业务需求,你可能需要选择另一个更适合的URL进行检测。例如,对于在中国大陆的用户,可能需要选择一个在当地访问速度快且稳定的网站。
  • 尽管这种方法通过HTTP请求来检测网络,但实际上也间接利用了DNS解析过程,因为HTTP请求的发起会先触发DNS解析。

用网络连接变化的监听优化判断次数

不再赘述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/829026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OSPF域间路由防环原则

1.域间路由防环原则 ①原则一 1&#xff09;为了避免区域间的环路&#xff0c;OSPF规定不同区域间的路由交互只能通过ABR实现。 2&#xff09;ABR是连接到骨干区域的&#xff0c;所以在区域设计上规定&#xff0c;所有非骨干区域都要连接到骨干区域。区 域间的通讯需要通…

C语言进阶:进阶指针(下)

一、 函数指针数组 我们都知道 数组是一个存放相同类型数据的存储空间 那我们已经学习了指针数组 那么函数有没有对应的指针数组呢&#xff1f; 如果有那应该怎么定义呢&#xff1f; 1. 函数指针数组的定义 我们说 函数指针数组的定义 应该遵循以下格式 int (*p[10])(); 首…

SpringBoot Aop使用篇

Getting Started SpringBoot AOP的实践 AOP相关的概念&#xff1a; Aspect&#xff08;切面&#xff09;&#xff1a; Aspect 声明类似于 Java 中的类声明&#xff0c;在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。就是抽离出来的逻辑类&#xff0c;比如日志、权限…

C++及QT的线程学习

目录 一. 线程学习 二. 学习线程当中&#xff0c;得到的未知。 1. 了解以下MainWindow和main的关系 2. []()匿名函数 有函数体&#xff0c;没有函数名. 3. join和detach都是用来管理线程的生命周期的&#xff0c;它们的区别在于线程结束和资源的回收。 4. operator()() 仿…

4G组网三相四线预付费电表-远程集中抄表

安科瑞薛瑶瑶18701709087/17343930412 DTSY1352 三相预付费电能表分别用于计量额定频率50Hz 的单、三相交流有功电能&#xff0c;具有预付费控制、负载控制、时间控制及 RS485 通信等功能&#xff0c;性能指标符合 GB/T17215.321-2008 标准。是改革传统用电体制&#xff0c…

杰理695的UI模式LED灯控制

UI模式LED灯修改每个模式对应的LED灯闪烁修改在ui_normal_status_deal(u8 *status, u8 *power_status, u8 ui_mg_para)

开源克隆声音的项目-OpenVoice V2

myshell的OpenVoice 出v2版本了 只需要上传一段20秒到5分钟之间的声音&#xff0c;就可以克隆声音。 单人讲话 没有背景噪音 时间在20秒至5分钟之间 本地部署我没有做&#xff0c;我在myshell的官网上测试了一下&#xff0c;可能是上传的音频有杂音&#xff0c;导致不是很清…

人机交互系统文本分类 text classification环节源码(E-commerce)

我把pre-trained model 下载到了本地 效果如下&#xff08;到时候把代码中的sequence 和labels换成自己的text和分类就行了。&#xff09;&#xff1a; 源码见链接&#xff1a; https://download.csdn.net/download/qqqweiweiqq/89211553

2024年好用又便宜的云手机!哪款性价比高?

随着科技的飞速发展&#xff0c;云计算技术也在不断演进&#xff0c;而云手机作为其创新之一&#xff0c;已经开始在我们的生活中崭露头角。它通过将手机的硬件和软件功能移到云端&#xff0c;让用户能够借助强大的云计算资源完成各种任务。2024年&#xff0c;哪款云手机性价比…

Ubuntu关闭防火墙、关闭selinux、关闭swap

关闭防火墙 打开终端&#xff0c;然后输入如下命令&#xff0c;查看防火墙状态&#xff1a; sudo ufw status 开启防火墙命令如下&#xff1a; sudo ufw enable 关闭防火墙命令如下&#xff1a; sudo ufw disable 关闭selinux setenforce 0 && sed -i s/SELINUXe…

QML中使用正则表达式

我想在TextField控件中使用正则表达式&#xff0c;然后GPT4给出的回答是这样的&#xff1a; TextField {id: versionInputplaceholderText: qsTr("输入版本号")validator: RegExpValidator { regExp: /^[a-zA-Z0-9]*$/ } // 仅允许字母和数字width: 120 // 设置合…

SpringBoot中多数据源灵活切换解决方案

本篇内容介绍了“SpringBoot中如何使用Dynamic Datasource配置多数据源”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 源码地址/文档说明 功能特性: 支持 数据源分组…

软件设计师-重点的创建型设计模式

一、简单工厂&#xff1a; 简单工厂模式属于创建型模式&#xff0c;但不属于23种设计模式之一。 软考中图 二、工厂方法&#xff1a; 意图&#xff1a; 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。 结…

YOLOV5 TensorRT部署 BatchedNMS(engine模型推理)(下)

主要是在王新宇代码的基础上改进,引入对BatchedNMS的解码 文章目录 1. 修改yolov5.cpp2.修改yololayer.h1. 修改yolov5.cpp 首先增加全局变量,名字根据转onnx时修改的节点名字来,查看onnx文件可以看到,顺序不要弄错。 const char *INPUT_NAME = “images”; const char …

FFmpeg常用结构体、关键函数、ffplay.c分析

一、常用结构体&#xff1a; 1、AVFormatContext结构体&#xff1a; AVFormatContext是一个贯穿全局的数据结构&#xff0c;很多函数都要用它作为参数。FFmpeg代码中对这个数据结构的注释是format I/O context&#xff0c;此结构包含了一个视频流的格式内容。其中存有AVIputFor…

抖音小店值得做吗?前期需要多少资金的投入?

大家好&#xff0c;我是电商糖果 这两天有位想做店的朋友&#xff0c;问了糖果一个问题。 他说开个体店是不是需要办理个体户营业执照。 我回答是的。 他又问办执照是不是需要花钱。 我说自己去工商局办理是免费的&#xff0c;找人代办市场上的价格一般在二百左右。 对方…

最大层内元素和

题目链接 最大层内元素和 题目描述 注意点 返回层内元素之和 最大 的那几层&#xff08;可能只有一层&#xff09;的层号&#xff0c;并返回其中 最小 的那个树中的节点数在 [1, 10000]范围内-10^5 < Node.val < 10^5 解答思路 广度优先遍历树&#xff0c;使用队列存…

应用内竞价(Bidding)技术为什么一定要结合瀑布流广告分层+混合智能排序技术?

应用内竞价&#xff08;In-App Bidding或Header Bidding&#xff09;即在APP端实现竞价的优势显而易见&#xff0c;接入的所有广告平台按价格实时排序&#xff0c;价高者得&#xff0c;这样使得每次广告请求收益都是最大值&#xff0c;从而实现收益最大化。 竞价机制是买卖双方…

改善员工绩效管理的 8 种最佳方法

企业如何改进绩效管理体系&#xff0c;才能获得最好的结果&#xff1f;请仔细阅读&#xff0c;找出答案… 人力资源部门对组织的成功起着至关重要的作用&#xff0c;组织的员工也是如此。更好的组织管理会带来更高的利润。人力资源部门的工作很大一部分就是规范绩效管理体系&a…

19-Echarts 配置系列之: timeline 动态切换

前言&#xff1a; timeline 动态切换 作用&#xff1a;在同一个图表上展示不同时间段的数据&#xff0c;并实现动态切换的效果。 简介原理&#xff1a;在 timeline 中定义显示节点并与相应的数据结构绑定&#xff0c;然后调用 ECharts 提供的方法&#xff0c;重新渲染图表。 …