根据官方Android文档,WifiManager中的方法startScan在API级别P中已弃用。但我尝试在API级别26(P之前)中使用此方法但未成功。如果用户同意所需的权限,我已经开发了一个需要扫描WiFi网络的应用程序,这种行为对于应用程序的适当运行至关重要。但是,在调用startScan方法时,我没有收到任何响应。 ¿任何人都可以帮我解决这个问题或找到替代解决方案吗?
这是文档的链接。 https://developer.android.com/reference/android/net/wifi/WifiManager.html#startScan()
干杯
修改:
这是启动de scannig进程的代码:
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”,但它对结果没有影响。
我会感激你的帮助。
答案 0 :(得分:5)
在Android 8或更高版本中,由于性能原因,不再发送或收到通过BroadcastReceivers
声明的隐式Manifest
(这是Android 8
中引入的限制background execution的优化})。列出了here列举的一些例外情况,但android.net.wifi.SCAN_RESULTS
操作不是例外,因此在Android 8+中您无法注册android.net.wifi.SCAN_RESULTS
操作以等待ScanResults
Manifest
(实际上你可以,但你什么都不会收到)。
如果您的targetSdkVersion
为26(Android 8 Oreo
)或更高,则会发生这种情况,但如果您在Gradle
文件中声明targetSdkVersion
25或更低,则此优化将无法运行对于您的应用,通过Intents
注册的隐式Manifest
将按预期工作。
要使用Android 8 Oreo
26+在targetSdkVersion
中使用它,您必须通过Application Context
进行注册。
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.wifi.SCAN_RESULTS");
context.registerReceiver(new InOutWifiScanResultsReceiver(), intentFilter);
但是要注意,这种注册要求应用正在运行,因此当您的应用停止时,您将无法收到此BroadcastReceiver
。
P.S:您的代码是正确的,但您没有记住这个Android 8
限制。