Android-x86-6.0定製之路 - 以太網靜態iP功能

需求確立

描述

Android-x86-6.0 僅支持以太網動態獲取 IP(DHCP),現在客戶要求設置靜態 IP,即手動填寫 ip 地址、網關、子網掩碼、dns 服務器等信息。首先還是去 Settings.apk 查看是否支持此功能,很遺憾系統並不支持此功能,沒法還是要去修改源碼了。

確認

Settings.apk 添加以太網模塊,包括以下功能:

  • 啓用以太網、禁用以太網
  • 顯示網絡信息,包括 ip 地址、網關、子網掩碼、dns 服務器
  • 切換以太網模式,包括動態獲取 ip 和手動填寫 ip

UI 搭建

多語言資源

找到apps/Settings/res/values-zh-rCN/arrays.xml文件,按照補丁文件修改:

    <item msgid="6131821495505931173">"紅色"</item>
   </string-array>
     <!-- no translation found for usb_configuration_titles:0 (292902998500371970) -->
+  <string-array name="ethernet_ip_mode_entries">
+    <item>"動態獲取"</item>
+    <item>"靜態地址"</item>
+  </string-array>
 </resources>

找到apps/Settings/res/values-zh-rCN/strings.xml文件,按照補丁文件修改:

<resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="ethernet_settings_title">"以太網"</string>
+    <string name="ethernet_settings">"以太網"</string>
+    <string name="ethernet_enable">"已啓用"</string>
+    <string name="ethernet_disable">"已禁用"</string>
+    <string name="ethernet_ip_address">"IP地址"</string>
+    <string name="ethernet_netmask">"子網掩碼"</string>
+    <string name="ethernet_gateway">"網關"</string>
+    <string name="ethernet_dns1">"首選 DNS 服務器"</string>
+    <string name="ethernet_dns2">"備選 DNS 服務器"</string>
+    <string name="ethernet_loading_tips">"獲取中..."</string>
+    <string name="ethernet_ip_mode">"以太網IP模式"</string>
+    <string name="ethernet_ip_dhcp">"動態獲取"</string>
+    <string name="ethernet_ip_static">"靜態地址"</string>
+    <string name="ethernet_ip_static_cancel_button">"取消"</string>
+    <string name="ethernet_ip_static_connect_button">"連接"</string>
+    <string name="ethernet_ip_settings_invalid_ip">"請填寫正確的格式"</string>
+
     <string name="yes" msgid="4676390750360727396">"是"</string>
     <string name="no" msgid="6731231425810196216">"否"</string>
     <string name="create" msgid="3578857613172647409">"創建"</string>

找到packages/apps/Settings/res/values/arrays.xml文件,按照補丁文件修改:

       <item>0</item>
     </string-array>

+    <string-array name="ethernet_ip_mode_entries">
+        <item>dhcp</item>
+        <item>static</item>
+    </string-array>
+
+    <string-array name="ethernet_ip_mode_values" translatable="false">
+        <item>dhcp</item>
+        <item>manual</item>
+    </string-array>
 </resources>

找到packages/apps/Settings/res/values/strings.xml文件,按照補丁文件修改:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="ethernet_settings_title">"Ethernet"</string>
+    <string name="ethernet_settings">"Ethernet"</string>
+    <string name="ethernet_enable">"ethernet is enable"</string>
+    <string name="ethernet_disable">"ethernet is disable"</string>
+    <string name="ethernet_ip_address">"IP address"</string>
+    <string name="ethernet_netmask">"Netmask"</string>
+    <string name="ethernet_gateway">"Gateway"</string>
+    <string name="ethernet_dns1">"DNS server1"</string>
+    <string name="ethernet_dns2">"DNS server2"</string>
+    <string name="ethernet_loading_tips">"loading..."</string>
+    <string name="ethernet_ip_mode">"Ethernet ip mode"</string>
+    <string name="ethernet_ip_dhcp">"dpcp"</string>
+    <string name="ethernet_ip_static">"static"</string>
+    <string name="ethernet_ip_static_cancel_button">"cancel"</string>
+    <string name="ethernet_ip_static_connect_button">"connect"</string>
+    <string name="ethernet_ip_settings_invalid_ip">"Please fill in the correct format."</string>
+
     <!-- Strings for Dialog yes button -->
     <string name="yes">"Yes"</string>
     <!-- Strings for Dialog no button -->

