SCAN_RESULTS_AVAILABLE_ACTION return empty list in Android 6.0

╄→гoц情女王★ 提交于 2019-11-26 03:11:34

问题


Yesterday my Nexus 5 receive the update from Android MNC to version 6.0 - Marshmallow. Since then, the action to scan the networks available in the device stop receiving the list, in this case the result list have a size of 0, even with 10+ Wifi networks listed in the Wifi system settings.

The code for this is the usual: Register the SCAN_RESULTS_AVAILABLE_ACTION and wait for the event in the Receiver, like this:

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

I searched in the changes of the API topic about this, but I didn\' see any breaking changes for this functionality.

Did anyone notice this? Is something new in the API or just a isolated case?


回答1:


As of Android 6.0, permission behaviour has changed to runtime. To use a feature that requires a permission, one should check first if the permission is granted previously. Using checkSelfPermission(permissionString) method a result is returned, wither ther permission is PERMISSION_GRANTED or PERMISSION_DENIED.

If permission isn't granted or it is first time, a request for permission should be made. Giving a user an option to grant or deny.

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
}

If your code is running on device prior to M, you proceed with your code, permission was granted using legacy method.

Once requested for permission, dialog will be shown to user. His/her response will be delivered as:

@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();
     }
 }

After that, you can check if the Location Services is ON, using LocationServices.SettingsApi and request the user to enable if this options is disabled. This is possible with Play Services LocationSettingsStatusCodes.RESOLUTION_REQUIRED callback.




回答2:


I find related issue in AOSP issue tracker issue 185370 WifiManager#getScanResults() returns an empty array list if GPS is turned off.

The problem mentions from #1, The mobile must open location service to get wifi list of mobile.

And From #18, The Android project member claims that the development team has fixed the issue that you have reported and it will be available in a future build.

The APP is in targetSdkVersion 23, just follow above solution to check runtime permission. Enforcing to enable location services problem will fix in Android future release.




回答3:


Edit

So, the problem seems to be with the new permission handling. You have to ask for permission before proceeding to the wifi code. Here is an example:

// 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();
    }
}

This check must be done in an Activity.

The original sample code is available here, modified according to the problem discussed in this topic.

Original

According to the linked changes of the API, your application must have one of the location permissions. Quote:

WifiManager.getScanResults(): Your app must have ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission.

Also note that there is a new boolean key received by your BroadcastReceiver on SCAN_RESULTS_AVAILABLE_ACTION action: EXTRA_RESULTS_UPDATED. This shows if the scan is complete and you can access the results by calling wifiManager.getScanResults().




回答4:


This won't work unless you have the GPS turned on. Weird, but it's the only way I got the list of wifi's :-(.




回答5:


In addition to the given responses; you can also use checkSelfPermission of ContextCompat to allow for backwards compatibility with lower Android versions:

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
}


来源:https://stackoverflow.com/questions/32151603/scan-results-available-action-return-empty-list-in-android-6-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!