1. 程式人生 > >android5.1 增加ethernet設定(DHCP與Static ip)

android5.1 增加ethernet設定(DHCP與Static ip)

android5.0以上的系統自帶了ethernet service,預設開機就會啟動,預設ip獲取方式是動態分配,這裡記錄下android5.1增加ethernet設定介面設定ip獲取方式及開關.

首先是介面方面要修改Settings增加ethernet設定介面

修改檔案packages/apps/Settings/res/xml/dashboard_categories.xml在藍芽後面加上如下程式碼

<!-- ethernet add by hclydao-->
		<dashboard-tile
		    android:id="@+id/ethernet_settings"
		    android:icon="@drawable/ic_settings_dock"
		    android:fragment="com.android.settings.ethernet.EthernetSettings"
		    android:title="@string/ethernet_settings" />

其中的EthernetSettings後面進行說明,然後增加string修改檔案packages/apps/Settings/res/values/strings.xml

增加如下內容

<!-- Eth settings title add by hclydao-->
    <string name="ethernet_settings">Ethernet</string>
    <!-- Ethernet configuration dialog add by hcldyao-->
    <string name="eth_config_title">Configure Ethernet device</string>
    <string name="eth_setting">Ethernet</string>
    <string name="eth_dev_list">Ethernet Devices:</string>
    <string name="eth_con_type">Connection Type</string>
    <string name="eth_con_type_dhcp">DHCP</string>
    <string name="eth_con_type_manual">Static IP</string>
    <string name="eth_dns">DNS address</string>
    <string name="eth_gw">Gateway address</string>
    <string name="eth_ipaddr">IP address</string>
    <string name="eth_quick_toggle_title">Ethernet</string>
    <string name="eth_quick_toggle_summary">Turn on Ethernet</string>
    <string name="eth_conf_perf_title">Ethernet configuration</string>
    <string name="eth_conf_summary">Configure Ethernet devices</string>
    <string name="eth_mask">Netmask</string>
    <string name="eth_toggle_summary_off">Turn off Ethernet</string>
    <string name="eth_toggle_summary_on">Turn on Ethernet</string>
    <string name="eth_settings_error">Failed to set: Please enter the valid characters 0~255</string>
	<string name="eth_settings_empty">can\'t be empty</string>
    <!-- Label for the network prefix of the network [CHAR LIMIT=25]-->
    <string name="eth_network_prefix_length">Network prefix length</string>
這是我修改完成後所要加的所有的string

接著修改檔案packages/apps/Settings/src/com/android/settings/SettingsActivity.java增加

import com.android.settings.ethernet.EthernetSettings;//add by hclydao

然後在R.id.bluetooth_settings,後增加

R.id.ethernet_settings,//add by hclydao

在BluetoothSettings.class.getName(),後增加

EthernetSettings.class.getName(),//add by hclydao

接著修改檔案packages/apps/Settings/src/com/android/settings/Settings.java

在public static class WirelessSettingsActivity extends SettingsActivity { /* empty */ }後增加

public static class EthernetSettingsActivity extends SettingsActivity { /* empty */ } //add by hclydao

這裡面應該是宣告與繼承關係

接著修改
packages/apps/Settings/AndroidManifest.xml

 <activity android:name="Settings$EthernetSettingsActivity"
                android:label="@string/ethernet_settings"
                android:taskAffinity="">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="com.android.settings.ETHERNET_SETTINGS" />
                <action android:name="android.settings.ETHERNET_SETTINGS" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.VOICE_LAUNCH" />
                <category android:name="com.android.settings.SHORTCUT" />
            </intent-filter>
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="com.android.settings.ethernet.EthernetSettings" />
            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
                android:resource="@id/ethernet_settings" />
            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                android:value="true" />
        </activity>
這三個檔案按照wifi的程式碼改就行了。
然後增加點選進去後的佈局檔案,增加
packages/apps/Settings/res/xml/ethernet_settings.xml

內容如下

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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"
        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
        <Preference
            android:title="@string/eth_conf_perf_title"
            android:summary="@string/eth_conf_summary"
            android:key="ETHERNET_CONFIG"
            android:persistent="false" />
</PreferenceScreen>
然後增加了packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java
這是我最終的程式碼,這裡就不貼上來了,下面我會給下載地址
編譯後效果應該是這個樣子的:


點選進去後會有一個Dialog佈局,需要增加檔案packages/apps/Settings/res/layout/eth_configure.xml

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

    <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="8dip"
            android:orientation="vertical">

            <LinearLayout
                android:id="@+id/table"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical">
            </LinearLayout>

        <!-- Connection type -->
	<TextView android:id="@+id/eth_con_type"
                style="?android:attr/textAppearanceSmall"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dip"
                android:text="@string/eth_con_type" />
        <RadioGroup android:id="@+id/con_type"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                >
                <RadioButton android:id="@+id/dhcp_radio"
			style="?android:attr/textAppearanceSmall"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content"
			android:text="@string/eth_con_type_dhcp"
                ></RadioButton>
                <RadioButton android:id="@+id/manual_radio"
			style="?android:attr/textAppearanceSmall"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content"
			android:text="@string/eth_con_type_manual"
                ></RadioButton>
        </RadioGroup>

        <!-- IP address -->
        <LinearLayout android:id="@+id/enterprise_wrapper"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="0dip"
            android:orientation="vertical">
                <TextView android:id="@+id/ipaddr_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_ipaddr" />
                <EditText android:id="@+id/ipaddr_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
<!--
                <TextView android:id="@+id/netmask_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_mask" />
                <EditText android:id="@+id/netmask_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
-->
                <TextView android:id="@+id/prefix_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_network_prefix_length" />
                <EditText android:id="@+id/prefix_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />

                <TextView android:id="@+id/dns_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_dns" />
                <EditText android:id="@+id/eth_dns_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
                <TextView android:id="@+id/gw_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_gw" />
                <EditText android:id="@+id/eth_gw_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
        </LinearLayout>

    </LinearLayout>

</ScrollView>

裡面包括了dhcp與static ip的選擇,以及static ip的設定

然後增加Settings/src/com/android/settings/ethernet/EthernetDialog.java
以及packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java
這些是具體的實現,最後我會給下載地址

最後出來的效果應該是這樣的:

配製介面


增加這些修改和檔案後,基本上就可以進行動態設定了。但是設定的關於ethernet的開關是沒有作用的,所以這裡增加開關的控制
修改檔案frameworks/base/core/java/android/provider/Settings.java
在Settings資料庫中增加一個ethernet的控制

public static final String ETHERNET_ON = "ethernet_on";//add by hclydao
增加這個以後需要更新api才能編譯過,增加這個後在ethernet-service和Settings中ethernet中進行讀寫操作
修改frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java檔案

在mHandler = new Handler(handlerThread.getLooper());後增加如下程式碼

int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao
if(enable != EthernetManager.ETH_STATE_ENABLED) {
    Log.i(TAG, "Ethernet is not enable");
    return;
}

如果沒有開啟就直接返回,不啟動Service後繼的操作,然後增加兩個介面

	class TstartThread extends Thread {
		public void run() {
			Looper.prepare();
			mTracker.start(mContext, mHandler);
			mStarted.set(true);
			Looper.loop();
		}
	}

	public void Trackstart() { //add by hclydao
		new TstartThread().start();
	}

	public void Trackstop() {
		Log.i(TAG, "Stop Ethernet service");
		Thread tstopthread = new Thread(new Runnable() {
			public void run() {
				Looper.prepare();
				mTracker.stop();
				mStarted.set(false);
				Looper.loop();
			}
		});
		tstopthread.start();
	}

同時要修改frameworks/base/core/java/android/net/EthernetManager.java檔案增加

    public static final int ETH_STATE_UNKNOWN = 0;
    public static final int ETH_STATE_DISABLED = 1;
    public static final int ETH_STATE_ENABLED = 2;

    public void start() {
        try {
            mService.Trackstart();
        } catch (NullPointerException | RemoteException e) {
        }
    }

    public void stop() {
        try {
            mService.Trackstop();
        } catch (NullPointerException | RemoteException e) {
        }
    }


同時修改frameworks/base/core/java/android/net/IEthernetManager.aidl

增加

	void Trackstart();//add by hclydao
	void Trackstop();
提供給設定進行狀態控制,這裡基本功能就實現了。
跟蹤測試時發現靜態ip設定的時候有時候不成功,修改檔案frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java

增加

private Handler mHandler;
然後在
mContext = context;

後增加

mHandler = target;//add by hclydao