以上修改,就是以太網模塊的所用到的多語言資源

以太網模塊入口

找到packages/apps/Settings/res/xml/wireless_settings.xml文件,按照補丁修改代碼:

     <PreferenceScreen
+        android:fragment="com.android.settings.ethernet.EthernetSettings"
+        android:key="ethernet_settings"
+        android:title="@string/ethernet_settings_title" />
+
+    <PreferenceScreen
         android:key="mobile_network_settings"
         android:title="@string/network_settings_title"
         settings:keywords="@string/keywords_more_mobile_networks"

如下圖所示:

在這裏插入圖片描述

以太網模塊界面

找到packages/apps/Settings/res/xml/文件夾,添加ethernet_settings.xml佈局文件,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<!--$_FOR_ROCKCHIP_RBOX_$--><!--$_rbox_$_modify_$_chenzhi_20120309: add for ethernet--><!-- Copyright (C) 2008 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="@string/ethernet_settings">

    <SwitchPreference
        android:key="ethernet_settings"
        android:persistent="false"
        android:summary="@string/ethernet_enable"
        android:title="@string/ethernet_settings" />

    <Preference
        android:key="ethernet_ip_address"
        android:title="@string/ethernet_ip_address"
        android:summary="0.0.0.0"/>

    <Preference
        android:key="ethernet_netmask"
        android:title="@string/ethernet_netmask"
        android:summary="0.0.0.0"/>

    <Preference
        android:key="ethernet_gateway"
        android:title="@string/ethernet_gateway"
        android:summary="0.0.0.0"/>

    <Preference
        android:key="ethernet_dns1"
        android:title="@string/ethernet_dns1"
        android:summary="0.0.0.0"/>

    <Preference
        android:key="ethernet_dns2"
        android:title="@string/ethernet_dns2"
        android:summary="0.0.0.0"/>

    <ListPreference
        android:entries="@array/ethernet_ip_mode_entries"
        android:entryValues="@array/ethernet_ip_mode_values"
        android:key="ethernet_ip_mode"
        android:persistent="false"
        android:summary="@string/ethernet_ip_dhcp"
        android:title="@string/ethernet_ip_mode" />

</PreferenceScreen>

如下圖所示:

在這裏插入圖片描述

區域一是啓用、禁用以太網,區域二是網絡相關信息,區域三是以太網模式切換

以太網手動設置 IP 彈窗

找到packages/apps/Settings/res/layout/文件夾,創建ethernet_static_ip_dialog.xml佈局文件,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingTop="12dp"
        android:paddingRight="20dp"
        android:paddingBottom="12dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="@string/ethernet_ip_address" />

        <EditText
            android:id="@+id/ethernet_ip_address"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="192.168.192.57" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="@string/ethernet_gateway" />

        <EditText
            android:id="@+id/ethernet_gateway"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="192.168.192.1" />


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="@string/ethernet_netmask" />

        <EditText
            android:id="@+id/ethernet_netmask"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="1dp"
            android:hint="255.255.255.0" />


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="@string/ethernet_dns1" />

        <EditText
            android:id="@+id/ethernet_dns1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="192.168.192.1" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:text="@string/ethernet_dns2" />

        <EditText
            android:id="@+id/ethernet_dns2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="114.114.114.114" />

    </LinearLayout>
</ScrollView>

如下圖所示:

在這裏插入圖片描述

功能實現

啓用、禁用以太網功能

找到frameworks/base/core/java/android/net/EthernetManager.java文件,添加setEthernetEnabled()方法,修改如下:

+    void setEthernetEnabled(boolean enabled);

這裏setEthernetEnabled()方法調用的是EthernetServiceImpl.java裏的方法,使用了 aidl 技術,具體修改如下:

找到frameworks/base/core/java/android/net/IEthernetManager.aidl文件,聲明以下方法:

+    public void setEthernetEnabled(boolean enabled) {
+        try {
+            mService.setEthernetEnabled(enabled);
+        } catch (NullPointerException | RemoteException e) {
+        }
+    }

找到frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java文件,實現setEthernetEnabled()方法

