android4.1.1 Settings WIFI模块浅析

xiaoxiao2021-02-28  95

http://blog.csdn.net/cljfqyd/article/details/8863694

[java] view plain copy <span style="font-family: Arial, Helvetica, sans-serif;">Settings 中的WIFI功能主要在package/Settings/src/com/android/wifi/WifiSettings实现</span>  

首先我们来看下WifiSettings类声明

[java] view plain copy public class WifiSettings extends SettingsPreferenceFragment          implements DialogInterface.OnClickListener  {          ......  }   继承SettingsPreferenceFragment,可见它是一个Fragment我们看到源码中的描述是这样的

/**  * Two types of UI are provided here.  *  * The first is for "usual Settings", appearing as any other Setup fragment.  *  * The second is for Setup Wizard, with a simplified interface that hides the action bar  * and menus.  */

一、注册广播,接受相关wifi信息变化

 WifiSettins类主要负责监测wifi状态,以及加载各个连接点,并负责Fragment界面的显示。  在WifiSettings类中比较重要的一个类是WifiManager(稍后再说,一步一步来).  在WifiSettings构造函数中初始化一个BroadcastReceiver,该BroadcastReceiver监测外部广播

[java] view plain copy public class WifiSettings extends SettingsPreferenceFragment          implements DialogInterface.OnClickListener  {          ......           public WifiSettings() {          mFilter = new IntentFilter();//添加过滤器          mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);          mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);          mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);          mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);          mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);          mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);          mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);          mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);            mReceiver = new BroadcastReceiver() {              @Override              public void onReceive(Context context, Intent intent) {                  handleEvent(context, intent);//事件处理函数              }          };            mScanner = new Scanner();      }      ......      @Override      public void onResume() {          super.onResume();          if (mWifiEnabler != null) {              mWifiEnabler.resume();          }            getActivity().registerReceiver(mReceiver, mFilter);//在onResume注册广播,获得相关wifi信息          if (mKeyStoreNetworkId != INVALID_NETWORK_ID &&                  KeyStore.getInstance().state() == KeyStore.State.UNLOCKED) {              mWifiManager.connect(mChannel, mKeyStoreNetworkId, mConnectListener);          }          mKeyStoreNetworkId = INVALID_NETWORK_ID;            updateAccessPoints();      }      ......       @Override      public void onPause() {          super.onPause();          if (mWifiEnabler != null) {              mWifiEnabler.pause();          }          getActivity().unregisterReceiver(mReceiver);//在onPause注销广播          mScanner.pause();      }      ......  }   广播的处理事件代码:

[java] view plain copy private void handleEvent(Context context, Intent intent) {          String action = intent.getAction();          if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {              updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,                      WifiManager.WIFI_STATE_UNKNOWN));          } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||                  WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) ||                  WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {                  updateAccessPoints();          } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {              //Ignore supplicant state changes when network is connected              //TODO: we should deprecate SUPPLICANT_STATE_CHANGED_ACTION and              //introduce a broadcast that combines the supplicant and network              //network state change events so the apps dont have to worry about              //ignoring supplicant state change when network is connected              //to get more fine grained information.              SupplicantState state = (SupplicantState) intent.getParcelableExtra(                      WifiManager.EXTRA_NEW_STATE);              if (!mConnected.get() && SupplicantState.isHandshakeState(state)) {                  updateConnectionState(WifiInfo.getDetailedStateOf(state));              }          } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {              NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(                      WifiManager.EXTRA_NETWORK_INFO);              mConnected.set(info.isConnected());              changeNextButtonState(info.isConnected());              updateAccessPoints();              updateConnectionState(info.getDetailedState());              if (mAutoFinishOnConnection && info.isConnected()) {                  getActivity().finish();                  return;              }          } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {              updateConnectionState(null);          }      }   二、WifiMananger类是是操作wifi的核心类

WifiManager定义wifi各种状态、wifi Action、网络配置等

[java] view plain copy public class WifiManager {     .....   public WifiManager(IWifiManager service, Handler handler) {          mService = service;          mHandler = handler;      }     ......  }   从IWifiManager 可知道,它是通过远程调用,也就是基于RPC原理(有时间再总结一下)。 为了保证Settings和Wifi相互交互,注册相应的监听对象。

[java] view plain copy public class WifiSettings extends SettingsPreferenceFragment          implements DialogInterface.OnClickListener  {      ......      private WifiManager.ActionListener mConnectListener;//连接      private WifiManager.ActionListener mSaveListener;//保存      private WifiManager.ActionListener mForgetListener;//清除保存      ......      //继承SettingsPreferenceFragment并从写 onActivityCreated方法          @Override      public void onActivityCreated(Bundle savedInstanceState) {          // We don't call super.onActivityCreated() here, since it assumes we already set up          // Preference (probably in onCreate()), while WifiSettings exceptionally set it up in          // this method.            mP2pSupported = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);          mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);          mChannel = mWifiManager.initialize(getActivity(), getActivity().getMainLooper(), null);            mConnectListener = new WifiManager.ActionListener() {                                     public void onSuccess() {//连接成功                                     }                                     public void onFailure(int reason) {//连接失败                                          Toast.makeText(getActivity(),                                              R.string.wifi_failed_connect_message,                                              Toast.LENGTH_SHORT).show();                                     }                                 };            mSaveListener = new WifiManager.ActionListener() {                                  public void onSuccess() {//保存成功                                  }                                  public void onFailure(int reason) {//保存失败                                      Toast.makeText(getActivity(),                                          R.string.wifi_failed_save_message,                                          Toast.LENGTH_SHORT).show();                                  }                              };            mForgetListener = new WifiManager.ActionListener() {                                     public void onSuccess() {//清除保存成功                                     }                                     public void onFailure(int reason) {//清除保存失败                                          Toast.makeText(getActivity(),                                              R.string.wifi_failed_forget_message,                                              Toast.LENGTH_SHORT).show();                                     }                                 };            if (savedInstanceState != null                  && savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) {              mDlgEdit = savedInstanceState.getBoolean(SAVE_DIALOG_EDIT_MODE);              mAccessPointSavedState = savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE);          }            final Activity activity = getActivity();          final Intent intent = activity.getIntent();            // first if we're supposed to finish once we have a connection          mAutoFinishOnConnection = intent.getBooleanExtra(EXTRA_AUTO_FINISH_ON_CONNECT, false);            if (mAutoFinishOnConnection) {              // Hide the next button              if (hasNextButton()) {                  getNextButton().setVisibility(View.GONE);              }                final ConnectivityManager connectivity = (ConnectivityManager)                      getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);              if (connectivity != null                      && connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {                  activity.finish();                  return;              }          }            // if we're supposed to enable/disable the Next button based on our current connection          // state, start it off in the right state          mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false);            if (mEnableNextOnConnection) {              if (hasNextButton()) {                  final ConnectivityManager connectivity = (ConnectivityManager)                          getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);                  if (connectivity != null) {                      NetworkInfo info = connectivity.getNetworkInfo(                              ConnectivityManager.TYPE_WIFI);                      changeNextButtonState(info.isConnected());                  }              }          }            addPreferencesFromResource(R.xml.wifi_settings);//加载布局             if (mSetupWizardMode) {              getView().setSystemUiVisibility(                      View.STATUS_BAR_DISABLE_BACK |                      View.STATUS_BAR_DISABLE_HOME |                      View.STATUS_BAR_DISABLE_RECENT |                      View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS |                      View.STATUS_BAR_DISABLE_CLOCK);          }            // On/off switch is hidden for Setup Wizard          if (!mSetupWizardMode) {              Switch actionBarSwitch = new Switch(activity);                if (activity instanceof PreferenceActivity) {                  PreferenceActivity preferenceActivity = (PreferenceActivity) activity;                  if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {                      final int padding = activity.getResources().getDimensionPixelSize(                              R.dimen.action_bar_switch_padding);                      actionBarSwitch.setPadding(00, padding, 0);                      activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,                              ActionBar.DISPLAY_SHOW_CUSTOM);                      activity.getActionBar().setCustomView(actionBarSwitch, new ActionBar.LayoutParams(                              ActionBar.LayoutParams.WRAP_CONTENT,                              ActionBar.LayoutParams.WRAP_CONTENT,                              Gravity.CENTER_VERTICAL | Gravity.RIGHT));                  }              }                mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);          }            mEmptyView = (TextView) getView().findViewById(android.R.id.empty);          getListView().setEmptyView(mEmptyView);            if (!mSetupWizardMode) {              registerForContextMenu(getListView());          }          setHasOptionsMenu(true);            // After confirming PreferenceScreen is available, we call super.          super.onActivityCreated(savedInstanceState);      }      ......  }  

三、用户on/off交互 用户通过Switch 开关按钮进行对wifi打开和关闭

[java] view plain copy public class WifiSettings extends SettingsPreferenceFragment          implements DialogInterface.OnClickListener  {          ......        public void onActivityCreated(Bundle savedInstanceState) {        ......          // On/off switch is hidden for Setup Wizard          if (!mSetupWizardMode) {              Switch actionBarSwitch = new Switch(activity);                if (activity instanceof PreferenceActivity) {                  PreferenceActivity preferenceActivity = (PreferenceActivity) activity;                  if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {                      final int padding = activity.getResources().getDimensionPixelSize(                              R.dimen.action_bar_switch_padding);                      actionBarSwitch.setPadding(00, padding, 0);                      activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,                              ActionBar.DISPLAY_SHOW_CUSTOM);                      activity.getActionBar().setCustomView(actionBarSwitch, new ActionBar.LayoutParams(                              ActionBar.LayoutParams.WRAP_CONTENT,                              ActionBar.LayoutParams.WRAP_CONTENT,                              Gravity.CENTER_VERTICAL | Gravity.RIGHT));                  }              }                mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);//将actionBarSwitch传递给WifiEnabler          }          ......        }        ......  }   WifiEnabler接受一个Switch对象和,并该对象进行操作 我们可以看下WifiEnabler这个类

[java] view plain copy import android.content.BroadcastReceiver;  import android.content.Context;  import android.content.Intent;  import android.content.IntentFilter;  import android.net.NetworkInfo;  import android.net.wifi.SupplicantState;  import android.net.wifi.WifiInfo;  import android.net.wifi.WifiManager;  import android.provider.Settings;  import android.widget.CompoundButton;  import android.widget.Switch;  import android.widget.Toast;    import com.android.settings.R;  import com.android.settings.WirelessSettings;    import java.util.concurrent.atomic.AtomicBoolean;    public class WifiEnabler implements CompoundButton.OnCheckedChangeListener  {      private final Context mContext;      private Switch mSwitch;      private AtomicBoolean mConnected = new AtomicBoolean(false);        private final WifiManager mWifiManager;      private boolean mStateMachineEvent;      private final IntentFilter mIntentFilter;      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {          @Override          public void onReceive(Context context, Intent intent) {              String action = intent.getAction();              if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {                  handleWifiStateChanged(intent.getIntExtra(                          WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));              } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {                  if (!mConnected.get()) {                      handleStateChanged(WifiInfo.getDetailedStateOf((SupplicantState)                              intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));                  }              } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {                  NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(                          WifiManager.EXTRA_NETWORK_INFO);                  mConnected.set(info.isConnected());                  handleStateChanged(info.getDetailedState());              }          }      };        public WifiEnabler(Context context, Switch switch_) {          mContext = context;          mSwitch = switch_;            mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);          mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);          // The order matters! We really should not depend on this. :(          mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);          mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);      }        public void resume() {          // Wi-Fi state is sticky, so just let the receiver update UI          mContext.registerReceiver(mReceiver, mIntentFilter);          mSwitch.setOnCheckedChangeListener(this);      }        public void pause() {          mContext.unregisterReceiver(mReceiver);          mSwitch.setOnCheckedChangeListener(null);      }        public void setSwitch(Switch switch_) {          if (mSwitch == switch_) return;          mSwitch.setOnCheckedChangeListener(null);          mSwitch = switch_;          mSwitch.setOnCheckedChangeListener(this);            final int wifiState = mWifiManager.getWifiState();          boolean isEnabled = wifiState == WifiManager.WIFI_STATE_ENABLED;          boolean isDisabled = wifiState == WifiManager.WIFI_STATE_DISABLED;          mSwitch.setChecked(isEnabled);          mSwitch.setEnabled(isEnabled || isDisabled);      }        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {          //Do nothing if called as a result of a state machine event          if (mStateMachineEvent) {              return;          }          // Show toast message if Wi-Fi is not allowed in airplane mode          if (isChecked && !WirelessSettings.isRadioAllowed(mContext, Settings.System.RADIO_WIFI)) {              Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();              // Reset switch to off. No infinite check/listenenr loop.              buttonView.setChecked(false);          }            // Disable tethering if enabling Wifi          int wifiApState = mWifiManager.getWifiApState();          if (isChecked && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||                  (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {              mWifiManager.setWifiApEnabled(nullfalse);          }            if (mWifiManager.setWifiEnabled(isChecked)) {              // Intent has been taken into account, disable until new state is active              mSwitch.setEnabled(false);          } else {              // Error              Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();          }      }        private void handleWifiStateChanged(int state) {          switch (state) {              case WifiManager.WIFI_STATE_ENABLING:                  mSwitch.setEnabled(false);                  break;              case WifiManager.WIFI_STATE_ENABLED:                  setSwitchChecked(true);                  mSwitch.setEnabled(true);                  break;              case WifiManager.WIFI_STATE_DISABLING:                  mSwitch.setEnabled(false);                  break;              case WifiManager.WIFI_STATE_DISABLED:                  setSwitchChecked(false);                  mSwitch.setEnabled(true);                  break;              default:                  setSwitchChecked(false);                  mSwitch.setEnabled(true);                  break;          }      }        private void setSwitchChecked(boolean checked) {          if (checked != mSwitch.isChecked()) {              mStateMachineEvent = true;              mSwitch.setChecked(checked);              mStateMachineEvent = false;          }      }        private void handleStateChanged(@SuppressWarnings("unused") NetworkInfo.DetailedState state) {          // After the refactoring from a CheckBoxPreference to a Switch, this method is useless since          // there is nowhere to display a summary.          // This code is kept in case a future change re-introduces an associated text.          /*         // WifiInfo is valid if and only if Wi-Fi is enabled.         // Here we use the state of the switch as an optimization.         if (state != null && mSwitch.isChecked()) {             WifiInfo info = mWifiManager.getConnectionInfo();             if (info != null) {                 //setSummary(Summary.get(mContext, info.getSSID(), state));             }         }         */      }  }   WifiEnabler实现了CompoundButton.OnCheckedChangeListener接口类,可见它也是一个监听器,并且在构造函数中通过接受一个switch对象去观察switch状态。
转载请注明原文地址: https://www.6miu.com/read-59247.html

最新回复(0)