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?

3
  • 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 ? Jul 5, 2013 at 15:24
  • elinux.org/Android_aapt Jul 5, 2013 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 ? Jul 5, 2013 at 15:50

7 Answers 7

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
3
  • *setFunction in first command
    – Jortstek
    Nov 15, 2021 at 0:50
  • @Jortstek in the latest release of Android (version 12), it still continues to be setFunctions. See android.googlesource.com/platform/frameworks/base/+/refs/heads/… It is possible the Android implementation by your device's vendor removed the trailing s from the keyword.
    – Firelord
    Nov 15, 2021 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, 2021 at 19:41
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.

6
  • 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.
    – user43185
    Jun 8, 2015 at 8: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, 2015 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, 2016 at 0:58
  • Confirm that the MM command works on CM13 6.0.1 also. Thanks!
    – David784
    Apr 17, 2016 at 16:31
  • 1
    on CM14.1(7.1) the Jelly Bean command works
    – christoph
    Jan 5, 2017 at 18:12
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.

4
  • 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, 2017 at 6: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, 2017 at 8: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. Nov 28, 2017 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;. Nov 29, 2017 at 18:55
8

Try the setprop command below:

setprop sys.usb.config rndis,adb
1
  • 5
    This is only part of what's needed. This won't start dnsmasq for instance.
    – kroot
    Dec 3, 2013 at 6:25
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
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
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .