android平板以太网设置

本文介绍了如何在Android平板上通过反射机制设置以太网。由于EthernetManager类被@hide注解,无法直接使用,作者通过反射解决这一问题,并提供了详细步骤,包括检测网络可用性、处理权限问题以及解决相关异常的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

项目需要搭载在平板上运行,有个需求是需要进行网络的设置—wifi和以太网。wifi的设置在网上已经有不少的demo,所以这里只谈谈这次以太网设置(这里只简单的说说以太网的开/关,如果需要其余的操作,例如去动态设置ip进行连接等,可以在后面的代码中自己实现)。其实如果平板在插入网线能自动打开以太网进行连接就不要这么麻烦了,怎奈我手上的设备还得去“设置中心”里手动设置才行,而App是不允许用户进到“设置中心”操作的。


瓶颈所在

搜了不少的网上资料,发现以太网设置其实是有一个类的—EthennetManager,通过一下方法就能进行以太网的开/关设置:

manage.setEthernetEnabled(boolean bl)

这不是很简单吗?!是啊,要是能够获取到这个EthernetManager类就真是的太简单的!!!
问题所在就是这个Ethernetmanager类并不是能很简单的进行获取到。我想肯定有大神表示不服,那我来说说不好获取的原因:
1. 代码中不能直接实例化,或者说你写出EthernetManager根本没出现导包的提示。因为Google想让它和你玩躲猫猫,所以给了它一顶@hide的隐身帽。
2. AS提供的SDK中每个版本的android.jar其实并不是完整的 ,是阉割版的,所以你可能会发现某个版本的android.jar中完全找不到EthernetManager这个类。


解决方案

针对上述2个难点来看看我们的解决方案。
1. 针对第一个难点,其实还是蛮好解决的,因为Java里有强大的反射机制;
2. 第二个难点我也查了不少资料,一说是下载android源码进行编译,然后获取到完整的android.jar,而后和本地SDK的进行替换即可。(Ps:这个说简单也简单,可是真不好找,末尾我会给上所需的所有文件已经小Demo。)


相关细节

反射获取EthernetManager类

我的解决方案中是直接把class.jar解压出来的ethernet整个文件夹添加到SDK中的android.net的目录下,所以在获取EthernetManager类的是路径为:

“android.net.ethernet.EthernetManager”

现在来看下反射的代码:

private void getAndSetEthernetManagerByReflection(boolean pIsEnable) {
    //通过反射调用
    try {
        // 获取ETHERNET_SERVICE参数
        String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
        //
        Class<?> ethernetManagerClass = Class.forName("android.net.ethernet.EthernetManager");
        // 获取ethernetManager服务对象
        Object ethernetManager = getSystemService(ETHERNET_SERVICE);
        ethernetManagerClass.getDeclaredMethod("setEthernetEnabled",
                boolean.class).invoke(ethernetManager, pIsEnable);
    } catch (IllegalAccessException | NoSuchFieldException | NoSuchMethodException | ClassNotFoundException
        | InvocationTargetException e) {
        e.printStackTrace();
    }
}

这段代码或许你在编码的时候会发现有一行爆红:
Object ethernetManager = getSystemService(ETHERNET_SERVICE);
提示说getSystemService(XXX)不能接收ETHERNET_SERVICE。怎么解决呢?直接无视,取消掉这个自动检测即可(原因不详==!)。

检测网络是否可用

在进行wifi开发的时候,检测网络是否可用已经是家常便饭。但网上大多数的都是只检测了是不联网,而不没有进一步检测是否能上网!
下面的代码可以检测各种网络是否连接网络且可用。

public  boolean isNetConnected(Context context) {//
    // 通过ping百度检测WIFI是否可用
    ConnectivityManager connectivityManager =
        (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    try {
        String ip = "www.baidu.com";// ping 的地址,可以换成任何一种可靠的外网
        Process p = Runtime.getRuntime().exec("ping -c 3 -w 100 " + ip);//
        int status = p.waitFor();// 只有0时表示正常返回。
        return (connectivityManager.getActiveNetworkInfo() != null && status == 0);
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } catch (InterruptedException e) {
        e.printStackTrace();
        return false;
    }
}

这里并没有什么坑,简单的说下下面一行代码的意思:

Process p = Runtime.getRuntime().exec("ping -c 3 -w 100 " + ip);//

括号内的-c 3是说连接次数,-w 100是连接超时时间。当然如果你硬要去ping谷歌,我只想说一句,请自备好梯子!!!

权限问题

先看看比较明显的权限:

//需要获取网络状态的权限  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
//需要通过ping检测网络,所以需要intent权限  
<uses-permission android:name="android.permission.INTERNET"/>

如果只有这2个,在你运行的时候肯定会发现如下的报错:

Caused by: java.lang.SecurityException: Permission denial: writing to settings requires android.permission.WRITE_SETTINGS
好吧,看来通过代码修改“设置”里面的还得加上下面一句权限:

//修改设置所需权限
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

这次一个可以pass了吧,Run一下却发现还有个坑:

Caused by: java.lang.SecurityException: Package android does not belong to 10056

我查了网上一些资料发现,原来还需要一个root权限(这个问题在定制系统的时候会比较常见)。
可是root权限又如何添加呢?请看代码:

<manifest package="com.xxx.xxx"
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:sharedUserId="android.uid.system">
...
</manifest>

只要在manifest文件中添加上下面一句即可,而且还可以省去了前一个的权限的添加。

  android:sharedUserId="android.uid.system"

其他

  • . 该Demo并不完善,只是提供一个思路,细节上没做太多的处理,例如连续点击第一个按钮会一直触发ping操作,尤其网络条件不好的情况下,这样肯定是会ANR的;

  • 通过打开/关闭以太网,状态的会稍有延迟,但不需要重启App(我查了一些资料说改变设置得重启app才能生效,不知道是不是真的);

  • 也许你在非第一次安装的时候会出现如下的报错:

    INSTALL_FAILED_SHARED_USER_INCOMPATIBLE while using shared user id

    这个问题我页查了资料,是说签名的问题,可惜签名这块还没怎么接触,所以这里只给出解决的方案(后续文章补齐,实在积攒了太多知识点没整理了,⊙﹏⊙b汗)

  • 或许你在刚打开或者clean的时候会发现gradle运行并不是pass的,会报下面的问题(工程不会报错,这是gradle引起的):

    Error:Execution failed for task ‘:app:mockableAndroidJar’ > java.lang.NullPointerException (no error message)

    这个问题还是比较好解决的,可以看下
    http://www.jianshu.com/p/1870d4a655bf

  • 最后是demo的地址已经相关的文件,欢迎前往下载
    http://download.youkuaiyun.com/detail/cherish20151011/9857290

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值