如何在Wi-Fi连接/断开状态变化时触发JobScheduler执行代码?
在Android Oreo+中实现Wi-Fi连接/断开指定路由器时执行代码(基于JobScheduler)
嘿,针对你的需求,我来梳理下可行的实现方案:JobScheduler本身并没有直接监听Wi-Fi连接状态变化的触发条件,所以我们需要结合「广播接收器监听Wi-Fi状态」+「触发JobScheduler任务」的方式来达成目标,具体步骤如下:
1. 先实现JobService任务载体
首先要创建一个JobService的子类,这是JobScheduler执行任务的核心,把你要运行的代码放在onStartJob()方法里:
public class WifiTriggerJobService extends JobService { @Override public boolean onStartJob(JobParameters params) { // 这里写Wi-Fi连接/断开时要执行的业务代码 Log.d("WifiJob", "触发指定代码执行"); // 如果是耗时操作,一定要开线程执行,完成后调用jobFinished()告知系统 new Thread(() -> { // 你的耗时任务逻辑 jobFinished(params, false); // false表示不需要重新调度任务 }).start(); return true; // 返回true表示任务会在后台执行,需手动调用jobFinished() } @Override public boolean onStopJob(JobParameters params) { // 任务被系统强制终止时的处理逻辑,返回true表示需要重新调度 return false; } }
记得在AndroidManifest.xml里注册这个Service,必须加上BIND_JOB_SERVICE权限:
<service android:name=".WifiTriggerJobService" android:permission="android.permission.BIND_JOB_SERVICE" />
2. 监听Wi-Fi状态变化的广播接收器
我们需要一个广播接收器来捕捉Wi-Fi连接/断开的事件,当检测到目标SSID的Wi-Fi状态变化时,立即触发JobScheduler任务。
注意Oreo+的广播限制
Android Oreo之后,大部分隐式广播(比如CONNECTIVITY_ACTION)禁止静态注册,所以推荐动态注册广播接收器。如果需要在应用后台持续监听,建议结合前台Service来托管接收器(避免Service被系统快速杀死);当然,部分Wi-Fi专属广播(比如NETWORK_STATE_CHANGED_ACTION)仍允许静态注册,也可以尝试这种方式。
广播接收器实现代码
public class WifiStateReceiver extends BroadcastReceiver { // 替换成你要监听的路由器SSID private static final String TARGET_SSID = "MyHomeWifi"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); if (networkInfo != null && wifiInfo != null) { // 去掉SSID自带的引号(系统返回的SSID会被双引号包裹) String currentSsid = wifiInfo.getSSID().replace("\"", ""); // 检测是否是目标Wi-Fi的连接/断开事件 if (networkInfo.isConnected() && TARGET_SSID.equals(currentSsid)) { // 连接目标Wi-Fi时触发任务 scheduleWifiJob(context); } else if (!networkInfo.isConnected() && TARGET_SSID.equals(currentSsid)) { // 断开目标Wi-Fi时触发任务 scheduleWifiJob(context); } } } } // 调度JobScheduler任务的方法 private void scheduleWifiJob(Context context) { JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo jobInfo = new JobInfo.Builder(123, new ComponentName(context, WifiTriggerJobService.class)) .setMinimumLatency(0) // 立即执行任务 .setOverrideDeadline(1000) // 1秒内必须完成调度(避免系统延迟) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) // 根据需求设置网络类型,可选 .build(); jobScheduler.schedule(jobInfo); } }
注册广播接收器的两种方式
- 动态注册(推荐):在Activity或者前台Service的
onCreate()方法中注册,记得在onDestroy()中注销:
// 注册 WifiStateReceiver wifiReceiver = new WifiStateReceiver(); IntentFilter filter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION); registerReceiver(wifiReceiver, filter); // 注销(比如在onDestroy中) unregisterReceiver(wifiReceiver);
- 静态注册(后台监听可选):直接在Manifest中配置,适合需要长期后台监听的场景:
<receiver android:name=".WifiStateReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.net.wifi.STATE_CHANGE" /> </intent-filter> </receiver>
3. 添加必要权限
在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 如果使用前台Service托管广播接收器,需要添加这个权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
一些补充提示
- 如果你的任务需要绝对实时执行,JobScheduler可能无法满足(因为系统会统一调度任务),这种情况下建议结合前台Service+动态广播的方式,直接在广播接收器中执行代码。
- 如果你不需要长期后台监听,只是应用在前台时触发,动态注册广播+JobScheduler的组合就足够稳定。
- 也可以考虑使用Jetpack的WorkManager替代JobScheduler,它的兼容性更好,同样可以通过广播触发任务,适合跨版本的场景。
内容的提问来源于stack exchange,提问作者Lcukerd
相关产品推荐
相关产品推荐

