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

wifi系列博客地址:

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

正文:

optionitem 是什么?
看图:
Wifi源码学习(Android5.1)之wifi optionItem_第1张图片
闲话少说,直接上代码:
首先是简单的optionitem 添加的方法。

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

@Override
public 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();
}

处理他们点击事件的地方

@Override
public 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 的。

@Override
public 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

Wifi源码学习(Android5.1)之wifi optionItem_第2张图片

"match_parent"
        android:layout_height="wrap_content"
        style="@style/wifi_item" >
    "wrap_content"
            android:layout_height="wrap_content"
            style="@style/wifi_item_label"
            android:text="@string/wifi_ssid"
            android:textDirection="locale" />

    "@+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 就是我们上图中的输入框。

@Override
public 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 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() 方法中处理点击事件

@Override
public 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

Wifi源码学习(Android5.1)之wifi optionItem_第3张图片
处理dialog

@Override
public 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)

你可能感兴趣的:(android,源码,wi-fi,optionitem,android系统开发)