美文网首页
getScanResults返回0的原因

getScanResults返回0的原因

作者: Merlin_720 | 来源:发表于2019-07-24 11:31 被阅读0次

前段时间做了一个需求就是获取附近wifi的列表,但是获取到的无线列表一直是0,但是周围有很多的无线网,觉得奇怪,下边就来看看我是怎么解决的。
先来看看我获取无线列表的代码

WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
List scanWifiList = wifiManager.getScanResults();
  Log.e("merlin", scanWifiList.size()+"");

返回的结果确实是0.

原因

于是去翻看源码 这里是7.0的
Android7.0源码

/**
     * Return the results of the most recent access point scan, in the form of a
     * list of {@link ScanResult} objects.
     * 
     * @return the list of results
     */
    public List<ScanResult> getScanResults(String callingPackage) {
        enforceAccessPermission();
        int userId = UserHandle.getCallingUserId();
        int uid = Binder.getCallingUid();
        boolean canReadPeerMacAddresses = checkPeersMacAddress();
        boolean isActiveNetworkScorer = NetworkScorerAppManager.isCallerActiveScorer(mContext, uid);
        boolean hasInteractUsersFull = checkInteractAcrossUsersFull();
        long ident = Binder.clearCallingIdentity();
        try {
            if (!canReadPeerMacAddresses && !isActiveNetworkScorer
                    && !isLocationEnabled(callingPackage)) {
                return new ArrayList<ScanResult>();
            }
            if (!canReadPeerMacAddresses && !isActiveNetworkScorer
                    && !checkCallerCanAccessScanResults(callingPackage, uid)) {
                return new ArrayList<ScanResult>();
            }
            if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid,
                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
                return new ArrayList<ScanResult>();
            }
            if (!isCurrentProfile(userId) && !hasInteractUsersFull) {
                return new ArrayList<ScanResult>();
            }
            return mWifiStateMachine.syncGetScanResultsList();
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

看一下第一个if语句

    if (!canReadPeerMacAddresses && !isActiveNetworkScorer   
               && !isLocationEnabled(callingPackage)) {
                return new ArrayList<ScanResult>();
            }

很明显这个是检查了定位权限,如果没有定位的权限就返回一个新list,于是返回的结果就是0.所有我们找到原因了。(ps:6.0的源码也是这样的,8.0的源码有所不同,但是也是判断了定位权限,6.0以前是不需要判断的)

解决办法

既然找到问题的原因那么咱们就动手去处理一下,下边是代码:

  • manifest里添加定位的权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  • 然后动态请求一下权限
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},
          1);
      //After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method

    }else{
      getScanResults();
      //do something, permission was previously granted; or legacy device
    }
  .....
 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
      @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
      case 1: {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
          getScanResults();
        } else {
    。。。。。
        }
        return;
      }
    }
  }

首先我们判断一下版本,然后检查一下有没有定位权限,如果没有权限,就去申请权限。下边的是申请权限之后的回调,根据用户的同意与否,我们执行后续的操作。如果允许定位的权限那么我们扫描一下,获取周边wifi信息,如果没有就提醒一下用户。

总结

到这里我们就吧问题的原因以及解决办法都聊完了。感觉遇到问题源码才是我们解决问题的最直接的办法,这里也记录一下自己发现问题的过程。大家加油~


公众号

相关文章

网友评论

      本文标题:getScanResults返回0的原因

      本文链接:https://www.haomeiwen.com/subject/qpotrctx.html