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

如何实现重启后仍能持续检测默认网络变化并触发HTTP请求

方案实现说明

完全可行,以下是针对你的需求的具体实现步骤及代码:

核心思路

通过前台服务长期持有网络监听逻辑,搭配开机广播接收器实现设备重启后的自动初始化,同时抽离独立的网络监听工具类,避免依赖Activity,确保后台任务正常执行。


1. 权限配置(AndroidManifest.xml)

先在清单文件中声明必要权限和组件:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Android 13+ 必需 -->

<application ...>
    <!-- 开机广播接收器 -->
    <receiver
        android:name=".BootCompletedReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <!-- 适配部分国产设备 -->
        </intent-filter>
    </receiver>

    <!-- 前台服务 -->
    <service
        android:name=".NetworkMonitorService"
        android:exported="false"
        android:foregroundServiceType="dataSync" />
</application>

2. 抽离网络监听工具类

将网络检测和HTTP请求逻辑独立出来,不依赖Activity:

public class NetworkMonitorUtil {
    private static ConnectivityManager.NetworkCallback networkCallback;
    private static Context appContext;

    public static void init(Context context) {
        appContext = context.getApplicationContext();
    }

    public static void startMonitoring() {
        if (networkCallback != null) return; // 避免重复注册

        ConnectivityManager cm = (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(@NonNull Network network) {
                super.onAvailable(network);
                // 网络恢复时触发后台HTTP请求
                executeHttpRequest();
            }
        };
        cm.registerDefaultNetworkCallback(networkCallback);
    }

    public static void stopMonitoring() {
        if (networkCallback == null) return;
        ConnectivityManager cm = (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        cm.unregisterNetworkCallback(networkCallback);
        networkCallback = null;
    }

    private static void executeHttpRequest() {
        // 用后台线程执行请求,避免ANR
        new Thread(() -> {
            try {
                // 示例:发送GET请求
                URL url = new URL("https://你的目标接口地址");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                // 处理响应逻辑
                int responseCode = conn.getResponseCode();
                conn.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

3. 前台服务实现

通过前台服务保持进程存活,确保网络监听长期有效:

public class NetworkMonitorService extends Service {
    private static final int NOTIFICATION_ID = 1001;
    private static final String CHANNEL_ID = "network_monitor_channel";

    @Override
    public void onCreate() {
        super.onCreate();
        // 创建通知渠道(Android 8.0+ 必需)
        createNotificationChannel();
        // 启动前台服务,避免被系统查杀
        startForeground(NOTIFICATION_ID, buildNotification());
        // 初始化并启动网络监听
        NetworkMonitorUtil.init(this);
        NetworkMonitorUtil.startMonitoring();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY; // 服务被杀死后自动重启(系统允许的情况下)
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        NetworkMonitorUtil.stopMonitoring();
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    CHANNEL_ID,
                    "网络监控",
                    NotificationManager.IMPORTANCE_LOW // 低优先级,不打扰用户
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }

    private Notification buildNotification() {
        return new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_notification) // 替换为你的应用图标
                .setContentTitle("网络监控运行中")
                .setContentText("持续检测网络变化")
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();
    }
}

4. 开机广播接收器

设备重启后自动启动前台服务:

public class BootCompletedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) ||
                "android.intent.action.QUICKBOOT_POWERON".equals(intent.getAction())) {
            Intent serviceIntent = new Intent(context, NetworkMonitorService.class);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(serviceIntent);
            } else {
                context.startService(serviceIntent);
            }
        }
    }
}

5. 首次启动初始化(MainActivity)

APP第一次启动时启动服务,并用SharedPreferences标记已初始化:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SharedPreferences sp = getSharedPreferences("app_prefs", MODE_PRIVATE);
        boolean isInitialized = sp.getBoolean("is_initialized", false);
        if (!isInitialized) {
            Intent serviceIntent = new Intent(this, NetworkMonitorService.class);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(serviceIntent);
            } else {
                startService(serviceIntent);
            }
            sp.edit().putBoolean("is_initialized", true).apply();
        }
    }
}

注意事项

  • 部分国产ROM需要手动开启APP的自启动权限,否则开机广播可能无法触发。
  • Android 13+ 需动态申请POST_NOTIFICATIONS权限,否则前台服务无法启动。
  • HTTP请求必须在后台线程执行,禁止在主线程操作网络。

内容的提问来源于stack exchange,提问作者Chris972

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:34:52