通过编程(Android)(根设备)实现以太网连接



我有一个关于以太网的小问题。

我的三个问题是:

  1. 我们能以编程方式打开/关闭Ethernet吗?

  2. 我们可以通过编程方式启用/禁用Ethernet吗?

  3. 我们可以通过程序连接Ethernet吗?

以上问题是用Wifi完成的。类似

  1. 我们可以通过编程方式打开/关闭Wifi

  2. 我们可以通过编程方式启用/禁用Wifi

  3. 我们可以使用WifiManager以编程方式连接Wifi

android是否提供类似WifiManagerEthernetManager来处理Ethernet

或者,如果这看起来不可行,那么我最初的要求是:

我要澄清的第一件事是"设备已生根"。

我可以操作设置(默认设置)吗?就像我不想要Settings.apk中除了WIFIEthernet之外的任何其他选项。它应该只显示WifiEthernet。就是这样。我可以禁用"设置"中的所有选项吗?或者我可以删除"设置"的所有其他选项吗?

我将在这里介绍的解决方案是一个使用反射的破解方案,仅适用于根android系统。

您的设备可能具有流行的android.net.ethernet包。在活动中,尝试

Object emInstance = getSystemService("ethernet");

它返回一个有效的EthernetManager实例或null。空表示你运气不佳。

另一个要求可能取决于您的设备:以太网和Wifi可能只能单独工作。您可能需要禁用Wifi才能启用以太网,反之亦然。

要通过反射启用以太网,请使用您的EthernetManager实例。要调用的方法是setEthEnabled(布尔值启用)

Class<?> emClass = null;
try {
emClass = Class.forName("android.net.ethernet.EthernetManager");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object emInstance = getSystemService("ethernet");
Method methodSetEthEnabled = null;
try {
methodSetEthEnabled = emClass.getMethod("setEthEnabled", Boolean.TYPE);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
methodSetEthEnabled.setAccessible(true);
try {
// new Boolean(true) to enable, new Boolean(false) to disable
methodSetEthEnabled.invoke(emInstance, new Boolean(false));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

您的应用程序清单需要这些权限

<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

WRITE_SECURE_SETTINGS权限只能由系统应用程序获取。该应用程序不需要通过系统密钥进行签名。它可以是任何有效的标志(如常规的Android应用程序导出功能)。使用busybox重新安装系统分区以进行写访问,并将您的apk移动到/system/app文件夹中。重新启动设备,它应该可以工作。

我们可以通过编程连接以太网吗?

没有接入点可以连接你喜欢的Wifi。您可以为DHCP配置它,也可以提供静态值。当然,这也可以通过反射来实现。为此,您需要类EthernetDevInfo。

EthernetManager和EthernetDevInfo的实际实现可能在Android版本和设备之间略有不同,因为它(还)不必符合公共api,甚至可能是自定义版本。要获得getter和setter的列表,通常可以使用Introspector或反射。

好的,下面是我为使用以太网接口(eth0)进行操作而制作的一些方法。

1) 一种检查以太网接口是否存在的方法

public static boolean doesEthExist() {
List<String> list = getListOfNetworkInterfaces();
return list.contains("eth0");
}
public static List<String> getListOfNetworkInterfaces() {
List<String> list = new ArrayList<String>();
Enumeration<NetworkInterface> nets;
try {
nets = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
e.printStackTrace();
return null;
}
for (NetworkInterface netint : Collections.list(nets)) {
list.add(netint.getName());
}
return list;
}

2) 一种检查以太网是否已启用或打开的方法

public static boolean isEthOn() {
try {
String line;
boolean r = false;
Process p = Runtime.getRuntime().exec("netcfg");
BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream()));   
while ((line = input.readLine()) != null) {   
if(line.contains("eth0")){
if(line.contains("UP")){
r=true;
}
else{
r=false;
}
}
}   
input.close();
Log.e("OLE","isEthOn: "+r);
return r; 
} catch (IOException e) {
Log.e("OLE","Runtime Error: "+e.getMessage());
e.printStackTrace();
return false;
}
}

3) 一种根据以太网的状态启用或禁用以太网的方法

public static void turnEthOnOrOff() {
try {
if(isEthOn()){
Runtime.getRuntime().exec("ifconfig eth0 down");
}
else{
Runtime.getRuntime().exec("ifconfig eth0 up");
}
} catch (IOException e) {
Log.e("OLE","Runtime Error: "+e.getMessage());
e.printStackTrace();
}
}

4) 一种通过以太网连接的方法,取决于所选类型(dhcp/static)

private boolean connectToStaticSettingsViaIfconfig(StaticConnectionSettings scs) {

try {
if(typeChosen.equalsIgnoreCase("dhcp")){
Runtime.getRuntime().exec("ifconfig eth0 dhcp start");
}
else{
Runtime.getRuntime().exec("ifconfig eth0 "+scs.getIp()+" netmask "+scs.getNetmask()+" gw "+scs.getGateway());
}
} catch (IOException e) {
Log.e("OLE","Runtime Error: "+e.getMessage());
e.printStackTrace();
return false;
}
return true;
}

还有一个类是我创建的,用于存储所有需要的eth值。该类使用用户插入的值进行初始化。

public class StaticConnectionSettings {
private String ip, netmask, dns, mac, gateway, type;
//Getters and Setters
}

就是这样。。。我很快就会测试它。。。此代码缺少测试阶段(ping)。也许它需要设置DNS。但这很容易做到。我没有包括它,因为我认为在我们的设备上,它也可以在没有DNS设置的情况下工作。

适用于Android 6.0.1

Class<?> ethernetManagerClass = Class.forName("android.net.ethernet.EthernetManager");
Method methodGetInstance = ethernetManagerClass.getMethod("getInstance");
Object ethernetManagerObject = methodGetInstance.invoke(ethernetManagerClass);
Method methodSetEthEnabled = ethernetManagerClass.getMethod("setEthernetEnabled", Boolean.TYPE);
methodSetEthEnabled.invoke(ethernetManagerObject, isEnabled);

以上问题的三个答案:

  1. 是的。您可以尝试使用ifconfig eth0 down ; ifconfig eth0 up。但我还没有自己测试过
  2. 是的,但你不必这么做。安卓为你切换。如果连接到WiFi,以太网将禁用。如果您已经连接到WiFi,并且将以太网电缆插入设备;你只需要禁用WiFi(你知道怎么做),android就会自动切换到以太网
  3. 并不像你想象的那么容易。我也有同样的问题,直到现在我只找到了一个我还没有测试的解决方案。由于android运行在linux内核上,我们可以使用ifconfig来操作以太网连接

此处隐藏了一个解释:http://elinux.org/images/9/98/Dive_Into_Android_Networking-_Adding_Ethernet_Connectivity.pdf

这次讲座的youtube视频

http://www.youtube.com/watch?v=LwI2NBq7BWM

以及关于如何为安卓使用ifconfig的参考

安卓以太网使用dhcp 配置IP

所以,如果你找到了一个可能的解决方案,请分享!!如果我在你面前做,我一定会的。

最新更新