Search This Blog

23 January 2012

Reverse USB Tethering

I decided to give reverse usb tethering a shot. I don't know which devices easily support this, but I assume you have to be root. In my particular case, I was using an ICS device.  These steps could easily screw up your existing cell routing - so make sure your willing to risk it.

Step 0: Make sure the device is booted and connected via USB

Step 1: Enable tethering on the device side
  • Go to Settings
  • Under the Wireless & Networks, click on More
  • Click on Tethering & portable hotspot
  • Enable USB Tethering
Step 2: Get the IP Address of the device
malachi@onyx:~$ adb shell
root@android:/ # netcfg
lo       UP                            0x00000049 00:00:00:00:00:00
dummy0   DOWN                            0x00000082 62:bc:02:e1:d5:ea
rmnet0   DOWN                            0x00000000 00:00:00:00:00:00
rmnet1   DOWN                            0x00000000 00:00:00:00:00:00
rmnet2   DOWN                            0x00000000 00:00:00:00:00:00
rmnet3   DOWN                            0x00000000 00:00:00:00:00:00
rmnet4   DOWN                            0x00000000 00:00:00:00:00:00
rmnet5   DOWN                            0x00000000 00:00:00:00:00:00
rmnet6   DOWN                            0x00000000 00:00:00:00:00:00
rmnet7   DOWN                            0x00000000 00:00:00:00:00:00
sit0     DOWN                            0x00000080 00:00:00:00:00:00
rndis0   UP                      0x00001043 da:02:11:22:14:af
Step 3: Get the matching IP Address of the workstation
malachi@onyx:~$ ifconfig -a usb0
usb0      Link encap:Ethernet  HWaddr e2:31:b5:d7:f3:7b 
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::e031:b5ff:fed7:f37b/64 Scope:Link
          RX packets:1990 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1188 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:181334 (181.3 KB)  TX bytes:657452 (657.4 KB)
Step 4: Ping the device from the workstation
malachi@onyx:~$ ping
PING ( 56(84) bytes of data.
64 bytes from icmp_req=1 ttl=64 time=1.01 ms
64 bytes from icmp_req=2 ttl=64 time=0.605 ms

Step 5: Ping the workstation from the device
root@android:/ # ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=0.427 ms
64 bytes from icmp_seq=2 ttl=64 time=0.397 ms
Step 6: Add workstation as the default gateway for the device
root@android:/ # route add default gw dev rndis0
Step 7: Get a list of DNS servers from the workstation
malachi@onyx:~$ cat /etc/resolv.conf
Step 8: Add them to the device
root@android:/ # setprop net.dns1
root@android:/ # setprop net.dns2
Step 9: Setup forwarding from usb0 to eth1 on the workstation
[ most people probably use eth0. Just use ifconfig to check which one is active]

malachi@onyx:~$ sudo su - root
[sudo] password for malachi:
root@onyx:~# echo 1 > /proc/sys/net/ipv4/ip_forward
root@onyx:~# exit
malachi@onyx:~$ sudo iptables --flush -t nat
malachi@onyx:~$ sudo iptables --table nat --append POSTROUTING --out-interface eth1 -j MASQUERADE
malachi@onyx:~$ sudo iptables --append FORWARD --in-interface usb0 -j ACCEPT
Step 10: ping google ;)