+    @Override
+    public void reconnect() {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                mTracker.start(mContext, mHandler);
+                mStarted.set(true);
+                Looper.loop();
+            }
+        }).start();
+    }
+
+    @Override
+    public void disconnect() {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                mTracker.stop();
+                mStarted.set(false);
+                Looper.loop();
+            }
+        }).start();
+    }
+    @Override
+    public void setEthernetEnabled(boolean enabled) {
+        if (enabled) {
+            reconnect();
+            Settings.Global.putInt(mContext.getContentResolver(), ETHERNET_ENABLED, 1);
+        } else {
+            disconnect();
+            Settings.Global.putInt(mContext.getContentResolver(), ETHERNET_ENABLED, 0);
+        }
+    }

找到packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java文件,當啓用、禁用以太網時調用EthernetManager中的setEthernetEnabled()方法

+    @Override
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        if (preference == mEthernetSettingsPreference) {
+            boolean value = (Boolean) objValue;
+            mEthernetManager.setEthernetEnabled(value);
+            mEthernetSettingsPreference.setChecked(value);
+            mEthernetSettingsPreference.setSummary(value ? getResources().getString(R.string.ethernet_enable) : getResources().getString(R.string.ethernet_disable));
+            mEthernetModePreference.setEnabled(mEthernetManager.isEthernetEnabled());
+            refreshEthernetInfo(1500);
+        }

獲取以太網信息功能

找到frameworks/base/core/java/android/net/EthernetManager.java文件,添加getEthernetInfo()方法,修改如下:

+    public EthernetInfo getEthernetInfo() {
+        try {
+            return mService.getEthernetInfo();
+        } catch (NullPointerException | RemoteException e) {
+            return null;
+        }
+    }

這裏getEthernetInfo()方法調用的是EthernetServiceImpl.java裏的方法,使用了 aidl 技術,具體修改如下:

找到frameworks/base/core/java/android/net/IEthernetManager.aidl文件,聲明以下方法:

+    EthernetInfo getEthernetInfo();

找到frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java文件,實現getEthernetInfo()方法

+    public EthernetInfo getEthernetInfo() {
+        String ipAddress = "0.0.0.0";
+        String gateway = "0.0.0.0";
+        String netmask = "0.0.0.0";
+        String dns1 = "0.0.0.0";
+        String dns2 = "0.0.0.0";
+
+        Pattern pattern = Pattern.compile("\\d+.\\d+.\\d+.\\d+");
+        Matcher matcher;
+
+        LinkProperties linkProperties = mTracker.getEthernetInfo();
+        Log.e(TAG, "linkProperties: " + linkProperties.toString());
+        List<LinkAddress> ipList = linkProperties.getLinkAddresses();
+        if (ipList != null && ipList.size() > 0) {
+            String linkAddresses = ipList.toString();
+            Log.e(TAG, "linkAddresses: " + linkAddresses);
+            if (!TextUtils.isEmpty(linkAddresses) && linkAddresses.length() > 1) {
+                ipAddress = linkAddresses.substring(1, linkAddresses.lastIndexOf("/"));
+                matcher = pattern.matcher(ipAddress);
+                while (matcher.find()) {
+                    if (!TextUtils.isEmpty(matcher.group())) {
+                        ipAddress = matcher.group();
+                    }
+                }
+            }
+
+            Log.e(TAG, "netmask: " + ipList.get(0).getPrefixLength());
+            if (ipList.get(0) != null) {
+                netmask = calcMaskByPrefixLength(ipList.get(0).getPrefixLength());
+            }
+        }
+
+        List<RouteInfo> routeList = linkProperties.getRoutes();
+        if (routeList != null && routeList.size() > 0) {
+            String routes = routeList.toString();
+            Log.e(TAG, "routes: " + routes);
+            matcher = pattern.matcher(routes);
+            while (matcher.find()) {
+                if (!TextUtils.isEmpty(matcher.group())) {
+                    gateway = matcher.group();
+                }
+            }
+        }
+
+        List<InetAddress> dnsList= linkProperties.getDnsServers();
+        if (dnsList != null && dnsList.size() > 0) {
+            String dnsServers = dnsList.toString();
+            Log.e(TAG, "dnsServers: " + dnsServers);
+            matcher = pattern.matcher(dnsServers);
+            int i = 0;
+            while (matcher.find()) {
+                i++;
+                if (!TextUtils.isEmpty(matcher.group())) {
+                    if (i == 1) {
+                        dns1 = matcher.group();
+                    } else if (i == 2) {
+                        dns2 = matcher.group();
+                    }
+                }
+            }
+        }
+
+        EthernetInfo info = new EthernetInfo();
+        info.setIpAddress(ipAddress);
+        info.setGateway(gateway);
+        info.setNetmask(netmask);
+        info.setDns1(dns1);
+        info.setDns2(dns2);
+        return info;
+    }
+
+    public static String calcMaskByPrefixLength(int length) {
+
+        int mask = 0xffffffff << (32 - length);
+        int partsNum = 4;
+        int bitsOfPart = 8;
+        int maskParts[] = new int[partsNum];
+        int selector = 0x000000ff;
+
+        for (int i = 0; i < maskParts.length; i++) {
+            int pos = maskParts.length - 1 - i;
+            maskParts[pos] = (mask >> (i * bitsOfPart)) & selector;
+        }
+
+        String result = "";
+        result = result + maskParts[0];
+        for (int i = 1; i < maskParts.length; i++) {
+            result = result + "." + maskParts[i];
+        }
+        return result;
+    }
+

