29

I would like to activate USB tethering from within a bash script.

I've found TetherSettings action name from

aapt dump xmltree com.android.settings.apk AndroidManifest.xml | less +/ether

The following command open the needed settings, but don't change anything alone

am start -n com.android.settings/.TetherSettings

Is there any possibility to run a command line with adb shell to change it?


Related, but the opposite: Is it possible to disable USB tethering from command line?

Andrew T.
  • 15,988
  • 10
  • 74
  • 123
Gilles Quénot
  • 695
  • 1
  • 5
  • 15
  • That's really cool. I tried to find other commands doing aapt dump xmltree com.android.settings.apk AndroidManifest.xml but that didn't work on my phone(aapt not found). How can I see a list of the available settings ? – George Profenza Jul 05 '13 at 15:24
  • http://elinux.org/Android_aapt – Gilles Quénot Jul 05 '13 at 15:37
  • Thanks! I've found aapt in the build-tools folder. I can run it now. I can't seem to find com.android.settings.apk though. I've tried: find / -name 'com.android.settings.apk' on the phone, but nothing came up :( Can you please let me know where I can find com.android.settings.apk ? – George Profenza Jul 05 '13 at 15:50

7 Answers7

20

Running the following command as root should enable USB tethering:

  • service call connectivity 32 i32 1 on Ice Cream Sandwich (4.0)
  • service call connectivity 33 i32 1 on Jelly Bean (4.1 to 4.3)
  • service call connectivity 34 i32 1 on KitKat (4.4)
  • service call connectivity 30 i32 1 on Lollipop (5.0)
  • service call connectivity 31 i32 1 on Lollipop (5.1) according to an answer by Firelord
  • service call connectivity 30 i32 1 on Marshmallow (6.0), untested
  • service call connectivity 41 i32 1 on Samsung Marshmallow (6.0)
  • service call connectivity 33 i32 1 on Nougat (7.0)
  • service call connectivity 39 i32 1 on Samsung Nougat (7.0)

The first number you see in the commands is the setUsbTethering() method's number in IConnectivityManager.aidl (this depends on the Android version and doesn't exist on Gingerbread).

(Tip: to check this file for a particular Android version, select the appropriate branch.)

So what this command does is call setUsbTethering() and pass either 1 (enable USB tethering) or 0 (to disable it).

For more information, see this related question on Stack Overflow.


If you're enabling USB tethering as part of a USB reverse tethering setup, setprop sys.usb.config rndis,adb should be more than enough to get the rndis0 interface set up.

Léo Lam
  • 313
  • 4
  • 11
  • 1
    Looking at the jb-release branch, int setUsbTethering(boolean enable); looks to be the 33rd method, not 34th. Also, I've tested both the 4.1/4.2 and 4.3/4.4 commands on a Nexus 7 with JB 4.3 and service call connectivity 33 i32 1 turns on tethering. –  Jun 08 '15 at 08:36
  • This is the right answer for USBTethering. It won't work for WifiTethering though. The API hasn't been left open for that... – Kristopher Dec 28 '15 at 16:47
  • That command for Android M works well on my stock Android 6.0.1 on Nexus 6. Good work keeping a list for multiple Android versions. I wish I could upvote it again. – Firelord Mar 17 '16 at 00:58
  • Confirm that the MM command works on CM13 6.0.1 also. Thanks! – David784 Apr 17 '16 at 16:31
  • 1
    on CM14.1(7.1) the Jelly Bean command works – christoph Jan 05 '17 at 18:12
  • For Oreo (8.0): service call connectivity 33 i32 1 – Elad Nava Jun 02 '18 at 02:40
8

If your Android version has svc inbuilt utility, run this command:

adb shell svc usb setFunctions rndis

This would enable USB tethering. To see what other USB functions are available, run:

adb shell svc usb
Firelord
  • 25,084
  • 20
  • 124
  • 286
  • *setFunction in first command – Jortstek Nov 15 '21 at 00:50
  • @Jortstek in the latest release of Android (version 12), it still continues to be setFunctions. See https://android.googlesource.com/platform/frameworks/base/+/refs/heads/android12-release/cmds/svc/src/com/android/commands/svc/UsbCommand.java#39 It is possible the Android implementation by your device's vendor removed the trailing s from the keyword. – Firelord Nov 15 '21 at 11:20
  • 1
    Wow. Android 8 on Samsung device, it most definitely is without the "s". What ways they think of to trip people up. – Jortstek Nov 15 '21 at 19:41
8

There is a pretty bad method using adb shell input tap, Get the coordinates for enable tethering and substitute

adb shell input tap <x> <y>

Or navigate to enable radio using adb shell input keyevent. Just have a look at,

adb shell input 

Again this confines to a particular device.

Andrew T.
  • 15,988
  • 10
  • 74
  • 123
