45

昨天我的 Nexus 5 收到了从Android MNC到版本的更新6.0 - Marshmallow。从那时起,扫描设备中可用网络的操作停止接收列表,在这种情况下,结果列表的大小为 0,即使 Wifi 系统设置中列出了 10 多个 Wifi 网络。

代码是通常的:SCAN_RESULTS_AVAILABLE_ACTION在接收器中注册并等待事件,如下所示:

// 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.

我搜索了有关此功能的 API主题的更改,但我没有看到此功能的任何重大更改。

有没有人注意到这一点?API 中有什么新东西还是只是一个孤立的案例?

4

5 回答 5

59

从 Android 6.0 开始,权限行为已更改为运行时。要使用需要权限的功能,应首先检查之前是否已授予权限。使用checkSelfPermission(permissionString) 方法返回结果,权限为PERMISSION_GRANTEDor 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 ServicesLocationSettingsStatusCodes.RESOLUTION_REQUIRED回调实现。

于 2015-08-22T03:16:25.860 回答
35

我在 AOSP 问题跟踪器问题185370中找到相关问题WifiManager#getScanResults() 如果 GPS 关闭,则返回一个空数组列表。

#1中提到的问题,手机必须打开位置服务才能获取手机的wifi列表。

#18开始,Android 项目成员声称开发团队已经修复了您报告的问题,并且将在未来的构建中提供。

该APP在targetSdkVersion 23,只需按照上面的解决方案检查运行时权限。强制启用位置服务问题将在 Android 未来版本中修复。

于 2015-10-27T07:37:56.643 回答
8

除非您打开 GPS,否则这将不起作用。很奇怪,但这是我获得 wifi 列表的唯一方法 :-(。

于 2018-10-24T15:39:38.607 回答
7

编辑

因此,问题似乎与新的权限处理有关。在继续使用 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();
    }
}

此检查必须在 Activity 中完成。

原始示例代码可在此处获得,根据本主题中讨论的问题进行修改。

原来的

根据API 的链接更改,您的应用程序必须具有位置权限之一。引用:

WifiManager.getScanResults():您的应用必须具有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限。

另请注意,您的 BroadcastReceiver 在action:时收到了一个新的布尔键。这显示扫描是否完成,您可以通过调用访问结果。SCAN_RESULTS_AVAILABLE_ACTIONEXTRA_RESULTS_UPDATEDwifiManager.getScanResults()

于 2015-08-22T02:38:11.880 回答
3

除了给定的响应;您还可以使用checkSelfPermission允许ContextCompat与较低的 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
}
于 2016-04-04T11:03:44.417 回答