You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android开发:WiFi连接提醒APP服务运行异常问题求助

解决WiFi连接提醒App后台服务异常的问题

看起来你遇到的核心问题是普通后台Service在App关闭后被系统限制,导致定时检测逻辑失效——这其实是Android从8.0(Oreo)开始的后台限制机制导致的,系统会主动回收后台非必要的Service,避免资源浪费。

我给你两个更可靠的解决方案,优先推荐第一种(事件驱动,更高效):


方案1:用BroadcastReceiver监听WiFi连接状态(推荐)

不用每分钟轮询,而是监听WiFi状态变化的系统广播,只有当WiFi连接状态改变时才触发检测,既省电又可靠。

步骤1:实现BroadcastReceiver

public class WifiConnectReceiver extends BroadcastReceiver {
    private final String mTargetWifi;
    private Vibrator mVibrator;

    public WifiConnectReceiver(String targetWifi) {
        mTargetWifi = targetWifi;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // 只处理WiFi网络状态变化的广播
        if (!WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
            return;
        }

        NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        if (networkInfo == null || !networkInfo.isConnected()) {
            return;
        }

        // 获取当前连接的WiFi名称
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        String currentSsid = wifiInfo.getSSID().replace("\"", ""); // 去掉SSID自带的引号

        // 匹配目标WiFi
        if (mTargetWifi.equals(currentSsid)) {
            // 触发1秒震动
            mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mVibrator.vibrate(VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE));
            } else {
                mVibrator.vibrate(1000);
            }

            // 取消广播监听,终止任务
            context.unregisterReceiver(this);
        }
    }
}

步骤2:在Activity中注册广播

当用户选择好目标WiFi后,注册这个广播:

// 假设用户选择的目标WiFi名称是targetWifi
String targetWifi = "MyHomeWiFi";

IntentFilter filter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
WifiConnectReceiver receiver = new WifiConnectReceiver(targetWifi);
// 如果需要App关闭后仍能监听,要动态注册(静态注册在Android 12+有限制)
registerReceiver(receiver, filter);

方案2:用WorkManager实现可靠定时检测

如果必须保持每分钟检测的逻辑,WorkManager是Android官方推荐的后台任务调度工具,它能适配不同系统版本,自动处理系统限制,保证任务尽可能执行。

步骤1:实现Worker类

public class WifiCheckWorker extends Worker {
    private static final String KEY_TARGET_WIFI = "TARGET_WIFI";

    public WifiCheckWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        String targetWifi = getInputData().getString(KEY_TARGET_WIFI);
        if (targetWifi == null) {
            return Result.failure();
        }

        // 获取当前WiFi信息
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        String currentSsid = wifiInfo.getSSID().replace("\"", "");

        // 匹配目标WiFi
        if (targetWifi.equals(currentSsid)) {
            // 触发震动
            Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                vibrator.vibrate(VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE));
            } else {
                vibrator.vibrate(1000);
            }

            // 任务完成,不再重试
            return Result.success();
        }

        // 未匹配到,继续下一次检测
        return Result.retry();
    }
}

步骤2:启动定时任务

在用户选择WiFi后,启动WorkManager任务:

String targetWifi = "MyHomeWiFi";

// 设置任务约束:仅在有网络时运行
Constraints constraints = new Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build();

// 创建每分钟执行一次的定时任务
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
                WifiCheckWorker.class,
                1, TimeUnit.MINUTES)
        .setConstraints(constraints)
        .setInputData(new Data.Builder().putString(WifiCheckWorker.KEY_TARGET_WIFI, targetWifi).build())
        .build();

// 唯一任务名,避免重复创建
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
        "WifiCheckWork",
        ExistingPeriodicWorkPolicy.REPLACE,
        workRequest);

必备权限

记得在AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Android 12+ 需要添加通知权限,否则WorkManager可能无法正常运行 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

为什么原来的Service不行?

从Android 8.0开始,系统对后台Service做了严格限制:当App进入后台(没有可见Activity),后台Service最多只能运行几分钟就会被系统强制停止。普通的Service+Timer/Handler定时的方式完全无法适配这种限制,而WorkManager和BroadcastReceiver是官方推荐的后台任务解决方案,能绕过这些限制。

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

火山引擎 最新活动