Rilwan
  • 431
  • 4
  • 9
  • Combining this all together, this works for me if the screen is unlocked: adb shell "am start -n com.android.settings/.TetherSettings; input keyevent KEYCODE_DPAD_UP; input keyevent KEYCODE_ENTER". I found a list of key events on SO. – redbmk Jan 31 '17 at 06:53
  • 1
    In case anyone wants to test this out and/or modify it for their device, I'll post this here. I wrote a little script to turn on tethering for my nexus 5x (needs to be unlocked) and hooked it up to udev to do that automatically when I plug it in – redbmk Jan 31 '17 at 08:28
  • 1
    @redbmk - thanks for the useful script. For a Galaxy A5 2017 the key sequence is:

    ${inputKey}DPAD_DOWN; $pause; ${inputKey}DPAD_DOWN; $pause; ${inputKey}ENTER. Also I found that pause="sleep 0.3" works ok.

    – P.Windridge Nov 28 '17 at 19:04
  • In the sequence above I had forgot the initial key presses to dismiss the pop up confirmation about enabling MTP, which is ${inputKey}DPAD_DOWN; $pause; ${inputKey}DPAD_DOWN; $pause; ${inputKey}ENTER;. – P.Windridge Nov 29 '17 at 18:55
8

Try the setprop command below:

setprop sys.usb.config rndis,adb
Andrew T.
  • 15,988
  • 10
  • 74
  • 123
user29787
  • 81
  • 1
  • 2
4

this is device independent (toggles USB tethering)

adb shell am start -n com.android.settings/.TetherSettings &&
adb shell input keyevent 20 &&
adb shell input keyevent 20 &&
adb shell input keyevent KEYCODE_ENTER &&
sleep 2 &&
adb shell input keyevent 4
Gilles Quénot
  • 695
  • 1
  • 5
  • 15
Zibri
  • 173
  • 5
3

Modified to use windows timeout command instead of sleep, wake screen first, and only press down once. Twice down enabled wifi tethering on my phone.

adb shell input keyevent KEYCODE_WAKEUP && adb shell am start -n com.android.settings/.TetherSettings && adb shell input keyevent KEYCODE_DPAD_DOWN && adb shell input keyevent KEYCODE_ENTER && timeout 2 && adb shell input keyevent KEYCODE_BACK
idkaaa
  • 31
  • 2
2

The service method did not work for me on my Samsung device. I figured out how to do it by configuring the network interface directly, though. Here is a script that sets up a Linux machine and a USB-connected rooted Android device for USB tethering. This does not set up DNS or NAT masquerading, but is sufficient to make the device accessible at 192.168.42.129:

#!/bin/bash
set -euo pipefail

# Set up USB tethering for an Android device.
# Usage: adb-usb-tether [USB-VENDOR USB-PRODUCT]
# If USB vendor/product is unspecified, use first USB network interface.
# On the Android side, tethering is enabled via adb shell.

if [[ $# -eq 2 ]]
then
    any=false
    vendor=$1
    product=$2
else
    any=true
fi

function find_if() {
    local path if
    for path in /sys/class/net/*
    do
        if=$(basename "$path")
        if [[ "$(readlink "$path")" == */usb* ]]
        then
            local ifproduct ifvendor
            ifproduct=$(cat "$(realpath "$path")/../../../idProduct")
            ifvendor=$(cat "$(realpath "$path")/../../../idVendor")
            if $any || [[ "$ifproduct" == "$product" && "$ifvendor" == "$vendor" ]]
            then
                echo "Found interface: $if" 1>&2
                echo "$if"
                return
            fi
        fi
    done
}

function adb_shell() {
    adb shell "$(printf " %q" "$@")"
}

function adb_su() {
    local quoted
    quoted="$(printf " %q" "$@")"
    adb shell su -c "$(printf %q "$quoted")"
}

if=$(find_if)
if [[ -z "$if" ]]
then
    echo "Requesting interface:" 1>&2
    adb_su setprop sys.usb.config rndis,adb
    echo " >> OK" 1>&2
fi

while [[ -z "$if" ]]
do
    echo "Waiting for network device..." 1>&2
    sleep 1
    if=$(find_if)
done

while ! ( ip link | grep -qF "$if" )
do
    echo "Waiting for interface..." 1>&2
    sleep 1
done

function configure_net() {
    local name="$1"
    local if="$2"
    local ip="$3"
    local table="$4"
    local cmdq="$5" # Query command
    local cmdx="$6" # Configuration command

    if ! ( "$cmdq" ip addr show dev "$if" | grep -qF 192.168.42."$ip" )
    then
        echo "Configuring $name interface address:" 1>&2
        "$cmdx" ip addr add 192.168.42."$ip"/24 dev "$if"
        echo " >> OK" 1>&2
    fi

    if ( "$cmdq" ip addr show dev "$if" | grep -qF 'state DOWN' )
    then
        echo "Bringing $name interface up:" 1>&2
        "$cmdx" ip link set dev "$if" up
        sleep 1
        echo " >> OK" 1>&2
    fi

    if ! ( "$cmdq" ip route show table "$table" | grep -qF "192.168.42.0/24 dev $if" )
    then
        echo "Configuring $name route:" 1>&2
        "$cmdx" ip route add table "$table" 192.168.42.0/24 dev "$if"
        echo " >> OK" 1>&2
    fi
}

configure_net local  "$if"   128 main  command   sudo
configure_net device rndis0  129 local adb_shell adb_su

To enable forwarding (i.e. connect to the Internet from the PC via the Android device), see my question and answer here.