【问题标题】:No response received in startscan method at WifiManager in Android 8 Oreo在 Android 8 Oreo 的 WifiManager 的 startscan 方法中没有收到响应
【发布时间】:2018-05-21 10:43:56
【问题描述】:

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

这是文档的链接。 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。它在具有 targetSdkVersion 26+ 的 Android 8 中除外

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 中,我们使用以下许可和声明的 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 android-8.0-oreo wifimanager


    【解决方案1】:

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

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

    要让它在Android 8 OreotargetSdkVersion 26+ 中工作,您必须通过您的Application Context 注册它。

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

    但是注意,这种注册需要应用程序正在运行,所以当您的应用程序停止时,您将不会收到此BroadcastReceiver

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

    【讨论】:

      猜你喜欢
      • 2018-08-17
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      • 2018-12-12
      相关资源
      最近更新 更多