在安卓设备上检测USB网络共享

8
有没有办法在您的Activity/Application中(以编程方式)知道用户是否已启用了手机上的USB共享网络?
6个回答

7

您还可以使用反射来访问隐藏的功能以设置USB网络共享。这是我的代码。

    ConnectivityManager cm =
        (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    Log.d(TAG,"test enable usb tethering");
    String[] available = null;
    int code=-1;
    Method[] wmMethods = cm.getClass().getDeclaredMethods();

    for(Method method: wmMethods){
      if(method.getName().equals("getTetherableIfaces")){
        try {
            available = (String[]) method.invoke(cm);
            break;
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return;
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return;
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return;
        }
      }
    }

    for(Method method: wmMethods){
          if(method.getName().equals("tether")){                  
              try {
                code = (Integer) method.invoke(cm, available[0]);


            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return;
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return;
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return;
            }
            break;
          }
    }

    if (code==0) 
        Log.d(TAG,"Enable usb tethering successfully!");
    else
        Log.d(TAG,"Enable usb tethering failed!");

如果要禁用USB网络共享,只需将反射方法名称“getTetherableIfaces”更改为“getTetheredIfaces”,并将“tether”更改为“untether”。

请确认无误。


不言而喻,但这当然是一种非标准的做法,开发者应该意识到,并且我还是要说一下。 - Prof. Falken
我试了一下你的代码并将它置于连接共享模式。然而,设备并没有真正处于共享模式,它只显示了“共享或热点已启用”的通知(带有一个不寻常的有圆点中心的滑稽图标),而共享设备设置也显示热点已启用但开关被关闭了。我没有检查热点,因为那不是我想要的(我想要的是USB)。 然而,坏的是在每个后续运行应用程序时(即使重新启动后),它都没有显示任何已共享、可共享或错误的接口!我可能需要从头开始重新加载它。 - Shorin
我的设备是一款AT&T三星Galaxy Note SGH-I717,运行官方版4.1.2。 - Shorin
Tether方法在Android M上需要WRITE_SETTINGS权限,可能是因为自Android Lolipop以来,没有任何getTether状态,只有一个set方法。 - Luis Pereira

3
浏览Settings.System文档,说明无法这样做。点击链接查看该文档。

即使使用java.lang.reflection也不可能吗?我用它实现了Wifi Tethering的状态检查...但是对于USB,我就想不出来了。 - Raza

2

这应该适用于所有手机,在一些安卓7、6和5设备上经过确认;

方法:接口rndisX(通常是rndis0)只有在启用USB网络共享时才会显示。

代码示例:

private static boolean isTetheringActive(Context context){
    try{
        for(Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();){
            NetworkInterface intf=en.nextElement();
            for(Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();){
                InetAddress inetAddress=enumIpAddr.nextElement();
                if(!intf.isLoopback()){
                    if(intf.getName().contains("rndis")){
                        return true;
                    }
                }
            }
        }
    }catch(Exception e){e.printStackTrace();}
    return false;
}

1

以下是监听网络共享状态变化的解决方案:

首先,您需要熟悉BroadcastReceiver。您可以找到很多教程(Google:如何监听连接更改...)

为了获取网络共享状态更新,您需要使用Android的隐藏过滤器动作(请参阅ConnectivityManager)

并在您的BroadcastReceiver类中:

IntentFilter filter = new IntentFilter("android.net.conn.TETHER_STATE_CHANGED");

然后将过滤器注册到您的BroadcastReceiver中:

myApplicationContext.registerReceiver(this, filter);

在你的onReceive(final Context context,final Intent intent)方法中,Intent.extras信息包含3个数组,分别填充了相应的网络接口:erroredArray / availableArray / activeArray。
这有点棘手,但你可以获取到网络共享状态信息。
此外,你还可以对Android代码的隐藏功能进行一些反射:
在Connectivity Manager中搜索getTetherableIfaces()。
这是一个链接:https://github.com/android/platform_frameworks_base/blob/master/core/java/android/net/ConnectivityManager.java#L1604


0
您可以通过以下方式获取网络接口并检查哪个是活动的:
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
NetworkInterface rndis = null;
NetworkInterface wlan = null;

while(interfaces.hasMoreElements()) {
     NetworkInterface nif = interfaces.nextElement();
     if(hasIP4Address(nif)) {
          if(nif.getDisplayName().startsWith("rndis"))
              rndis = nif;
          else if (nif.getDisplayName().startsWith("wlan"))
              wlan = nif;
     }
}
// Let the user choose Wi-Fi or rndis connect
if (rndis != null) {
    socket.setNetworkInterface(rndis);
    Log.i(TAG, "Subscribe: with interface rndis");
} else if(wlan != null) {
    socket.setNetworkInterface(wlan);
    Log.i(TAG, "Subscribe: with interface wlan");
}

-1

我发现如果要检查usb0网络接口,只有在设置了数据共享后才会有IP地址。

public static String getIPAddressUsb(final boolean useIPv4) {
    try {
        final List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
        for (final NetworkInterface intf : interfaces) {
            if (intf.getDisplayName().startsWith("usb")) {
                final List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
                for (final InetAddress addr : addrs) {
                    final String sAddr = addr.getHostAddress().toUpperCase();
                    final boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
                    if (useIPv4) {
                        if (isIPv4) { return sAddr; }
                    } else {
                        if (!isIPv4) {
                            final int delim = sAddr.indexOf('%');
                            return delim < 0 ? sAddr : sAddr.substring(0, delim);
                        }
                    }
                }
            }
        }
    } catch (final Exception ex) {
        // for now eat exceptions
    }
    return "";
}


boolean isUsbTethered(){
String ipAddr = MipnAndroidApplication.getIPAddressUsb(true);
    if (ipAddr.length() == 0) {
        Log.i(LOG_TAG, "tethering not enabled");
    return false;
    } else {
        Log.i(LOG_TAG, "tethering enabled :)");
    return true;
    }
}

这个不起作用。即使我知道我已经启用了数据共享,我仍然收到“未启用数据共享”的消息。 - javawocky
是的,你可能需要一个新的解决方案,因为我的答案是在2013年的。事情已经发生了变化。 - Andy Aspell-Clark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接