Bug分享之飞行模式下wifi开关问题
需要说明的是我在这里分享的是我在工作中遇到的一些bug,并不是要对某个模块进行整个分析,因为我还达不到这种程度。可能我的这些问题,都是一些很小的东西,但是对于刚接触android的我来说也是需要些时间的,我在这写出来只是想对这些个问题有个记录,并且对于和我一样刚学习Android的朋友有些许帮助,如果有什么地方改的不对,希望各位大牛指导教育。
对于Wifi模块的分析,我觉得这两个博客不错,有需要的同学可以去看一下:
http://www.eoeandroid.com/forum.php?mod=viewthread&tid=84118&_dsign=f5ab38c0
http://blog.csdn.net/chenyafei617/article/details/6921231
对于飞行模式的相关分析,也有两个博客:
http://www.cnblogs.com/simonshi/archive/2011/01/25/1944876.html
http://blog.sina.com.cn/s/blog_6d720e5901011hv2.html
现在开始正文,呵呵。对于在飞行模式下能否开启wifi这个问题,正常来说应该是不能开启的,但是前不久有某家航空公司说他们在飞机上已经提供wifi服务,如果不能开的话,那情何以堪啊!我拿到的手机在飞行模式下是可以开启wifi的,但需求又是不能开启wifi,哎,纠结啊!好了,需求:在飞行模式下不能开启wifi。
有两个地方可以对wifi开关进行操作,Settings和状态栏的下拉菜单,我分别对这两个地方进行了修改,我的思路是在飞行模式下让wifi开关按钮不能使用,说明一下我这儿并不是去真正意思的关wifi,而是让wifi开的按钮不能使用。
在packages\apps\Settings\src\com\android\settings\wifi下的WifiEnabler类里有个onCheckedChanged方法,很容易理解,当wifi按钮状态改变时会执行这儿,
1 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2 3 //Do nothing if called as a result of a state machine event 4 5 if (mStateMachineEvent) { 6 7 return; 8 9 } 10 11 // Show toast message if Wi-Fi is not allowed in airplane mode 12 13 if (isChecked && !WirelessSettings.isRadioAllowed(mContext, Settings.Global.RADIO_WIFI)) { 14 15 Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show(); 16 17 // Reset switch to off. No infinite check/listenenr loop. 18 19 buttonView.setChecked(false); 20 21 } 22 23 24 25 ……………………………. 26 27 }
在这个方法里调用了WirelessSettings.isRadioAllowed方法,OK,跟代码,在packages\apps\Settings\src\com\android\settings下找到WirelessSettings的isRadioAllowed方法,这个也容易理解,就是是否允许这个按钮能被使用,
1 public static boolean isRadioAllowed(Context context, String type) { 2 3 if (!AirplaneModeEnabler.isAirplaneModeOn(context)) { 4 5 return true; 6 7 } 8 9 // Here we use the same logic in onCreate(). 10 11 String toggleable = Settings.Global.getString(context.getContentResolver(), 12 13 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 14 15 return toggleable != null && toggleable.contains(type); 16 17 }
从这个方法可以看出,如果飞行模式是关着的,那么直接返回true,通过调试,可以得到toggleable = “bluetooth,wifi,nfc”,继续跟代码,在frameworks/base/packages/SettingsProvider/res/values/defaults.xml:中找到<string name="airplane_mode_toggleable_radios" translatable="false">bluetooth,wifi,nfc</string>,然后toggleable.contains(type)如果要操作bluetooth,wifi,nfc,那么会返回true,就是允许操作,现在已经明白问题在哪儿呢,我尝试了两种修改方法,都可以:1.在String中将wifi去掉。2. return toggleable != null && !toggleable.contains(type) 加个非。个人觉得第一种较好,后面一种会影响bluetooth,nfc的需求。
修改之后就会执行到WifiEnabler的buttonView.setChecked(false),OK,Settings这边修改好了,接着是下拉菜单那块。
在frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\toolbar的QuickSettingsConnectionModel类中的onActualStateChange方法中,就是wifi按钮实际状态改变时会执行这儿,
1 public void onActualStateChange(Context context, Intent intent) { 2 3 if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { 4 5 return; 6 7 } 8 9 int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1); 10 11 setCurrentState(context, wifiStateToFiveState(wifiState)); 12 13 }
我是这样修改的加了几句
1 if(isAirplaneModeOn(context)) 2 3 { 4 5 mWifiTileView.setClickable(false); 6 7 }
通过上面的修改,我实现了相应的需求,可能会有不对的地方,希望各位批评指正,如果有更好的方法,也欢迎大家不吝赐教!