在Android 8 Oreo中的WifiManager上的startscan方法中未收到响应 [英] No response received in startscan method at WifiManager in Android 8 Oreo

查看:312
本文介绍了在Android 8 Oreo中的WifiManager上的startscan方法中未收到响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据Android官方文档,API级别P不推荐使用WifiManager中的startScan方法.但是,我尝试在API级别26(P之前的版本)中使用此方法,但未成功.如果用户同意所需的权限,我已经开发了一个需要扫描WiFi网络的应用程序,这种行为对于该应用程序的正常运行至关重要.但是,调用startScan方法时没有收到任何响应. ¿任何人都可以帮助我解决此问题或找到替代解决方案吗?

According to official Android documentation, the method startScan at WifiManager is deprecated in API level P. However I am trying to use this method in API level 26 (previous to P) without success. I have developped an app which requires the scanning of the WiFi networks, if the user agree with the required permissions, and this behaviour is paramount for the appropriate functioning of the app. However I do not receive any response when calling the startScan method. ¿Can anyone help me to solve this problem or find an alternative solution?

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

欢呼

编辑:

这是开始扫描过程的代码:

This is the code to start de scannig process:

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中运行

And this is the BroadcastReceiver that receives the result of the scan. It works except in Android 8 with 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<>();
      }
   }
}

在清单中,我们使用followint权限,并声明BroadcastReceiver:

In the Manifest we use the followint permissins and the BroadcastReceiver declared:

<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级别).

The location permission is required in runtime so I'm sure it is allowed. I'm also true that location is active (GPS level).

BroadcastReceiver可以正常工作,因为使用targetSdkVersion = 25或更小值进行编译可以按预期进行每个工作,并且可以接收扫描.我还用android:exported ="true"进行了测试,但是它对结果没有影响.

The BroadcastReceiver works fine because compiling with targetSdkVersion = 25 or less every works as expected and scans are received. I have also tested with android:exported="true" , but it doesn't have influence on the results.

感谢您的帮助.

推荐答案

在Android 8或更高版本中,由于性能原因,不再发送或接收通过Manifest声明的隐式BroadcastReceivers(这是Android 8限制了后台执行).在此处中列出了一些例外,但android.net.wifi.SCAN_RESULTS操作不是一个例外,因此在Android 8+中,您无法在Manifest中注册android.net.wifi.SCAN_RESULTS操作来等待ScanResults(实际上可以,但是什么也收不到).

In Android 8 or higher the implicit BroadcastReceivers declared via Manifest are no longer send nor received due to performance reasons (this is an optimization introduced in Android 8 which limits background execution). There are some exceptions which are listed here, but android.net.wifi.SCAN_RESULTS action isn't an exception, so in Android 8+ you can't register a android.net.wifi.SCAN_RESULTS action to wait for ScanResults in the Manifest (actually you can, but you'll receive nothing).

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

This happens if your targetSdkVersion is 26 (Android 8 Oreo) or higher, but if you declare in your Gradle file a targetSdkVersion 25 or lower this optimization will not run for your app and your implicit Intents registered through Manifest will work as expected.

要使其与targetSdkVersion 26+一起在Android 8 Oreo中工作,您必须通过Application Context注册它.

To get it work in Android 8 Oreo with a targetSdkVersion 26+ you have to register it through your Application Context.

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

但是请注意,这种注册要求该应用正在运行,因此当您的应用停止运行时,您将不会收到此BroadcastReceiver.

But be aware, this kind of registration requires the app being running, so when your app is stopped you will not receive this BroadcastReceiver.

P.S:您的代码是正确的,但您没有牢记此Android 8限制.

P.S: Your code is correct, but you didn't keep in mind this Android 8 limitation.

这篇关于在Android 8 Oreo中的WifiManager上的startscan方法中未收到响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