android app 设置以太网静态Ip

写文目的

  • 公司是做工控和楼宇智能方面产品,使用的设备有rk和全志平台,
    运行的是android操作系统,部分场景需要设置有线网络的静态Ip。
    所以针对这一需求做了如下工作,并以此文作为总结。

遇到的问题

  • 之前也有百度过相关方案,但大部分使用的是busybox ifconfig来设置,而这种方式有很多弊端,如设置的app必须拥有root权限、不能实时切换static和dhcp、重启后设置的就不生效、不能通过系统的settings参看设置的状态。经过一番折腾后发现为了解决这些问题必须从android的系统应用settings apk入手!
    注意:若手上没有android系统源码,就不用往下看了。但可以尝试下载如下源码测试点击下载。

实现思路

  • 在settings中注册一个静态广播,广播的接收函数中完成ip的设置。当用户层要设置ip时,只需发送广播给settings即可。

用户app设置样例

Intent intent = new Intent();
        intent.putExtra("netMode", "static");
        intent.putExtra("ipaddr", "192.168.1.223");
        intent.putExtra("netMask", "255.255.255.0");
        intent.putExtra("gateway", "192.168.1.198");
        intent.putExtra("dns1", "192.168.1.198");
        intent.putExtra("dns2", "8.8.8.8");
        intent.setAction("android.net.action.ETHERNET_IP_CHANGED");
        sendBroadcast(intent);

settings修改部分

一、修改AndroidManifest.xml
1.新增如下内容



             
                
            
        

2.在目录Settings\src\com\android\settings\ethernet 下新增文件EtherentBoardcastReceive.java

package com.android.settings;

import com.android.settings.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.CheckBoxPreference;
//import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceScreen;
//import android.preference.SwitchPreference;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.content.Intent;

import java.io.File;
import java.io.FileDescriptor;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileDescriptor;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.regex.Pattern;
import java.lang.Integer;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;



/*for 5.0*/
import android.net.EthernetManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.StaticIpConfiguration;
import android.net.NetworkUtils;
import android.net.LinkAddress;
import android.net.LinkProperties;
//import android.preference.ListPreference;
import com.android.internal.logging.MetricsProto.MetricsEvent;

import com.android.settings.ethernet_static_ip_dialog;
import com.android.settings.pppoe_dialog;

import com.android.settings.EthernetSettings;  

public class EtherentBoardcastReceive extends BroadcastReceiver  {
	private static final String TAG = "EtherentBoardcastReceive";
	 
	private  static String mEthMode = null;//"static";
    private  static String mEthIpAddress = null;//"192.168.1.254";
    private  static String mEthNetmask = null;//"255.255.255.0";
    private  static String mEthGateway = null;//"192.168.1.1";
    private  static String mEthdns1 = null;//"192.168.1.1";
    private  static String mEthdns2 = null;//"null";

    private final static String nullIpInfo = "0.0.0.0";

	 @Override
    public void onReceive(Context context, Intent intent) {

			IpConfiguration mIpConfiguration;
			StaticIpConfiguration mStaticIpConfiguration;
			String action = intent.getAction();
		    Log.i(TAG, "receive a new action : " + action);
			
			EthernetManager mEthManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
			if(mEthManager == null){
				Log.i(TAG, "fail to getSystemService :  "+Context.ETHERNET_SERVICE);
			}

		  mStaticIpConfiguration =new StaticIpConfiguration();
		  getNetConfigFromIntent(intent);
		 /*
		  * get ip address, netmask,dns ,gw etc.
		  */
		


		if (mEthMode  == null ||mEthMode.equals("static"))
		{
			 Inet4Address inetAddr = getIPv4Address(this.mEthIpAddress);
			int prefixLength = maskStr2InetMask(this.mEthNetmask); 
			InetAddress gatewayAddr = getIPv4Address(this.mEthGateway); 
			InetAddress dnsAddr1 = getIPv4Address(this.mEthdns1);
			InetAddress dnsAddr2 = getIPv4Address(this.mEthdns2);
			if(inetAddr ==null || gatewayAddr == null || prefixLength <= 0  ){
				  Log.e(TAG,"ip,mask or dnsAddr is wrong");
				  return ;
			}
			if (inetAddr.getAddress().toString().isEmpty() || prefixLength ==0 || gatewayAddr.toString().isEmpty()
			  ) {
				   Log.e(TAG,"ip,mask or dnsAddr is wrong");
				  return ;
			}
			  
			mStaticIpConfiguration.ipAddress = new LinkAddress(inetAddr, prefixLength);
			mStaticIpConfiguration.gateway=gatewayAddr;
			if(dnsAddr1 != null && !dnsAddr1.toString().isEmpty())
				mStaticIpConfiguration.dnsServers.add(dnsAddr1);
			if(dnsAddr2 != null && !dnsAddr2.toString().isEmpty())
				mStaticIpConfiguration.dnsServers.add(dnsAddr2);
		
			mIpConfiguration=new IpConfiguration(IpAssignment.STATIC, ProxySettings.NONE,mStaticIpConfiguration,null);  
			mEthManager.setConfiguration(mIpConfiguration); 
		}else{
			mEthManager.setConfiguration(new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE,null,null));
		}
       
		//
		
    }
	
	private void getNetConfigFromIntent(Intent intent){
		Bundle bundle = intent.getExtras();
        if (bundle.getString("netMode") != null)
			this.mEthMode = bundle.getString("netMode");
		if (bundle.getString("ipaddr") != null)
			this.mEthIpAddress = bundle.getString("ipaddr");
		if (bundle.getString("netMask")!= null)
			this.mEthNetmask = bundle.getString("netMask");
		if (bundle.getString("gateway")!= null)
			this.mEthGateway = bundle.getString("gateway");
		if (bundle.getString("dns1") != null)
			this.mEthdns1 = bundle.getString("dns1");
		if (bundle.getString("dns2") != null)
			this.mEthdns2 = bundle.getString("dns2");
	}
	 private Inet4Address getIPv4Address(String text) {
        try {
            return (Inet4Address) NetworkUtils.numericToInetAddress(text);
        } catch (IllegalArgumentException|ClassCastException e) {
            return null;
        }
    }

	 /*
     * convert subMask string to prefix length
     */
    private int maskStr2InetMask(String maskStr) {
    	StringBuffer sb ;
    	String str;
    	int inetmask = 0; 
    	int count = 0;
    	/*
    	 * check the subMask format
    	 */
      	Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
    	if (pattern.matcher(maskStr).matches() == false) {
    		Log.e(TAG,"subMask is error");
    		return 0;
    	}
    	
    	String[] ipSegment = maskStr.split("\\.");
    	for(int n =0; n<ipSegment.length;n++) {
    		sb = new StringBuffer(Integer.toBinaryString(Integer.parseInt(ipSegment[n])));
    		str = sb.reverse().toString();
    		count=0;
    		for(int i=0; i<str.length();i++) {
    			i=str.indexOf("1",i);
    			if(i==-1)  
    				break;
    			count++;
    		}
    		inetmask+=count;
    	}
    	return inetmask;
    }



}

代码就不多介绍了,大体流程是接收到广播后就解析字符串后进行IP设置
,有明白处可加我微信讨论

最后打个小广告,本人还承接一些android、linux主板软硬件开发的项目,有兴趣的可以加我微信(CSDN账号同名)详聊。

你可能感兴趣的:(android,开发,android,安卓)