通过编程的以太网连接 (Android)(有根设备)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21746192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ethernet Connectivity through Programmatically (Android) (Rooted Device)
提问by Manohar Perepa
I have a small issue regarding Ethernet.
我有一个关于以太网的小问题。
My three questions are:
我的三个问题是:
Can we programmatically Turn-On/Off
Ethernet
?Can we programmatically Enable/Disable
Ethernet
?Can we programmatically Connect
Ethernet
?
我们可以以编程方式打开/关闭
Ethernet
吗?我们可以以编程方式启用/禁用
Ethernet
吗?我们可以以编程方式连接
Ethernet
吗?
The above Questions are done with the Wifi
. Like
上面的问题是用Wifi
. 喜欢
We can programmatically Turn-On/Off
Wifi
.We can programmatically Enable/Disable
Wifi
.We can programmatically Connect
Wifi
usingWifiManager
.
我们可以以编程方式 Turn-On/Off
Wifi
。我们可以以编程方式启用/禁用
Wifi
。我们可以
Wifi
使用WifiManager
.
Does android provides any EthernetManager
like as WifiManager
to handle Ethernet
?
android 是否提供EthernetManager
类似的WifiManager
处理方式Ethernet
?
Or, if this doesn't seem feasible, then my original requirement is:
或者,如果这似乎不可行,那么我最初的要求是:
The first thing I am going to clear is "DEVICE IS ROOTED" .
我要澄清的第一件事是“设备已扎根”。
Can I manipulate the Settings (Default)? Like I don't want any other option in the Settings.apk
other than WIFI
and Ethernet
. It should show only Wifi
and Ethernet
. That's it. Can I disable all the options from the Settings or Can I remove all the other options from the Settings?
我可以操作设置(默认)吗?就像我不想要Settings.apk
除了WIFI
and之外的任何其他选项Ethernet
。它应该只显示Wifi
和Ethernet
。就是这样。我可以从“设置”中禁用所有选项还是可以从“设置”中删除所有其他选项?
回答by Robin Gawenda
The solution I will present here is a hack using reflection and does only work on a rooted android system.
我将在此处介绍的解决方案是使用反射的 hack,并且仅适用于有根的 android 系统。
Your device might have the popular android.net.ethernet package. In an Activity, try
您的设备可能具有流行的 android.net.ethernet 包。在活动中,尝试
Object emInstance = getSystemService("ethernet");
It returns an valid instance of the EthernetManager or null. Null means you are out of luck.
它返回一个有效的 EthernetManager 实例或 null。Null 意味着你不走运。
An additional requirement might be depending on your device: Ethernet and Wifi might only work exclusively. You might need to disable Wifi to enable Ethernet and vice versa.
一个额外的要求可能取决于您的设备:以太网和 Wifi 可能只能专门工作。您可能需要禁用 Wifi 才能启用以太网,反之亦然。
To enable Ethernet by reflection use your instance of the EthernetManager. The method you want to invoke is setEthEnabled(boolean enabled)
要通过反射启用以太网,请使用您的 EthernetManager 实例。您要调用的方法是 setEthEnabled(boolean enabled)
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();
}
Your application manifest needs these permissions
您的应用程序清单需要这些权限
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
The permission WRITE_SECURE_SETTINGS can only be acquired by system apps. The app does not need to be signed by a system key. It can be any valid sign (like the regular Android App Export function). Use busybox to remount the system partition for write access and move your apk into the /system/app folder. Reboot the device and it should work.
WRITE_SECURE_SETTINGS 权限只能由系统应用获取。该应用程序不需要由系统密钥签名。它可以是任何有效的符号(如常规的 Android 应用程序导出功能)。使用 busybox 重新挂载系统分区以进行写访问并将您的 apk 移动到 /system/app 文件夹中。重新启动设备,它应该可以工作。
Can we programmatically Connect Ethernet ?
我们可以以编程方式连接以太网吗?
There is no Access Point to connect you like with Wifi. You either configure it for DHCP or provide static values. This can of course also be done via reflection. You will need the class EthernetDevInfo for that.
没有接入点可以像 Wifi 一样连接您。您可以为 DHCP 配置它或提供静态值。这当然也可以通过反射来完成。为此,您将需要类 EthernetDevInfo。
The actual implementation of the EthernetManager and EthernetDevInfo might slightly differ between Android versions and devices as it doesn't have to conform to a public api (yet) and might even be a custom version. To get a list of getters and setters you can use a Introspectoror reflection in general.
EthernetManager 和 EthernetDevInfo 的实际实现在 Android 版本和设备之间可能略有不同,因为它不必符合公共 api(尚),甚至可能是自定义版本。要获取 getter 和 setter 的列表,您可以使用Introspector或一般的反射。
回答by MTurPash
Ok here are some methods i made for manipulating with the ETHERNET INTERFACE (eth0).
好的,这里是我使用以太网接口 (eth0) 进行操作的一些方法。
1) A method for checking if an ethernet interface exists
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) A method for checking if the ETHERNET is enabled or ON
2)一种检查以太网是否启用或ON的方法
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) A method for enabling or disabling the Ethernet depending on the state in which it is
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) A method for connecting via ethernet depending on the chosen type (dhcp/static)
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;
}
There is one more class which i created for storing all the eth values needed. This class is than initialized with the values the user inserts.
我又创建了一个类来存储所需的所有 eth 值。这个类然后用用户插入的值初始化。
public class StaticConnectionSettings {
private String ip, netmask, dns, mac, gateway, type;
//Getters and Setters
}
This is it ... I will test it shortly... This code lacks a test phase (ping). And maybe it needs setting of DNS. But this can be done easily. I have not included it because i think on our device it will work also without the DNS setting.
就是这样......我很快就会测试它......这段代码缺少测试阶段(ping)。也许它需要设置DNS。但这很容易做到。我没有包含它,因为我认为在我们的设备上它也可以在没有 DNS 设置的情况下工作。
回答by klnvch
It works for Android 6.0.1
它适用于 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);
回答by MTurPash
Three Answeres to your above questions:
以上问题的三个答案:
- Yes. You could try using
ifconfig eth0 down ; ifconfig eth0 up
. But i have not tested it by myself yet. - Yes, but you do not have to. Android does the switching for you. If you connect to WiFi, Ethernet disables. If you are already connected to WiFi and you plug your ethernet cable into the device; you need only to disable WiFi (which you know how to) and android switches automatically to ethernet.
- Not so easy as you may think. I have the same problem and until now i have found only one solution which i have not yet tested. Since android runs on the linux kernel, we can use ifconfig in order to manipulate the ethernet connection.
- 是的。您可以尝试使用
ifconfig eth0 down ; ifconfig eth0 up
. 但我还没有亲自测试过。 - 是的,但您不必这样做。Android 会为您进行切换。如果您连接到 WiFi,以太网将禁用。如果您已经连接到 WiFi 并且将以太网电缆插入设备;你只需要禁用 WiFi(你知道怎么做),android 就会自动切换到以太网。
- 并不像你想象的那么容易。我有同样的问题,直到现在我只找到了一个我还没有测试过的解决方案。由于 android 在 linux 内核上运行,我们可以使用 ifconfig 来操作以太网连接。
An explanation is hidden here: http://elinux.org/images/9/98/Dive_Into_Android_Networking-_Adding_Ethernet_Connectivity.pdf
此处隐藏了解释:http: //elinux.org/images/9/98/Dive_Into_Android_Networking-_Adding_Ethernet_Connectivity.pdf
And the youtube video of this lecture
还有这个讲座的youtube视频
http://www.youtube.com/watch?v=LwI2NBq7BWM
http://www.youtube.com/watch?v=LwI2NBq7BWM
And a reference on how to use ifconfig for android
以及如何使用 ifconfig for android 的参考
Android ethernet configure IP using dhcp
So if you come to a possible solution, please share it!! If i will do it before you i will certenly.
因此,如果您找到可能的解决方案,请分享!!如果我会在你之前做,我一定会的。