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

Android开发新手求助:实现后台定时检测特定WiFi并调用指定类

实现后台检测特定WiFi并触发逻辑的方案

嘿,作为Android新手,这个需求其实挺常见的,我来一步步给你捋清楚怎么实现~

第一步:先搞定必要的权限

Android系统对权限管得严,要检测WiFi状态,得先在AndroidManifest.xml里声明这些权限:

<!-- 基础网络权限,获取WiFi和网络状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 划重点:Android 10及以上,要获取具体WiFi名称必须要位置权限,不然只能拿到"<unknown ssid>" -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 如果用前台服务持续后台运行,Android 12+还要通知权限,因为前台服务得显示通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

这些都是危险权限,不能只在Manifest里声明就行,还得在Activity里动态申请(比如启动时弹出权限请求框),用户同意了才能用。

第二步:选个合适的检测方式

我给你两种方案,按需选:

方式1:监听网络变化(推荐!更省电高效)

比起每隔几分钟查一次,直接监听网络状态变化更聪明——只有当网络切换的时候才触发检查,不会浪费电量。用ConnectivityManager的NetworkCallback就能实现:

先写个回调类,专门处理WiFi连接事件:

class WifiNetworkCallback(
    private val context: Context,
    private val targetSsid: String,
    private val onConnectedToTargetWifi: () -> Unit
) : ConnectivityManager.NetworkCallback() {

    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        // 获取当前连接的WiFi信息
        val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val currentWifiInfo = wifiManager.connectionInfo
        // 注意:SSID返回的是带双引号的字符串,比如"家里的WiFi",得去掉引号再对比
        val currentSsid = currentWifiInfo.ssid.removeSurrounding("\"")
        
        if (currentSsid == targetSsid) {
            // 连上目标WiFi啦!调用你的指定类
            onConnectedToTargetWifi.invoke()
        }
    }

    override fun onLost(network: Network) {
        super.onLost(network)
        // 网络断开了,要是有需要可以在这里做些清理(可选)
    }
}

然后在服务或者Activity里注册这个回调:

// 获取ConnectivityManager实例
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
// 只监听WiFi类型的网络
val networkRequest = NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .build()
// 注册回调,传入你的目标SSID和触发逻辑
val callback = WifiNetworkCallback(this, "你的目标WiFi名称") {
    // 这里调用你的指定类,比如:
    // YourTargetClass().doYourBusiness()
}
connectivityManager.registerNetworkCallback(networkRequest, callback)

方式2:定时轮询(适合简单场景)

如果你觉得监听方式有点复杂,用定时轮询也可以——每隔几分钟查一次当前WiFi是不是目标网络。这里推荐用WorkManager,它是Android官方推荐的后台任务调度工具,能避开系统的后台限制,保证任务能执行。

先写一个Worker类,负责检查WiFi:

class WifiCheckWorker(
    private val context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    // 替换成你的目标WiFi名称
    private val targetSsid = "你的目标WiFi名称"

    override suspend fun doWork(): Result {
        val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val currentWifiInfo = wifiManager.connectionInfo
        val currentSsid = currentWifiInfo.ssid.removeSurrounding("\"")

        if (currentSsid == targetSsid) {
            // 连上目标WiFi,调用指定类
            YourTargetClass().doYourBusiness()
        }

        // 让任务每隔15分钟重复执行(系统可能会根据状态调整最小间隔)
        return Result.retry()
    }
}

然后在合适的地方启动这个Worker:

// 创建一个每15分钟执行一次的任务请求
val periodicRequest = PeriodicWorkRequestBuilder<WifiCheckWorker>(15, TimeUnit.MINUTES)
    .build()
// 交给WorkManager调度执行
WorkManager.getInstance(this).enqueue(periodicRequest)

第三步:搞定后台运行的坑

Android现在对后台应用限制特别严,尤其是Doze模式(低电量时系统会限制后台操作),如果想持续检测,建议用前台服务——它会在通知栏显示一个持续的小通知,系统就不会轻易把它杀掉。

写个前台服务示例:

class WifiMonitorService : Service() {
    private lateinit var networkCallback: WifiNetworkCallback

    override fun onCreate() {
        super.onCreate()
        // 先创建前台通知,必须的!
        val notificationChannelId = "WIFI_MONITOR_CHANNEL"
        // Android 8.0+ 需要创建通知渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                notificationChannelId,
                "WiFi监控",
                NotificationManager.IMPORTANCE_LOW
            )
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
        // 构建通知内容
        val notification = NotificationCompat.Builder(this, notificationChannelId)
            .setContentTitle("WiFi监控中")
            .setContentText("正在检测目标WiFi连接")
            .setSmallIcon(R.drawable.ic_wifi) // 替换成你的图标
            .build()

        // 启动前台服务,传入通知ID和通知对象
        startForeground(1, notification)

        // 注册网络回调,开始监听WiFi
        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val networkRequest = NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .build()
        networkCallback = WifiNetworkCallback(this, "你的目标WiFi名称") {
            YourTargetClass().doYourBusiness()
        }
        connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 服务销毁时记得注销回调,避免内存泄漏
        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        connectivityManager.unregisterNetworkCallback(networkCallback)
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

别忘了在Manifest里声明这个服务:

<service 
    android:name=".WifiMonitorService" 
    android:foregroundServiceType="location" />

最后提醒几个关键点

  • 位置权限必须申请:Android 10+没有位置权限的话,拿不到真实的WiFi名称,只能拿到<unknown ssid>,这时候对比肯定失败。
  • SSID的格式问题:connectionInfo.ssid返回的是带双引号的字符串,一定要用removeSurrounding("\"")去掉引号再和你的目标SSID对比。
  • 后台任务选WorkManager:别自己用Timer或者Handler搞定时,很容易被系统杀掉,WorkManager是官方推荐的,更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:16:13