Detect USB tethering on android
Asked Answered
M

6

8

Is there any way to know (pro grammatically) in your Activity/Application that the user has enabled USB tethering on his phone?

Merideth answered 22/9, 2011 at 5:29 Comment(0)
I
3

Looking through the Settings.System documentation points to the answer being no, its not possible to do this.

Link to said documentation

Ingram answered 22/9, 2011 at 6:2 Comment(1)
Is it not possible by even using java.lang.reflection? I achieved the status check of Wifi Tethering using that...but for USB I just can't figure it out.Merideth
C
7

you can also use reflection to access the hidden function for setting usb tethering. Here is my code.

    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!");

For disabling usb tethering, you just need to change the reflection method name "getTetherableIfaces" to "getTetheredIfaces", change "tether" to "untether".

Please check.

Colettacolette answered 20/10, 2011 at 3:17 Comment(4)
It should go without saying, but this is of course a non standard way of doing it, which a developer should be aware of, so I just say it anyway.Disservice
I tried out your code and put it into tethering mode. However, the device wasn't REALLY in tethering mode, it only showed the "tethering or hotspot enabled" notifiaction (with an unusual funny circle with dot in the middle icon), and the tethering settings said hotspot was enabled but the switch was set to off. Didn't check for a hotspot because that wasn't what I wanted (I wanted USB). However the BAD thing is on every subsequent run of the application (even after reboot) it didn't show any tethered, tetherable, or errored interfaces! I may have to reload this from scratch.Rich
My device is an AT&T Samsung Galaxy Note SGH-I717 running stock 4.1.2Rich
tether method needs WRITE_SETTINGS permissions on Android M, probably because android Lolipop onwards, does not have any getTether state, just a set methodSuicidal
I
3

Looking through the Settings.System documentation points to the answer being no, its not possible to do this.

Link to said documentation

Ingram answered 22/9, 2011 at 6:2 Comment(1)
Is it not possible by even using java.lang.reflection? I achieved the status check of Wifi Tethering using that...but for USB I just can't figure it out.Merideth
C
2

This should work on all phones, confirmed on some Android 7,6 and 5 devices;

Method: interface rndisX (typically rndis0) only shows up when usb tethering is enabled.

Code Example:

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;
}
Ciao answered 11/5, 2017 at 13:8 Comment(0)
C
1

Here is a solution to Listen for tethering state changes :

First you need to be familiar with BroadcastReceiver. you can find a lot of tutorial (google : how to listen for connectivity changes ...)

In order to get the Tethering state update, you need to use a hidden filter action of Android (see ConnectivityManager)

and in your BroadcastReceiver class :

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

then register the filter to your BroadcastReceiver :

myApplicationContext.registerReceiver(this, filter);

on your onReceive(final Context context,final Intent intent) method, the Intent.extras information contains 3 arrays filled with the corresponding tethered network interface : erroredArray / availableArray / activeArray

It's a little bit tricky but you can get the tethering status information.

In addition, you can do some reflexion on hidden function of Android code :

Search for getTetherableIfaces() in the Connectivity Manager.

Here is a link : https://github.com/android/platform_frameworks_base/blob/master/core/java/android/net/ConnectivityManager.java#L1604

Chinua answered 18/11, 2015 at 18:59 Comment(1)
Note that, starting from Android 8 (API level 26), the EXTRA_ACTIVE_TETHER value is "tetherArray" instead of "activeArray" (retrieving the received extras within the onReceive() of the BroadcastReceiver will return a null String array for the "activeArray" key)Hawkinson
J
0

You can get the Network Interfaces and check what is active like this:

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");
}
Jazminejazz answered 11/12, 2020 at 9:44 Comment(0)
T
-1

I have found that if I check for usb0 network interface it only has an ip address once tethering has been set up.

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;
    }
}
Turnstile answered 4/6, 2013 at 10:37 Comment(2)
This doent work. Even after I know I have tethering up and running I still get back the message "tethering not enabled"Adermin
yeah, you probably need a new solution as my answer was in 2013. Things move on.Turnstile

© 2022 - 2024 — McMap. All rights reserved.