Android M 开发中wifi列表显示问题的实践

公司在开发一个读取wifi列表的应用功能时,遇到了兼容性问题,由于之前一直是在Android4.0到Android 5.0之间开发,遇到Android M(6.0)的时候,还真是有点郁闷。言归正传,在网上查询了好多地方,简书上的一篇文章还是很靠谱的,帮我找到了解决方案,附上地址:http://www.jianshu.com/p/3400ca0deeee。

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Android 6.0发布近一年之后,我遇到了第一个Android 6.0的兼容性问题,getScanResults在Android6.0上返回了一个空列表,getScanResults的源码是这样的:

public List<ScanResult> getScanResults(String callingPackage) {
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()) {
	 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);
}
 }
 private boolean isLocationEnabled() {
 return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE,
 Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF;
 }
 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()) {
	 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);
 }
 }

 private boolean isLocationEnabled() {
 	return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE,
	 Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF;
 }

//此处重要
 if (!canReadPeerMacAddresses && !isActiveNetworkScorer
	 && !isLocationEnabled()) {
	 return new ArrayList<ScanResult>();
 }

可以看到如果定位关闭,那么将直接返回一个空的列表,当我去打开定位时,果然就正常的返回了WiFi列表,于是解决方案就是在6.0以上系统中,帮用户打开GPS开关:

if (Build.VERSION.SDK_INT >= 23 && !AppUtil.isGpsOPen(this)) {    
Settings.Secure.putInt(getContentResolver(),Settings.Secure.LOCATION_MODE, 1);
}
以上这段方法,可能SDK版本的问题吧,我的试验并不成功,不得不改为提示用户去打开GPS开关:

if (Build.VERSION.SDK_INT >= 23 && !isGpsOpen(MainTestActivity.this)) {

            Intent gpsIntent = new Intent();
            gpsIntent.setClassName("com.Android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
            gpsIntent.addCategory("android.intent.category.ALTERNATIVE");
            gpsIntent.setData(Uri.parse("custom:3"));
            try {
               PendingIntent.getBroadcast(MainTestActivity.this, 0, gpsIntent, 0).send();
            } catch (PendingIntent.CanceledException e) {
               e.printStackTrace();
            }

         }

当然,这里还需要用到一些权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>

如果App不是system app,那么是获取不到WRITE_SECURE_SETTINGS权限的,此时就要引导用户去手动打开GPS开关,跟简书作者心情一样:为何扫描个WiFi也需要打开GPS。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值