這裏調用了EthernetNetworkFactorygetEthernetInfo()方法,找到frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java文件,添加以下方法:

+    public LinkProperties getEthernetInfo() {
+        return mLinkProperties;
+    }

找到packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java文件,當進入以太網模塊時調用EthernetManager中的getEthernetInfo()方法

+    private void refreshEthernetInfo(long delay) {
+        if (mEthernetSettingsPreference.isChecked()) {
+            mEthernetIPAdressPreference.setSummary(R.string.ethernet_loading_tips);
+            mEthernetGatewayPreference.setSummary(R.string.ethernet_loading_tips);
+            mEthernetNetmaskPreference.setSummary(R.string.ethernet_loading_tips);
+            mEthernetDNS1Preference.setSummary(R.string.ethernet_loading_tips);
+            mEthernetDNS2Preference.setSummary(R.string.ethernet_loading_tips);
+            new Handler().postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    EthernetInfo info = mEthernetManager.getEthernetInfo();
+                    mEthernetIPAdressPreference.setSummary(info.getIpAddress());
+                    mEthernetGatewayPreference.setSummary(info.getGateway());
+                    mEthernetNetmaskPreference.setSummary(info.getNetmask());
+                    mEthernetDNS1Preference.setSummary(info.getDns1());
+                    mEthernetDNS2Preference.setSummary(info.getDns2());
+                }
+            }, delay);
+         } else {
+            mEthernetIPAdressPreference.setSummary("0.0.0.0");
+            mEthernetGatewayPreference.setSummary("0.0.0.0");
+            mEthernetNetmaskPreference.setSummary("0.0.0.0");
+            mEthernetDNS1Preference.setSummary("0.0.0.0");
+            mEthernetDNS2Preference.setSummary("0.0.0.0");
+        }
+    }

以太網模式切換功能

找到frameworks/base/core/java/android/net/EthernetManager.java文件,添加setEthernetIPMode()方法,修改如下:

+    public void setEthernetIPMode(String mode, EthernetInfo info) {
+        try {
+            mService.setEthernetIPMode(mode, info);
+        } catch (NullPointerException | RemoteException e) {
+        }
+    }

這裏setEthernetIPMode()方法調用的是EthernetServiceImpl.java裏的方法,使用了 aidl 技術,具體修改如下:

找到frameworks/base/core/java/android/net/IEthernetManager.aidl文件,聲明以下方法:

+    void setEthernetIPMode(String mode, in EthernetInfo info);

找到frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java文件,實現setEthernetIPMode()方法

