Android 8 Oreo 中 WifiManager 的 startscan 方法未收到响应

No response received in startscan method at WifiManager in Android 8 Oreo

根据官方 Android 文档,WifiManager 的 startScan 方法在 API 级别 P 中已弃用。但是我试图在 API 级别 26(之前P) 没有成功。我开发了一个应用程序,如果用户同意所需的权限,则需要扫描 WiFi 网络,并且此行为对于应用程序的正常运行至关重要。但是,调用 startScan 方法时我没有收到任何响应。 ¿谁能帮我解决这个问题或找到替代解决方案?

这是对文档的 link。 https://developer.android.com/reference/android/net/wifi/WifiManager.html#startScan()

干杯

编辑:

这是启动反扫描过程的代码:

public boolean startScan() {
   WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
   if (!wm.isWifiEnabled()) {
     try {
       wm.setWifiEnabled(true);
     } catch (SecurityException e) {
       Log.w(LOG_TAG, "Error enabling wifi", e);
       return false;
     }
   }
   boolean started = wm.startScan();
   Log.d(LOG_TAG, "Scan started? " + started);
   return started;
}

这是接收扫描结果的BroadcastReceiver。它适用于 Android 8 和 targetSdkVersion 26+

public class InOutWifiScanResultsReceiver extends BroadcastReceiver {
   private static final String LOG_TAG = "ScanResults";

   @Override
   public void onReceive(Context context, Intent intent) {
     super.onReceive(context, intent); // Never called in Android 8 and targetSdkVersion 26+
     List<ScanResult> results = getWifiResults(context);
     Log.d(LOG_TAG, "Received results (" +  results.size() + " AP's)");
   }

   private static List<ScanResult> getWifiResults(Context context) {
      WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
      try {
        return wm.getScanResults();
      } catch (SecurityException e) {
        return new ArrayList<>();
      }
   }
}

在 Manifest 中我们使用 followint permissins 和声明的 BroadcastReceiver:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

 <receiver
    android:name=".InOutWifiScanResultsReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="android.net.wifi.SCAN_RESULTS"/>
    </intent-filter>
 </receiver>

运行时需要位置权限,所以我确定它是允许的。我也确信位置处于活动状态(GPS 级别)。

BroadcastReceiver 工作正常,因为使用 targetSdkVersion = 25 或更低进行编译时,每次都按预期工作并收到扫描。我也用 android:exported="true" 测试过,但它对结果没有影响。

感谢您的帮助。

在 Android 8 或更高版本中,由于性能原因,不再发送或接收通过 Manifest 声明的隐式 BroadcastReceivers(这是 Android 8 中引入的优化)这限制了 background execution). There are some exceptions which are listed here,但是 android.net.wifi.SCAN_RESULTS 操作也不例外,所以在 Android 8+ 中你不能注册一个 android.net.wifi.SCAN_RESULTS 操作来等待 ScanResultsManifest(实际上你可以,但你什么也得不到)。

如果您的 targetSdkVersion 为 26 (Android 8 Oreo) 或更高,则会发生这种情况,但如果您在 Gradle 文件中声明 targetSdkVersion 25 或更低,则此优化将不是 运行 对于您的应用程序,您通过 Manifest 注册的隐式 Intents 将按预期工作。

要在 Android 8 Oreo 中使用 targetSdkVersion 26+,您必须通过 Application Context.

注册它
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.wifi.SCAN_RESULTS");
context.registerReceiver(new InOutWifiScanResultsReceiver(), intentFilter);

但是请注意,这种注册需要应用程序处于 运行ning 状态,因此当您的应用程序停止时,您将不会收到此 BroadcastReceiver .

P.S: 你的代码是正确的,但是你没有记住这个Android 8限制。