SCAN_RESULTS_AVAILABLE_ACTION在Android 6.0中返回空列表
昨天我的Nexus 5从Android MNC收到更新到版本6.0 - Marshmallow 。 此后,扫描设备中可用networking的操作停止接收列表,在这种情况下,结果列表的大小为0,即使Wifi系统设置中列出了10个以上的Wifinetworking。 
 代码如下:注册SCAN_RESULTS_AVAILABLE_ACTION并等待Receiver中的事件,如下所示: 
 // Register the Receiver in some part os fragment... getActivity().registerReceiver(wifiListener, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); WifiManager wifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE); wifiManager.startScan(); // Inside the receiver: WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); List<ScanResult> results = wifiManager.getScanResults(); // the result.size() is 0 after update to Android v6.0, same code working in older devices. 
我search了关于这个API主题的变化 ,但是我没有看到这个function的任何重大改变。
有没有人注意到这个? 在API中是新东西还是只是一个孤立的情况?
 从Android 6.0开始,权限行为已经更改为运行时。 要使用需要权限的function,应该先检查权限是否先前被授予。 使用checkSelfPermission(permissionString) 方法返回一个结果, checkSelfPermission(permissionString)权限是PERMISSION_GRANTED还是PERMISSION_DENIED 。 
如果未获得许可或者是第一次,则应该提出许可请求。 给用户授予或拒绝的选项。
 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){ requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION); //After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method }else{ getScanningResults(); //do something, permission was previously granted; or legacy device } 
如果您的代码在M之前的设备上运行,则继续执行代码,使用传统方法授予权限。
一旦请求许可,对话框将显示给用户。 他/她的回应将作为:
 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Do something with granted permission mWifiListener.getScanningResults(); } } 
 之后,您可以使用LocationServices.SettingsApi检查位置服务是否处于开启状态,并请求用户在禁用此选项时启用。 这是可能的Play服务LocationSettingsStatusCodes.RESOLUTION_REQUIREDcallback。 
我在AOSP问题跟踪问题185370中find相关问题WifiManager#getScanResults()返回一个空数组列表,如果GPSclosures。
问题来自#1 ,手机必须打开位置服务才能获取手机的wifi列表。
从#18开始 ,Android项目成员声称开发团队已经解决了您所报告的问题,并将在未来的版本中提供。
APP在targetSdkVersion 23中,只需按照上面的解决scheme来检查运行时权限。 强化定位服务问题将在Android未来版本中解决。
编辑
所以,这个问题似乎是与新的权限处理。 在进入wifi代码之前,您必须先获得许可。 这里是一个例子:
 // call this method only if you are on 6.0 and up, otherwise call doGetWifi() private void getWifi() { if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 0x12345); } else { doGetWifi(); // the actual wifi scanning } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == 0x12345) { for (int grantResult : grantResults) { if (grantResult != PackageManager.PERMISSION_GRANTED) { return; } } getWifi(); } } 
这项检查必须在活动中完成。
原始示例代码在此处可用,根据本主题中讨论的问题进行修改。
原版的
根据API的链接更改 ,您的应用程序必须具有其中一个位置权限。 引用:
WifiManager.getScanResults():您的应用程序必须具有ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限。
 另外请注意,您的BroadcastReceiver在SCAN_RESULTS_AVAILABLE_ACTION操作中收到了新的布尔键 : EXTRA_RESULTS_UPDATED 。 这显示扫描是否完成,您可以通过调用wifiManager.getScanResults()来访问结果。 
 除了给出的回答之外, 您还可以使用ContextCompat checkSelfPermission来允许向下兼容较低的Android版本: 
 if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST_CODE_ACCESS_FINE_LOCATION); // Get the result in onRequestPermissionsResult(int, String[], int[]) } else { // Permission was granted, do your stuff here }