前段时间做了一个需求就是获取附近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信息,如果没有就提醒一下用户。
总结
到这里我们就吧问题的原因以及解决办法都聊完了。感觉遇到问题源码才是我们解决问题的最直接的办法,这里也记录一下自己发现问题的过程。大家加油~
公众号
网友评论