Wifi源码学习(Android5.1)之wifi optionItem

来源:互联网 发布:好看的步兵番号知乎 编辑:程序博客网 时间:2024/06/09 22:05

wifi系列博客地址:

Wifi源码学习(Android5.1)之wifi开关
Wifi源码学习(Android5.1)之wifi optionItem
Wifi源码学习(Android5.1)之wifi列表

正文:

optionitem 是什么?
看图:
这里写图片描述
闲话少说,直接上代码:
首先是简单的optionitem 添加的方法。

Settings\src\com\android\settings\wifi\WifiSettings.java

@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {    // If the user is not allowed to configure wifi, do not show the menu.    if (isUiRestricted()) return;    addOptionsMenuItems(menu);    super.onCreateOptionsMenu(menu, inflater);}
/** * @param menu */void addOptionsMenuItems(Menu menu) {//判断 wifi 是否可用    final boolean wifiIsEnabled = mWifiManager.isWifiEnabled();    TypedArray ta = getActivity().getTheme().obtainStyledAttributes(            new int[] {R.attr.ic_menu_add, R.attr.ic_wps});    // 添加网络    menu.add(Menu.NONE, MENU_ID_ADD_NETWORK, 0, R.string.wifi_add_network)            .setIcon(ta.getDrawable(0))            .setEnabled(wifiIsEnabled)            .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);    if (savedNetworksExist) {        // 显示已经保存的 wifi(不一定连接成功过)        menu.add(Menu.NONE, MENU_ID_SAVED_NETWORK, 0, R.string.wifi_saved_access_points_label)                .setIcon(ta.getDrawable(0))                .setEnabled(wifiIsEnabled)                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);    }    // 用的最多的,扫描(刷新)    menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.menu_stats_refresh)           .setEnabled(wifiIsEnabled)           .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);    // 高级设置    menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)            .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);    ta.recycle();}

处理他们点击事件的地方

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    // If the user is not allowed to configure wifi, do not handle menu selections.    if (isUiRestricted()) return false;    switch (item.getItemId()) {        case MENU_ID_WPS_PBC:            showDialog(WPS_PBC_DIALOG_ID);            return true;        case MENU_ID_SCAN:            // 如果wifi可用,则进行搜索            if (mWifiManager.isWifiEnabled()) {                mScanner.forceScan();            }            return true;        case MENU_ID_ADD_NETWORK:            // 添加新的网络            if (mWifiManager.isWifiEnabled()) {                onAddNetworkPressed();            }            return true;        case MENU_ID_SAVED_NETWORK:            // 显示已经保存的 wifi 信息            // 如果是从设置中进入 则 执行 if 语句部分,如果是三方访问,则走else 部分            if (getActivity() instanceof SettingsActivity) {                ((SettingsActivity) getActivity()).startPreferencePanel(                        SavedAccessPointsWifiSettings.class.getCanonicalName(), null,                        R.string.wifi_saved_access_points_titlebar, null, this, 0);            } else {                startFragment(this, SavedAccessPointsWifiSettings.class.getCanonicalName(),                        R.string.wifi_saved_access_points_titlebar,                        -1 /* Do not request a result */, null);            }            return true;        case MENU_ID_ADVANCED:            if (getActivity() instanceof SettingsActivity) {                ((SettingsActivity) getActivity()).startPreferencePanel(                        AdvancedWifiSettings.class.getCanonicalName(), null,                        R.string.wifi_advanced_titlebar, null, this, 0);            } else {                startFragment(this, AdvancedWifiSettings.class.getCanonicalName(),                        R.string.wifi_advanced_titlebar, -1 /* Do not request a results */,                        null);            }            return true;    }    return super.onOptionsItemSelected(item);}

wifi界面的optionitem就是下边四项,下边我们一个一个来梳理流程:

1、添加wifi

2、获取已配对wifi

3、刷新列表

4、高级设置(Advanced)

1、添加WiFi

/* package */ void onAddNetworkPressed() {    // No exact access point is selected.    mSelectedAccessPoint = null;    showDialog(null, true);}
private void showDialog(AccessPoint accessPoint, boolean edit) {    // 如果 dialog 已经存在,则现将前 dialog 移除掉,然后再创建新的 dialog    // 这种写法也是我们需要借鉴的,代码小细节    if (mDialog != null) {        removeDialog(WIFI_DIALOG_ID);        mDialog = null;    }    // Save the access point and edit mode    mDlgAccessPoint = accessPoint; // null    mDlgEdit = edit; // true    // 调用了“父亲的父亲”(注意加了引号,点击看详细解释)的方法,这儿就是体现了继承的好处,慢慢体会    showDialog(WIFI_DIALOG_ID);// WIFI_DIALOG_ID = 1}

Settings\src\com\android\settings\SettingsPreferenceFragment.java

protected void showDialog(int dialogId) {    if (mDialogFragment != null) {        Log.e(TAG, "Old dialog fragment not null!");    }    mDialogFragment = new SettingsDialogFragment(this, dialogId);    mDialogFragment.show(getChildFragmentManager(), Integer.toString(dialogId));    Log.e("blb","----------------------------------------------------------------------------------"+getChildFragmentManager());}
 // 构造方法public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {    mDialogId = dialogId;    if (!(fragment instanceof Fragment)) {        throw new IllegalArgumentException("fragment argument must be an instance of "                + Fragment.class.getName());    }    mParentFragment = (Fragment) fragment;}

Settings\src\com\android\settings\wifi\WifiSettings.java
// 注意这里调用的是 WifiSettings.java 的方法,而不是 SettingsPreferenceFragment.java 的。

@Overridepublic Dialog onCreateDialog(int dialogId) {    switch (dialogId) {        case WIFI_DIALOG_ID:            AccessPoint ap = mDlgAccessPoint; // For manual launch            if (ap == null) { // For re-launch from saved state                if (mAccessPointSavedState != null) {                    ap = new AccessPoint(getActivity(), mAccessPointSavedState);                    // For repeated orientation changes                    mDlgAccessPoint = ap;                    // Reset the saved access point data                    mAccessPointSavedState = null;                }            }            // If it's null, fine, it's for Add Network            mSelectedAccessPoint = ap;            mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit);            return mDialog;  // 后边的代码暂时不需要,暂且省略    }    return super.onCreateDialog(dialogId);}

Settings\src\com\android\settings\wifi\WifiDialog.java

然后看一下布局:
这个 dialog 比较复杂,我们现在看到的只是一小部分,我们暂且只看这一个简单界面
Settings\res\layout\wifi_dialog.xml

这里写图片描述

<LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        style="@style/wifi_item" >    <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            style="@style/wifi_item_label"            android:text="@string/wifi_ssid"            android:textDirection="locale" />    <EditText android:id="@+id/ssid"            android:layout_width="match_parent"            android:layout_height="wrap_content"            style="@style/wifi_item_edit_content"            android:hint="@string/wifi_ssid_hint"            android:maxLength="32"            android:singleLine="true"            android:inputType="textNoSuggestions" /> </LinearLayout>

很明显,这个 EditText 就是我们上图中的输入框。

@Overridepublic void onClick(DialogInterface dialogInterface, int button) {    if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) {        forget();    } else if (button == WifiDialog.BUTTON_SUBMIT) {        if (mDialog != null) {            // 点击确定            submit(mDialog.getController());        }    }}

// 点击确定之后 保存 连接等

/* package */ void submit(WifiConfigController configController) {    final WifiConfiguration config = configController.getConfig();    if (config == null) {        if (mSelectedAccessPoint != null                && mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {            connect(mSelectedAccessPoint.networkId);        }    } else if (config.networkId != INVALID_NETWORK_ID) {        if (mSelectedAccessPoint != null) {            mWifiManager.save(config, mSaveListener);        }    } else {        if (configController.isEdit()) {            mWifiManager.save(config, mSaveListener);        } else {            connect(config);        }    }    if (mWifiManager.isWifiEnabled()) {        mScanner.resume();    }    updateAccessPoints();}

2、获取已配对的wifi

Settings\src\com\android\settings\wifi\SavedAccessPointsWifiSettings.java

在 onResume() 中,获取数据动态绘制

private void initPreferences() {    PreferenceScreen preferenceScreen = getPreferenceScreen();    final Context context = getActivity();    mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);    final List<AccessPoint> accessPoints = constructSavedAccessPoints(context, mWifiManager);    preferenceScreen.removeAll();    final int accessPointsSize = accessPoints.size();    //  类似于listView 的样子    for (int i = 0; i < accessPointsSize; ++i){        preferenceScreen.addPreference(accessPoints.get(i));    }    if(getPreferenceScreen().getPreferenceCount() < 1) {        Log.w(TAG, "Saved networks activity loaded, but there are no saved networks!");    }}

在 onPreferenceTreeClick() 方法中处理点击事件

@Overridepublic boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {    if (preference instanceof AccessPoint) {        // 弹出 dialog ,流程与 添加 wifi 一样        showDialog((AccessPoint) preference, false);        return true;    } else{        return super.onPreferenceTreeClick(screen, preference);    }}

点击每一行会弹出 dialog

这里写图片描述
处理dialog

@Overridepublic void onClick(DialogInterface dialogInterface, int button) {    // 如果点击了 forget ,则进行相应的处理操作    if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) {        mWifiManager.forget(mSelectedAccessPoint.networkId, null);        getPreferenceScreen().removePreference(mSelectedAccessPoint);        mSelectedAccessPoint = null;    }}

3、刷新列表

// 这一部分和WifiSettings 的内部类 Scanner相关,在上一篇博客中已经做了介绍,此处不再赘述

4、高级设置(Advanced)