android app 设置以太网静态Ip

2023-05-16

写文目的

  • 公司是做工控和楼宇智能方面产品,使用的设备有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.新增如下内容

<uses-permission android:name="android.net.action.ETHERNET_IP_CHANGED"/>
<receiver android:name="com.android.settings.EtherentBoardcastReceive"
			 android:enabled="true"
			 android:exported="true">
             <intent-filter android:priority="1000">
                <action android:name="android.net.action.ETHERNET_IP_CHANGED" />
            </intent-filter>
        </receiver>

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账号同名)详聊。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android app 设置以太网静态Ip 的相关文章

  • 主题以编程方式设置。如何重新加载 Activity 来应用

    如何在不重新启动整个应用程序的情况下应用主题 如果我这样做startActivity getIntent finish 活动退出并且不重新启动 是否可以简单地重新启动 重新创建活动来应用主题 它的顺序不正确 finish intent ne
  • “此版本中使用了已弃用的 Gradle 功能,使其与 Gradle 7.0 不兼容。” -反应-原生

    当我尝试运行反应本机应用程序时 我遇到此错误react native run android 我无法安装该应用程序 我正在尝试构建一个相机应用程序 我当前的react native版本 0 62 0 React cli版本 2 0 1 De
  • Android STFP 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在我的 Android 项目中使用 SFTP 安卓已经有了吗 SFTP 库 还是我必须实现它 I
  • 在Android中将半径边框绘制到imageview或textview的一个角落

    我需要在我的应用程序中为图像视图或文本视图绘制边框 但我只需要在一个角落绘制它 就像图像一样 我做了一个形状 但我在所有 4 个边上都有边框
  • 删除视图并重新创建它

    有没有办法删除设置的视图 setContentView R layout set map center mapView MapView findViewById R id mapview 如果我再次调用此视图 则会收到一条错误消息 java
  • 在Android内存中存储gif图像

    我对安卓还很陌生 我想将图像保存到内存中 然后从内存中检索图像并将其加载到图像视图中 我已使用以下代码成功将图像存储在内存中 void saveImage String fileName img cnt jpg File file new
  • NumberPicker 的格式化值在单击时消失

    我的 NumberPicker 在setDescendantFocusability FOCUS BLOCK DESCENDANTS 模式和setWrapSelectorWheel false 已关闭 我用一个简单的格式化程序格式化了我的
  • Android 从键盘读取

    我的登录屏幕根本没有文本字段 当用户使用 RFID 扫描仪扫描他的 id 令牌时 我会得到一个 8 个字符长的字符串 其原理与使用键盘相同 只是更快 我希望我的登录活动在用户扫描其令牌时而不是之前执行 有一个聪明的方法来实现这个吗 我不能有
  • Mesibo 通话 UI 未更新

    我正在尝试更改 Mesibo Call UI 的配置 但它并没有改变 我尝试如下 MesiboCallConfig mesiboCallConfig new MesiboCallConfig mesiboCallConfig backgro
  • Android Accessibility 执行触摸操作

    我想知道是否可以使用 Android 辅助功能服务在屏幕上的位置执行触摸操作 例如 Bundle arguments new Bundle arguments putInt coord X X value arguments putInt
  • AOSP 中 android.Build.SERIAL 何时何地生成?

    我知道android Build SERIAL是在第一次设备启动时生成的 但我无法准确定位位置和时间 我正在建造AOSP Jelly Bean Android平板电脑 nosdcard 第二个问题 这个是序列号吗 really对所有人来说都
  • 如何将 Google Now 搜索栏添加到我的应用程序中?

    谷歌刚刚将其搜索栏从 Google Now 引入到了 Play 商店应用程序中 如下面的 gif 所示 如何将这个操作栏搜索栏实现到我自己的应用程序中 我想要 style 汉堡动画 从工具栏按钮访问 麦克风按钮 对棒棒糖设备的连锁反应 我已
  • opencv人脸检测示例

    当我在设备上运行应用程序时 应用程序崩溃并显示以下按摩 java lang UnsatisfiedLinkError 无法加载 detector based tracker findLibrary 返回 null 我正在使用 OpenCV
  • Android 26 (O) 通知不显示操作图标 [重复]

    这个问题在这里已经有答案了 随着 Android 26 O 引入通知渠道 我一直在调查 Google 提供的com example android notificationchannels 这个示例按预期工作 直到我尝试添加Action到示
  • Proguard - 找不到任何超级类

    我收到此错误 Unexpected error while performing partial evaluation Class org apache log4j chainsaw Main Method
  • 活动组代码示例

    有人可以给我一些使用活动组的示例代码吗 我的应用程序中有一些按钮 我想将活动应用于这些按钮 目前我正在使用 setVisibility 但我被告知活动组将是更好的选择 这是另一个ActivityGroup 示例项目 http richipa
  • Android 发布到 facebook 墙,stream.publish 几天来就中断了

    我有很多使用 FB android sdk 发布的应用程序 github com facebook facebook android sdk 我所有使用 FB 的应用程序几天后就停止工作了 这必然是 FB 方面的更改或错误 因为我的应用程序
  • InAppMessage 一旦显示就会自动消失

    您好 我最近将 InAppMessaging 添加到我的项目中 这似乎很容易集成 但对我来说并没有按预期工作 首先 我将其添加到 build gradle 中 implementation com google firebase fireb
  • Android:如何在布局中放置纯色矩形?

    我有一个可以很好地膨胀的relativelayout 我想在顶部添加一个跨越布局宽度的纯色矩形 我尝试将以下内容放入我的 xml 中
  • 在上下文操作模式下选择时,ListView 项目不会在视觉上“突出显示”

    我关注了 Android 官方网站创建上下文操作菜单的教程 http developer android com guide topics ui menus html CAB 使用下面的代码 当我长按我的 ListView 项目之一时 它确

随机推荐