+    @Override
+    public void setEthernetIPMode(String mode, EthernetInfo info) {
+        Log.e(TAG, "String mode: " + mode + "mStarted.get(): " + mStarted.get());
+        mTracker.changeInterfaceState(false);
+        ContentResolver contentResolver = mContext.getContentResolver();
+        IpConfiguration ipConfiguration;
+        if (EthernetManager.ETHERNET_IP_MODE_DHCP.equals(mode)) {
+            ipConfiguration = new IpConfiguration(IpConfiguration.IpAssignment.DHCP, IpConfiguration.ProxySettings.NONE, null, null);
+            Settings.Global.putString(contentResolver, ETHERNET_IP_MODE, EthernetManager.ETHERNET_IP_MODE_DHCP);
+
+        } else if (EthernetManager.ETHERNET_IP_MODE_STATIC.equals(mode)) {
+            String ipAddress = info.getIpAddress();
+            String gateWay = info.getGateway();
+            String netMask = info.getNetmask();
+            String dns1 = info.getDns1();
+            String dns2 = info.getDns2();
+
+            StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+            try {
+                staticIpConfiguration.domains = netMask;
+                staticIpConfiguration.gateway = InetAddress.getByName(gateWay);
+                staticIpConfiguration.ipAddress = new LinkAddress(InetAddress.getByName(ipAddress), 24);
+                staticIpConfiguration.dnsServers.add(InetAddress.getByName(dns1));
+                staticIpConfiguration.dnsServers.add(InetAddress.getByName(dns2));
+            } catch (UnknownHostException e) {
+                e.printStackTrace();
+            }
+            ipConfiguration = new IpConfiguration(IpConfiguration.IpAssignment.STATIC, IpConfiguration.ProxySettings.NONE, staticIpConfiguration, null);
+
+            Settings.Global.putString(contentResolver, ETHERNET_STATIC_IP, ipAddress);
+            Settings.Global.putString(contentResolver, ETHERNET_STATIC_GATEWAY, gateWay);
+            Settings.Global.putString(contentResolver, ETHERNET_STATIC_NETMASK, netMask);
+            Settings.Global.putString(contentResolver, ETHERNET_STATIC_DNS1, dns1);
+            Settings.Global.putString(contentResolver, ETHERNET_STATIC_DNS2, dns2);
+            Settings.Global.putString(contentResolver, ETHERNET_IP_MODE, EthernetManager.ETHERNET_IP_MODE_STATIC);
+        } else {
+            ipConfiguration = mEthernetConfigStore.readIpAndProxyConfigurations();
+        }
+        setConfiguration(ipConfiguration);
+    }

這裏調用了EthernetNetworkFactorychangeInterfaceState()方法,找到frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java文件,添加以下方法:

+    public void changeInterfaceState(boolean up) {
+        if (!TextUtils.isEmpty(mIface)) {
+            updateInterfaceState(mIface, up);
+        }
+    }

找到packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java文件,當切換太網模式時調用EthernetManager中的setEthernetIPMode()方法

if (KEY_ETHERNET_IP_MODE.equals(preference.getKey())) {
+            try {
+                String value = ((String) objValue);
+                if (value.equals(EthernetManager.ETHERNET_IP_MODE_STATIC)) {
+                    ViewGroup mParent = (ViewGroup) mDialogView.getParent();
+                    if (mParent != null) {
+                        mParent.removeAllViews();
+                    }
+                    mDialog = mBuilder.show();
+                    setDialogCanConnect();
+                } else if (value.equals(EthernetManager.ETHERNET_IP_MODE_DHCP)) {
+                    mEthernetManager.setEthernetIPMode(EthernetManager.ETHERNET_IP_MODE_DHCP, null);
+                    mEthernetModePreference.setValue(EthernetManager.ETHERNET_IP_MODE_DHCP);
+                    mEthernetModePreference.setSummary(getResources().getString(R.string.ethernet_ip_dhcp));
+                    refreshEthernetInfo(1500);
+                }
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "could not persist screen timeout setting", e);
+            }