在if (!setStaticIpAddress(config.getStaticIpConfiguration())) {後增加

//if error then stop and restart add by hclydao
if((mContext != null) && (mHandler != null)) {
    Log.d(TAG, "Setting static ip failed now restart");
    stop();
    start(mContext,mHandler);
}
如果設定失敗,stop後重新start

然後在if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {前面增加

                        if(!iface.equals("eth0"))//add by hclydao make sure the interface is eth0
                            continue;

這裡只設置了一個裝置名,為儲存是eth0所以加上這句,防止意外.

最後來增加Systemui statusbar中的狀態提示,這裡只增加了兩種狀態,一種是連線成功,一種是連線不成功,簡單點來
修改frameworks/base/packages/SystemUI/res/layout/signal_cluster_view.xml

     <View
         android:id="@+id/wifi_signal_spacer"
         android:layout_width="4dp"
前增加

</FrameLayout>
	<!--add by hclyado for ethernet-->
	<FrameLayout
	    android:id="@+id/ethernet_combo"
	    android:layout_height="wrap_content"
	    android:layout_width="wrap_content"
	    android:layout_marginRight="-6dp"
	    >
	    <ImageView
	        android:id="@+id/ethernet_state"
	        android:layout_height="wrap_content"
	        android:layout_width="wrap_content"
	        android:layout_alignParentRight="true"
	        android:layout_centerVertical="true"
	        android:scaleType="center"
	        />
	</FrameLayout>

修改檔案frameworks/base/packages/SystemUI/res/values/strings.xml
增加

    <!-- Content description of the Ethernet connected icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] add by hclydao-->
    <string name="accessibility_ethernet_connected">Ethernet connected.</string>
    <string name="accessibility_ethernet_disconnected">Ethernet disconnected.</string>
    <string name="accessibility_ethernet_connecting">Ethernet connecting.</string>
修改檔案
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java

增加

import android.net.EthernetManager;

在mWifiSignalController.notifyListeners();前面加上

cluster.setEthernetIndicators(false,R.drawable.ethernet_disconnected,R.string.accessibility_ethernet_disconnected);
在pushConnectivityToSignals函式中的
         mWifiSignalController.setInetCondition(
                 mValidatedTransports.get(mWifiSignalController.getTransportType()) ? 1 : 0);

後面增加

//add by hclydao
        int length = mSignalClusters.size();
		int ethicon = R.drawable.ethernet_connecting;
		int ethacc = R.string.accessibility_ethernet_connecting;
		if(mValidatedTransports.get(TRANSPORT_ETHERNET)) {
			ethicon = R.drawable.ethernet_connected;
			ethacc = R.string.accessibility_ethernet_connected;
		}
        for (int i = 0; i < length; i++) {
            mSignalClusters.get(i).setEthernetIndicators(mEthernetConnected, ethicon,ethacc);
        }
//end add

void setIsAirplaneMode(boolean is, int airplaneIcon, int contentDescription);

後增加

public void setEthernetIndicators(boolean visible, int stateIcon, int contentDescription);
修改檔案frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java

增加

    private boolean mEthernetVisible = false;//add by hclydao
    private int mEthernetStateId = 0;
	private int mEthernetDescription;
    ViewGroup mWifiGroup,mEthernetGroup;//modify by hclydao
    ImageView mVpn, mWifi, mAirplane, mNoSims,mEthernet;//modify by hclydao

         mWifiAirplaneSpacer =         findViewById(R.id.wifi_airplane_spacer);
         mWifiSignalSpacer =           findViewById(R.id.wifi_signal_spacer);
         mMobileSignalGroup = (LinearLayout) findViewById(R.id.mobile_signal_group);

後增加

        mEthernetGroup  = (ViewGroup) findViewById(R.id.ethernet_combo);//add by hclydao
        mEthernet       = (ImageView) findViewById(R.id.ethernet_state);

         mWifi           = null;
         mAirplane       = null;

後增加

        mEthernetGroup  = null;//add by hclydao
        mEthernet	    = null;

增加函式

	//add by hclydao
	@Override
    public void setEthernetIndicators(boolean visible, int stateIcon, int contentDescription) {
        mEthernetVisible = visible;
        mEthernetStateId = stateIcon;
        mEthernetDescription = contentDescription;

        apply();
    }
在apply函式中
             mWifiSignalSpacer.setVisibility(View.GONE);
         }

後增加

        if (mEthernetVisible && !mWifiVisible) {//add by hclydao
            mEthernetGroup.setVisibility(View.VISIBLE);
            mEthernet.setImageResource(mEthernetStateId);
            mEthernetGroup.setContentDescription(mContext.getString(mEthernetDescription));
        } else {
            mEthernetGroup.setVisibility(View.GONE);
        }

在boolean anythingVisible = mNoSimsVisible || mWifiVisible || mIsAirplaneMode上增加

|| mEthernetVisible

最後效果圖如下:

============================================
作者:hclydao
http://blog.csdn.net/hclydao
版權沒有,但是轉載請保留此段宣告

============================================

參考文章:

下載檔案為zip檔案,上傳後自動在最後加了_ 下載後將_刪除