malachi@onyx:~$ adb shell
root@android:/ # ping
PING ( 56(84) bytes of data.
64 bytes from ( icmp_seq=1 ttl=51 time=11.8 ms
64 bytes from ( icmp_seq=2 ttl=51 time=11.9 ms
And finally, check things like the Browser...

03 January 2012


Well, I've been needing to look into Fragments for awhile now...

First, to generate a blank project...

malachi@onyx:~/work$ mvn archetype:generate -DarchetypeCatalog=
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: -> org.eoti.kryten:kryten-archetype (kryten-archetype)
2: -> org.eoti.galatea:galatea-archetype (galatea-archetype)
3: -> org.eoti.archtest:archtest-archetype (archtest-archetype)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 2
Define value for property 'groupId': :
Define value for property 'artifactId': : FragmentTest
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package': :
Confirm properties configuration:
artifactId: FragmentTest
version: 1.0-SNAPSHOT
 Y: :
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: galatea-archetype:1.1-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value:
[INFO] Parameter: artifactId, Value: FragmentTest
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value:
[INFO] Parameter: packageInPathFormat, Value: org/eoti/android/test/fragments
[INFO] Parameter: package, Value:
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value:
[INFO] Parameter: artifactId, Value: FragmentTest
[WARNING] Don't override file /home/malachi/work/FragmentTest/src/main/android/res/values/strings.xml
[WARNING] Don't override file /home/malachi/work/FragmentTest/src/main/android/res/layout/main.xml
[INFO] project created from Archetype in dir: /home/malachi/work/FragmentTest
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 21.579s
[INFO] Finished at: Tue Jan 03 08:30:32 PST 2012
[INFO] Final Memory: 8M/245M
[INFO] ------------------------------------------------------------------------
malachi@onyx:~/work$ cd FragmentTest/
malachi@onyx:~/work/FragmentTest$ tree
├── pom.xml
└── src
    ├── AndroidManifest.xml
    └── main
        ├── android
        │   └── res
        │       ├── drawable
        │       │   └── icon.png
        │       ├── layout
        │       │   └── main.xml
        │       └── values
        │           └── strings.xml
        └── java
            └── org
                └── eoti
                    └── android
                        └── test
                            └── fragments

13 directories, 6 files

While it should be possible to use the Fragments with pre-HONEYCOMB (; but for now, let's just try it in the ICS emulator.

Based on the available jars in (||android||jar) let's set the version of the Android dependency in the pom to

Also, change the <sdk><platform>10</platform></sdk> to <sdk><platform>14</platform></sdk>.

For now, comment out the maven-jarsigner-plugin as that requires setting up a keystore.
You'll also need to comment out the <sign /> portion of the android-maven-plugin.

Start up an ICS emulator and try 'mvn clean install' just to make sure we are able to grab the dependencies.
Launch the FragmentTest and you should see your hello world.

Let's move on to adding fragments... this part is derived from
I've modified their instructions quite a bit to fit into our Maven structure as well as to make things more clear (they had ListFragment extends ListFragment which tends to confuse people).

First, copy src/main/android/res/layout/main.xml to src/main/android/res/layout/detail.xml
On the new detail.xml, give the TextView an id:

Now, we'll deal the with portrait layout for FragmentTestActivity:
Replace the TextView in the layout/main.xml with:

Now, let's modify it for landscape...

Copy src/main/android/res/layout/main.xml to src/main/android/res/layout-land/main.xml [note: you will have to create the layout-land directory]

Now, for the layout-land/main.xml:
1. change the LinearLayout to Horizontal:
2. copy/paste the fragment so you now have 2 of them
3. for the first one. let's change the width to:
4. for the second one, change the id to:
5. Change the class to

Note: I changed the name of these classes so it would be obvious that these are our classes, and not some default Android implementation. Perhaps a redundant point since we also set the package name.

We'll need to have a separate activity for the detail portion in portrait mode, so let's create the layout for that.
Copy src/main/android/res/layout-land/main.xml to src/main/android/res/layout/details.xml [note: plural details not detail]

For the new details.xml:
1. change the LinearLayout back to Vertical:
2. remove the ftListFragment <fragment />

We already have our main FragmentTestActivity.  We are missing our DetailActivity. Let's do some more copy/paste.
Copy to (in the same directory)
Let's edit
1. Change the class name to DetailActivity [I'd change the TAG to match]
2. change the setContentView to R.layout.details
3. add the following just after setContentView:
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            TextView view = (TextView) findViewById(;
4. Make sure to add the import android.widget.TextView;

We've defined two fragments in the layouts.  We need to create those.
First, we'll create our src/main/java/org/eoti/android/test/fragments/
This one is pretty simple:


import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class FTDetailFragment extends Fragment
    public void onCreate(Bundle savedInstanceState) {

    public void onActivityCreated(Bundle savedInstanceState) {

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.detail, container,  false);

    public void setText(String key)


Next, we'll create our src/main/java/org/eoti/android/test/fragments/
This one isn't much more difficult:


import android.*;
import android.R;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;

public class FTListFragment extends ListFragment
    public void onCreate(Bundle savedInstanceState) {

    public void onActivityCreated(Bundle savedInstanceState) {
        ArrayList keys = new ArrayList(System.getProperties().keySet());
        ArrayAdapter adapter = new ArrayAdapter(getActivity(), R.layout.simple_list_item_1, keys);

    public void onListItemClick(ListView l, View v, int position, long id) {
        String key = getListAdapter().getItem(position).toString();
        FTDetailFragment fragment = (FTDetailFragment)getFragmentManager().findFragmentById(;
        if(fragment != null)
            Intent intent = new Intent(getActivity().getApplicationContext(), DetailActivity.class);
            intent.putExtra("key", key);

Last, but not least, we need to add the other activity to your AndroidManifest. Put this inside your <application /> tag.
          <activity android:name=".DetailActivity" />

mvn clean install

Launch the application (in portrait mode, I assume)
Select something. You should see a new activity popup with the value of the property you chose.
Hit back, and try it a few times.
When you are done, rotate the emulator using CTRL-F11.  I'm not sure about anyone else, but I have to hit it twice quickly or it won't rotate.
Now, when you select an item on the left, the answer is on the right.
When you are done playing with it, CTRL-F12 [twice in my case] to go back to portrait.

UPDATE: If you wish to use it with older devices...
First, I used the  maven-android-sdk-deployer to create the maven-compliant compat library for me.


This allows older versions of Android to use the Fragments. In my case, I tested against an Android 2.3.3 emulator.

I made no other changes to the pom.  IE: I compiled against a newer SDK and deployed against both.

Other changes to make:
  1. make FTDetailFragment extend
  2. make FTListFragment extend
  3. make DetailActivity extend
  4. make FragmentTestActivity extend
  5. In FTListFragment, instead of using getFragmentManager you need to call getSupportFragmentManager.  This is part of the FragmentActivity, so you will need to do something like:

mvn clean install and it should all work... close down the 2.3.3 emulator, start up an ICS emulator and.. it will still work ;)