You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用持续检测可用互联网连接方案求助

兄弟,我太懂你这种找了一整天方案却全踩坑的崩溃感——要么是API被Android弃用,要么是只能检测有没有连接不能判断能不能真的上网,Stack Overflow上的方案试了个遍还是不行,太闹心了!

下面直接给你一套可以复制粘贴的最新方案,完美解决你的需求:进入MathActivity时立即检测、浏览PDF时能监听断网,甚至重新开数据但网络不可用也能检测到,还支持多设备,完全避开已废弃的AsyncTask。


核心设计思路

我这套方案用了三个核心组件,互补保障检测准确性:

  • WorkManager:官方推荐的后台任务调度工具,替代AsyncTask,完美适配Android 14+,自动处理Doze模式、设备重启等场景
  • 真实连通性检测:用InetAddress.isReachable()验证是否能访问公共服务器,而不是单纯检测网络连接状态
  • 网络状态监听:配合ConnectivityManager的广播回调,在网络连接状态变化时立即触发检测,和定时检测形成双重保障

步骤1:先加依赖和权限

1.1 项目依赖(build.gradle)

先把需要的库加上:

dependencies {
    // WorkManager 后台任务调度
    implementation "androidx.work:work-runtime:2.8.1"
}

1.2 权限配置(AndroidManifest.xml)

添加必要的网络权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Android 12+ 后台任务需要的通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

步骤2:网络检测工具类

写一个通用工具类,区分「有网络连接」和「能真实上网」两种状态:

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class NetworkUtils {

    // 核心方法:检测是否能真实访问互联网(可传输数据)
    public static boolean isInternetAvailable() {
        try {
            // 用谷歌公共DNS做检测,超时2秒(也可以换成国内的114.114.114.114)
            InetAddress address = InetAddress.getByName("8.8.8.8");
            return address.isReachable(2000);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    // 辅助方法:快速判断是否有网络连接(不保证能上网)
    public static boolean hasNetworkConnection(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) return false;

        Network activeNetwork = cm.getActiveNetwork();
        if (activeNetwork == null) return false;

        NetworkCapabilities capabilities = cm.getNetworkCapabilities(activeNetwork);
        return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
    }
}

步骤3:定时检测的WorkManager任务

创建一个Worker类,执行网络检测并通过LiveData把结果通知给页面:

import android.content.Context;
import androidx.lifecycle.MutableLiveData;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

public class NetworkCheckWorker extends Worker {

    // 全局LiveData,用于向页面传递检测结果
    public static final MutableLiveData<Boolean> networkAvailabilityLiveData = new MutableLiveData<>();

    public NetworkCheckWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
        // 执行真实网络检测
        boolean isAvailable = NetworkUtils.isInternetAvailable();
        // 把结果发送给页面
        networkAvailabilityLiveData.postValue(isAvailable);
        // 返回成功,让WorkManager继续调度下一次任务
        return Result.success();
    }
}

步骤4:MathActivity完整实现逻辑

直接把下面的代码复制到你的MathActivity里,就能实现所有需求:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import java.util.concurrent.TimeUnit;

public class MathActivity extends AppCompatActivity {

    private WorkManager workManager;
    private PeriodicWorkRequest periodicWorkRequest;
    private NetworkChangeReceiver networkChangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_math);

        // 1. 初始化WorkManager,创建每5分钟一次的定时检测任务
        workManager = WorkManager.getInstance(this);
        periodicWorkRequest = new PeriodicWorkRequest.Builder(NetworkCheckWorker.class, 5, TimeUnit.MINUTES)
                .build();

        // 2. 进入页面时立即检测一次网络
        checkInternetImmediately();

        // 3. 监听网络检测结果,更新UI或提示用户
        NetworkCheckWorker.networkAvailabilityLiveData.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean isAvailable) {
                if (isAvailable) {
                    showToast("网络已恢复可用");
                    // 这里可以写恢复PDF加载、隐藏断网提示的逻辑
                } else {
                    showToast("当前网络无法连接到互联网");
                    // 这里可以写暂停PDF加载、显示断网提示的逻辑
                }
            }
        });

        // 4. 注册网络状态变化广播,网络连接状态改变时立即检测
        networkChangeReceiver = new NetworkChangeReceiver();
        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeReceiver, filter);
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 页面回到前台时,启动定时检测任务
        workManager.enqueue(periodicWorkRequest);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 页面退到后台时,暂停定时检测(可选,根据你的需求调整)
        workManager.cancelWorkById(periodicWorkRequest.getId());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 页面销毁时,取消广播注册和定时任务
        unregisterReceiver(networkChangeReceiver);
        workManager.cancelWorkById(periodicWorkRequest.getId());
    }

    // 立即触发一次网络检测
    private void checkInternetImmediately() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean isAvailable = NetworkUtils.isInternetAvailable();
                NetworkCheckWorker.networkAvailabilityLiveData.postValue(isAvailable);
            }
        }).start();
    }

    // 监听网络连接状态变化的广播接收器
    private class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // 网络连接状态变化时,立即检测一次真实连通性
            checkInternetImmediately();
        }
    }

    // 封装Toast工具方法
    private void showToast(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
}

关键细节说明

  1. 真实连通性检测:InetAddress.isReachable()会尝试和公共DNS建立TCP连接,能准确判断是否能上网,而不是单纯检测有没有WiFi/数据连接
  2. WorkManager优势:替代AsyncTask的最佳选择,自动处理后台任务限制,支持设备重启后继续调度
  3. 双重检测机制:定时检测(每5分钟)+ 网络状态变化即时检测,确保任何网络异常都能被及时捕捉
  4. 多设备兼容性:支持Android 6.0+,适配各种品牌的设备系统

内容的提问来源于stack exchange,提问作者Md. Moniruzzaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:52:45