Enabling USB tethering programmatically - there is

2019-01-14 04:25发布

问题:

I've read many questions here on SO that ask how to enable USB tethering programmatically.

The answer is always the same, ordinary applications can't do it, only system apps.

Yet for 2.3 you could download an app in the market that would do it for you.

https://play.google.com/store/apps/details?id=org.tdtran.autousbtethering

On ICS (Android 4.0.3) it no longer works.

How did they do it for 2.3? Is it possible also for 4.0?

回答1:

using the following code you can enable USB tethering. i didt test in 4.0.

 public void switchOnTethering() {

                Object obj = getSystemService(Context.CONNECTIVITY_SERVICE);
                for (Method m : obj.getClass().getDeclaredMethods()) {

                    if (m.getName().equals("tether")) {
                        try {
                            m.invoke(obj, "usb0");
                        } 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();
                        }
                    }
                }
        }


回答2:

ICS and above: To execute the reflection method, the application would require the WRITE_SECURE_SETTINGS permission.

This is not available unless the phone is rooted.



回答3:

since this is one of the most popular pages in the Google results for this topic I'd like to contribute my code which is checking the available interfaces. It does work on a Gingerbread phone I have, but not my Galaxy S3.

    // DETECT INTERFACE NAME
Log.i("UsbTethering","Detecting tetherable usb interface.");
String[] available = null;
ConnectivityManager connMgr = (ConnectivityManager)connectivityServiceObject;
Method[] wmMethods = connMgr.getClass().getDeclaredMethods();
for(Method getMethod: wmMethods)
{
    if(getMethod.getName().equals("getTetherableUsbRegexs"))
    {
        try
        {
            available = (String[]) getMethod.invoke(connMgr);
            break;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
// DETECT INTERFACE NAME


if(available.length > 0)
{       
    for(String interfaceName : available)
    {
        Log.i("UsbTethering", "Detected " + String.valueOf(available.length) + " tetherable usb interfaces.");
        Log.i("UsbTethering", "Trying to " + desiredString + " UsbTethering on interface " + interfaceName + "...");
        Integer returnCode = (Integer)method.invoke(connectivityServiceObject, interfaceName);
        if(returnCode == 0)
        {
            Log.i("UsbTethering", "UsbTethering " + desiredString + "d.");
            return true;
        }
        else
        {
            Log.w("UsbTethering", "Failed to " + desiredString + "Usb Tethering. ReturnCode of method " + method.getName() + ": " + String.valueOf(returnCode));
        }
    }
}


回答4:

On Samsumg Galaxy Tab 2 10.1 the interface isn't called "usb0" but "rndis0". Maybe that's the same for Galaxy SII



回答5:

The port "rndis0" is enabled dynamically not availble in the the Tetherable interfaces list. It gets added when the user selects the USB Tethering option in the menu. The function ConnectivityManager::setUsbTethering(bool) is called when the option is selected. And this function call is allowed only for System applications.



回答6:

I know its an old thread but i hope this could help some other people in the future ,

That code worked for me in Android 4.4(with root privilege)

code: the trick is to use reflection , the method which changes the usb tethring is called "setUsbTethering"

I wont write the entire class but here is what you need:

ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Method usbTethering = connectivityManager.getClass().getMethod('setUsbTethering')
int returnCode = (Integer)usbTethering.invoke(connectivityManager, true);

0 = success

you can print the entire class methods using the following code

private static void printClassMethod(@NonNull Class aClazz) {
Method[] wmMethods = aClazz.getDeclaredMethods();
  for (Method method : wmMethods) {
     Log.i('anytag', method.getName());
  }
}

then call printClassMethod(ConnectivityManager.class)

More Over, you can go onto the class itself and check the methods and arguments needed.

to get things work: you must set your app as System app,

  1. Declare in manifest : android:sharedUserId="android.uid.system"

  2. add writing secure permission<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"

  3. Sign the apk using google certificate key(apk-with-system-privileges) and push it to /system/app

Mind, that usbTethering is turned on while USB is attached, so a nicer solution will be to register to both USB_STATE and USB_ATTACH and enable/disable it correspondingly in onReceive Method. (USB tethering is turned off automatically when USB is de-attached)



标签: android usb