Android 6.0中的扫描结果可用操作返回空列表

Android 6.0中的扫描结果可用操作返回空列表,android,android-wifi,android-6.0-marshmallow,Android,Android Wifi,Android 6.0 Marshmallow,昨天,我的Nexus 5收到了从安卓MNC到6.0版棉花糖的更新。 此后,扫描设备中可用网络的操作将停止接收列表,在这种情况下,结果列表的大小为0,即使Wifi系统设置中列出了10+个Wifi网络 此操作的代码通常是:注册扫描结果\u可用\u操作并在接收器中等待事件,如下所示: // Register the Receiver in some part os fragment... getActivity().registerReceiver(wifiListener, new IntentFi

昨天,我的Nexus 5收到了从安卓MNC到6.0版棉花糖的更新。 此后,扫描设备中可用网络的操作将停止接收列表,在这种情况下,结果列表的大小为0,即使Wifi系统设置中列出了10+个Wifi网络

此操作的代码通常是:注册
扫描结果\u可用\u操作
并在接收器中等待事件,如下所示:

// 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.
//在某些部分操作系统片段中注册接收器。。。
getActivity().registerReceiver(wifiListener,新的IntentFilter(WifiManager.SCAN\u RESULTS\u AVAILABLE\u ACTION));
WifiManager WifiManager=(WifiManager)getActivity().getSystemService(Context.WIFI_服务);
wifiManager.startScan();
//在接收器内部:
WifiManager=(WifiManager)context.getSystemService(context.WIFI\u SERVICE);
List results=wifiManager.getScanResults();
//更新到Android v6.0后,result.size()为0,与旧设备中的代码相同。
我在主题中搜索了有关此功能的内容,但没有看到此功能有任何突破性的更改

有人注意到了吗?API中是否有新的内容,或者只是个别情况?

Edit 因此,问题似乎在于新的权限处理。在继续使用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();
    }
}
此检查必须在活动中完成

原始示例代码可用,并根据本主题中讨论的问题进行了修改

起初的 根据链接,应用程序必须具有其中一个位置权限。引述:

WifiManager.getScanResults():您的应用程序必须具有访问\u精细\u位置或访问\u粗略\u位置权限

还请注意,您的广播接收器在
扫描结果\u可用\u操作
操作:
额外结果\u更新
上接收到一条消息。这显示扫描是否完成,您可以通过调用
wifiManager.getScanResults()

编辑来访问结果 因此,问题似乎在于新的权限处理。在继续使用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();
    }
}
此检查必须在活动中完成

原始示例代码可用,并根据本主题中讨论的问题进行了修改

起初的 根据链接,应用程序必须具有其中一个位置权限。引述:

WifiManager.getScanResults():您的应用程序必须具有访问\u精细\u位置或访问\u粗略\u位置权限


还请注意,您的广播接收器在
扫描结果\u可用\u操作
操作:
额外结果\u更新
上接收到一条消息。这显示扫描是否已完成,并且您可以通过调用wifiManager.getScanResults()

访问结果。从Android 6.0开始,权限行为已更改为运行时。若要使用需要权限的功能,应首先检查该权限以前是否已授予。使用
checkSelfPermission(permissionString)
返回一个结果,结果是
permission\u被授予
permission\u被拒绝

如果未授予权限或是第一次,则应提出权限请求。给用户授予或拒绝的选项

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 Services
LocationSettingsStatusCodes.RESOLUTION\u REQUIRED
回调中是可能的。

从Android 6.0开始,权限行为已更改为运行时。若要使用需要权限的功能,应首先检查该权限以前是否已授予。使用
checkSelfPermission(permissionString)
返回一个结果,结果是
permission\u被授予
permission\u被拒绝

如果未授予权限或是第一次,则应提出权限请求。给用户授予或拒绝的选项

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 Services
LocationSettingsStatusCodes中是可能的。需要分辨率
回调。

我在AOSP问题跟踪程序issue WifiManager中找到相关问题#getScanResults()在GPS关闭时返回空数组列表

问题从中提到,手机必须开通定位服务才能获得手机的wifi列表

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


该应用程序位于targetSdkVersion 23中,只需按照上述解决方案检查运行时权限。强制启用位置服务问题将在Android的未来版本中得到解决

我在AOSP issue tracker issue WifiManager中找到了相关问题#getScanResults()在GPS关闭时返回空数组列表

问题从中提到,手机必须开通定位服务才能获得手机的wifi列表

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

该应用程序位于targetSdkVersion 23中,只需按照上述解决方案检查运行时权限。强制使能