+    private void keepDialog(DialogInterface mDialogLongInterface) {
+        try {
+            Field field = mDialogLongInterface.getClass().getSuperclass().getDeclaredField("mShowing");
+            field.setAccessible(true);//將mShowing設置爲false表示對話框已關閉
+            field.set(mDialogLongInterface, false);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    private void closeDialog(DialogInterface mDialogInterface) {
+        try {
+            Field field = mDialogInterface.getClass().getSuperclass().getDeclaredField("mShowing");
+            field.setAccessible(true);
+            field.set(mDialogInterface, true);
+            mDialogInterface.dismiss();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    private void setDialogCanConnect() {
+        if (mEthernetIPAdressEditText != null) {
+            ipAddress = mEthernetIPAdressEditText.getText().toString();
+        }
+        if (mEthernetGatewayEditText != null) {
+            gateWay = mEthernetGatewayEditText.getText().toString();
+        }
+        if (mEthernetNetmaskEditText != null) {
+            netMask = mEthernetNetmaskEditText.getText().toString();
+        }
+        if (mEthernetDNS1EditText != null) {
+            dns1 = mEthernetDNS1EditText.getText().toString();
+        }
+        if (mEthernetDNS2EditText != null) {
+            dns2 = mEthernetDNS2EditText.getText().toString();
+        }
+        if (!TextUtils.isEmpty(ipAddress) && !TextUtils.isEmpty(gateWay) && !TextUtils.isEmpty(netMask)
+                && (!TextUtils.isEmpty(dns1) || !TextUtils.isEmpty(dns2))) {
+            if (mDialog != null)
+                mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
+        } else {
+            if (mDialog != null)
+                mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
+        }
+    }
+
+    private void connect(DialogInterface dialog) {
+        ipAddress = mEthernetIPAdressEditText.getText().toString();
+        if (TextUtils.isEmpty(ipAddress) || !isValidIpAddress(ipAddress)) {
+            Toast.makeText(getActivity(), R.string.ethernet_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
+            keepDialog(dialog);
+            return;
+        }
+        gateWay = mEthernetGatewayEditText.getText().toString();
+        if (TextUtils.isEmpty(gateWay) || !isValidIpAddress(gateWay)) {
+            Toast.makeText(getActivity(), R.string.ethernet_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
+            keepDialog(dialog);
+            return;
+        }
+        netMask = mEthernetNetmaskEditText.getText().toString();
+        if (TextUtils.isEmpty(netMask) || !isValidIpAddress(netMask)) {
+            Toast.makeText(getActivity(), R.string.ethernet_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
+            keepDialog(dialog);
+            return;
+        }
+        dns1 = mEthernetDNS1EditText.getText().toString();
+        if (TextUtils.isEmpty(dns1) || !isValidIpAddress(dns1)) {
+            Toast.makeText(getActivity(), R.string.ethernet_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
+            keepDialog(dialog);
+            return;
+        }
+        dns2 = mEthernetDNS2EditText.getText().toString();
+        if (!TextUtils.isEmpty(dns2) && !isValidIpAddress(dns2)) {
+            Toast.makeText(getActivity(), R.string.ethernet_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
+            keepDialog(dialog);
+            return;
+        }
+
+        EthernetInfo info = new EthernetInfo();
+        info.setIpAddress(ipAddress);
+        info.setGateway(gateWay);
+        info.setNetmask(netMask);
+        info.setDns1(dns1);
+        info.setDns2(dns2);
+
+        mEthernetManager.setEthernetIPMode(EthernetManager.ETHERNET_IP_MODE_STATIC, info);
+        mEthernetModePreference.setSummary(getResources().getString(R.string.ethernet_ip_static));
+        mEthernetModePreference.setValue(EthernetManager.ETHERNET_IP_MODE_STATIC);
+
+        closeDialog(dialog);
+
+        refreshEthernetInfo(1500);
+    }
+
+    private boolean isValidIpAddress(String value) {
+
+        int start = 0;
+        int end = value.indexOf('.');
+        int numBlocks = 0;
+
+        while (start < value.length()) {
+
+            if (-1 == end) {
+                end = value.length();
+            }
+
+            try {
+                int block = Integer.parseInt(value.substring(start, end));
+                if ((block > 255) || (block < 0)) {
+                    Log.e(TAG, "isValidIpAddress() : invalid 'block', block = " + block);
+                    return false;
+                }
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "isValidIpAddress() : e = " + e);
+                return false;
+            }
+
+            numBlocks++;
+
+            start = end + 1;
+            end = value.indexOf('.', start);
+        }
+
+        return numBlocks == 4;
+    }
+}

小結

在這裏插入圖片描述

以上修改是以太網模塊主要功能的實現,時間匆忙沒有具體分析,就簡單記錄下。

功能實現不易,參考了許多資料:

Android 6.0 Ethernet 流程分析記錄

Android 以太網/有線網 Ethernet 功能開發

Android 8.1 增加以太網設置功能

這裏提供補丁下載android-6.0 以太網補丁,有興趣的話可以去看看

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章