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

应用处于后台时获取WifiInfo异常,如何解决?

解决后台获取WiFi SSID返回的问题

1. 检查并申请必要权限

Android系统对WiFi信息的获取有严格的权限与隐私限制,尤其是后台场景:

  • 必须在AndroidManifest.xml中声明以下权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Android 12(API 31)及以上,后台获取WiFi信息必须声明此权限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
  • 动态申请权限:除Manifest声明外,需在代码中主动请求ACCESS_FINE_LOCATION权限;ACCESS_BACKGROUND_LOCATION无法通过弹窗直接申请,需引导用户到应用设置中手动开启。

2. 改用合法的后台任务执行方式

你当前使用MainScope启动的协程会绑定Activity生命周期,应用后台时Activity进入停止状态,协程会被系统限制执行。推荐两种稳定的后台任务方案:

方案A:使用WorkManager定期调度任务

WorkManager是Android官方适配系统后台限制的任务调度工具,兼容性更强:

  1. 先添加依赖到build.gradle:
implementation "androidx.work:work-runtime-ktx:2.8.1"
  1. 创建Worker类处理WiFi信息获取:
class WifiInfoWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val wifiInfo = wifiManager.connectionInfo
        // 仅当WiFi已连接时打印
        if (wifiInfo.networkId != -1) {
            Log.d("###", "SSID: ${wifiInfo.ssid}")
        }
        // 重复执行任务,间隔1秒
        return Result.retry()
    }
}
  1. 在Activity中启动任务:
val workRequest = PeriodicWorkRequestBuilder<WifiInfoWorker>(1, TimeUnit.SECONDS)
    .build()
WorkManager.getInstance(this).enqueue(workRequest)

方案B:使用前台服务持续获取

如果需要实时监控WiFi状态,前台服务优先级更高,不会被系统轻易限制:

  1. 创建前台服务类:
class WifiForegroundService : Service() {
    private lateinit var monitorJob: Job

    override fun onCreate() {
        super.onCreate()
        // Android 8.0+要求前台服务必须显示通知
        val notification = NotificationCompat.Builder(this, "WIFI_MONITOR_CHANNEL")
            .setContentTitle("WiFi监控中")
            .setContentText("正在获取当前SSID")
            .setSmallIcon(R.drawable.ic_wifi)
            .build()
        startForeground(1, notification)

        // 在IO线程启动协程持续获取SSID
        monitorJob = CoroutineScope(Dispatchers.IO).launch {
            val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
            while (isActive) {
                val wifiInfo = wifiManager.connectionInfo
                if (wifiInfo.networkId != -1) {
                    Log.d("###", "SSID: ${wifiInfo.ssid}")
                }
                delay(1000)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        monitorJob.cancel()
    }

    override fun onBind(intent: Intent): IBinder? = null
}
  1. 在Manifest中声明服务:
<service android:name=".WifiForegroundService" android:foregroundServiceType="location" />
  1. 在Activity中启动服务(需先确认权限已授予):
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    val intent = Intent(this, WifiForegroundService::class.java)
    ContextCompat.startForegroundService(this, intent)
}

3. 额外优化建议

  • 避免过于频繁的WiFi信息查询,可适当延长间隔减少资源消耗;
  • 检查设备电池优化设置,将应用排除在电池优化外,防止后台任务被系统强制终止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:15:55