Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android SoftAp支持 (二)

Android SoftAp支持 (二)

編輯:關於Android編程

SoftAp界面開啟流程(讓你的手機支持SoftAp功能)

市面上大多數手機支持SoftAp功能,有少數手機沒有打開SoftAp的界面設置,所以無法開啟此功能(當然有些山寨手機平板打開了此設置功能也不一定能使用SoftAP,因為此功能需要WIFI芯片與WIFI驅動的支持才能真正意義上實現)。

深入代碼介紹一下手機 Portable Wi-Fi hostpot 界面開啟條件

上文《Android SoftAp支持 (一)》提到當勾選Portable Wi-Fi hostpot,系統的Setting程序TetherSettings.java將響應此動作。tether這個詞意思是拴繩,拴住的意思,理解起來有點晦澀,這裡我的理解是分享的意思,比如 WIFI_TETHERING(用WIFI分享網路), USB_TETHERING(用USB分享網絡)……

那麼這些網絡分享如何滿足什麼條件才開啟呢?疑問

從WirelessSettings開始說

在packages/apps/Settings/src/com/android/settings/WirelessSettings.java 的onCreate方法中會去檢測系統是否Tether

       // Disable Tethering if it's not allowed or if it's a wifi-only device
        ConnectivityManager cm =       
                (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (isSecondaryUser || !cm.isTetheringSupported()) {
            getPreferenceScreen().removePreference(findPreference(KEY_TETHER_SETTINGS));
        } else {
            Preference p = findPreference(KEY_TETHER_SETTINGS);
            p.setTitle(Utils.getTetheringLabel(cm));
        }
        protectByRestrictions(KEY_TETHER_SETTINGS);

1)調用獲取ConnectivityManager實例對象,並調用isTetheringSupported方法來檢測是否支持Tether

2)調用getTetheringLabel查看支持哪些網絡共享方式,並顯示到界面

先看isTetheringSupported方法

    public boolean isTetheringSupported() {
        try {
            return mService.isTetheringSupported();
        } catch (RemoteException e) {  
            return false;
            ...

它調用了frameworks/base/services/java/com/android/server/ConnectivityService.java 的isTetheringSupported 方法

    public boolean isTetheringSupported() {
        enforceTetherAccessPermission();
        int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
        boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.TETHER_SUPPORTED, defaultVal) != 0);
        return tetherEnabledInSettings && ((mTethering.getTetherableUsbRegexs().length != 0 ||
                mTethering.getTetherableWifiRegexs().length != 0 ||
                mTethering.getTetherableBluetoothRegexs().length != 0) &&
                mTethering.getUpstreamIfaceTypes().length != 0);
    }  
讀取系統ro.tether.denied的屬性,返回true則表示關閉tether功能,返回false表示打開tether功能。(有些設備不能顯示portable wifi 就是因為此屬性返回true,這裡需要修改設置為false)

之後會檢測是否有配置文件配置了tether,有則使用設置的值,沒有查詢到配置這使用查詢ro.tether.denied屬性的默認值。

這裡我們假設得到的tetherEnableInSettings為ture,也不意味著就能正確打開Portable Wi-Fi hostpot 界面。因為還需要檢測是否支持WIFI網絡共享配置

mTethering.getTetherableWifiRegexs().length!=0 檢測是否支持網絡共享配置,這裡Android4.4 與之前的版本有一定區別,但總體不變,大家可以參考其他代碼做一些變通

getTetherableWifiRegexs()方法

frameworks/base/services/java/com/android/server/connectivity/Tethering.java
return mTetherableWifiRegexs;
直接返回了一個變量。 此變量在frameworks/base/services/java/com/android/server/connectivity/Tethering.java

updateConfiguration()方法中賦值

mTetherableWifiRegexs = tetherableWifiRegexs;
而 tetherableWifiRegexs變量賦值也在此方法中

String[] tetherableWifiRegexs = mContext.getResources().getStringArray(
            com.android.internal.R.array.config_tether_wifi_regexs);

這裡的config_tether_wifi_regexs數組由配置文件生成

配置文件config.xml

frameworks/base/core/res/res/values/config.xml

    
    
    

這裡看到需要在此默認的config.xml中的 name="config_tether_wifi_regexs" 子標簽下添加用作softap的接口(一般為wlan0 或者eth0 視你的WIFI驅動程序而定)

修改後的標簽:

    
    
    "wlan0"
    

OK 此處mTethering.getTetherableWifiRegexs().length!=0 返回true, 整個isTetheringSupported 返回真

p.setTitle(Utils.getTetheringLabel(cm))

packages/apps/Settings/src/com/android/settings/WirelessSettings.java 調用到else中的

p.setTitle(Utils.getTetheringLabel(cm));函數

首先看packages/apps/Settings/src/com/android/settings/Utils.java 下的

getTetheringLabel 方法

/**
 * Return string resource that best describes combination of tethering
 * options available on this device.
 */
    
public static int getTetheringLabel(ConnectivityManager cm) {
    String[] usbRegexs = cm.getTetherableUsbRegexs();
    String[] wifiRegexs = cm.getTetherableWifiRegexs();
    String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();

    boolean usbAvailable = usbRegexs.length != 0;
    boolean wifiAvailable = wifiRegexs.length != 0;
    boolean bluetoothAvailable = bluetoothRegexs.length != 0;

    if (wifiAvailable && usbAvailable && bluetoothAvailable) {
        return R.string.tether_settings_title_all;
    } else if (wifiAvailable && usbAvailable) {
        return R.string.tether_settings_title_all;
    } else if (wifiAvailable && bluetoothAvailable) {
        return R.string.tether_settings_title_all;
    } else if (wifiAvailable) {
        return R.string.tether_settings_title_wifi;
    } else if (usbAvailable && bluetoothAvailable) {
        ...
}

這裡 cm.getTetherableWifiRegexs();最終會調用到frameworks/base/services/java/com/android/server/connectivity/Tethering.java的 getTetherableWifiRegexs()方法(與上相同,不再贅述)


總結

講到這裡相信有些雲裡霧裡了。

總結一下腰打開Portable Wi-Fi hostpot界面條件

需要確認:

1) 首先需要確認你的設備的WIFI芯片以及驅動是否支持softap

2) ro.tether.denied系統屬性被設置為false(或者配置”tether_supported“標簽並置1)

3) 在frameworks/base/core/res/res/values/config.xml name="config_tether_wifi_regexs"標簽下 添加做softap的接口

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved