Programmatically Connect and Disconnect Android Device
Asked Answered
M

4

17

I need to find a way to (using an Android application) programmatically connect and disconnect an Android device from a host.

I am using a Galaxy Nexus. My goal is to keep everything as close to stock as possible, though I have already enabled verbose debug messages in the kernel and in order to view them have enabled root access on the phone to access /proc/kmsg (and the shell command dmesg).

I am certain that there is a way to leverage root access to do what I need to do, but all of my attempts have lead to nix.

  • Mess with /proc/bus/usb
  • Mess with /dev/bus/usb
  • Change between MTP/PTP (unable to do programatically)
  • Making the Android USB gadget driver into a module <- ???

I am going to try to figure out how to do the last object on the list, as then I would be able to rmmod and insmod the resulting *.ko in my application and that would connect and disconnect the phone. I am unsure of the feasibility of this option though.

Mattah answered 19/10, 2012 at 17:45 Comment(4)
I was able to make the android usb gadget driver into a module, then the issue arose of trying to run the kernel w/out the module built-in.Mattah
So using the developer page as a guide, if you have an open and close method for your device then couldn't you just call those to "disconnect" and "reconnect" you device? Or I may not be understanding quite what you are trying to do...?Gave
If PTP works with android cant you control it with that?Duluth
I am looking at dankulp.com/ptpfsDuluth
M
1

Solution came when close to a deadline, so I am almost sure it is not the best way of doing things, but it met my requirements.

Build Modded kernel (to allow hooking of particular function)

  • Modify kernel config to support Kprobes (set CONFIG_KPROBES to Y)
  • Remove "static" keyword from android_setup() definition (driver/usb/gadget/android.c)
  • Build that kernel

Build kernel module (which gives the actual functionality of connecting and disconnecting)

  • Use Kallsyms to dynamically pull the absolute address of android_setup()
  • Using kprobes, hook android_setup()
  • Set up two timers to execute every time android_setup() is called
  • First timer set for 2 seconds from now, Second set for 2.005 seconds from now
  • Both timers take a pointer to the struct usb_gadget as their data
  • In respective callback functions, call usb_gadget_connect() and usb_gadget_disconnect(), which forces physical disconnect followed by reconnect on the Samsung Galaxy Nexus

Build Application

  • Gotta have a rooted device
  • Simply make a shell call with SU privilege - "insmod module_name." Until you call rmmod, the module will force the device into an enumeration cycle, disconnecting and reconnecting continuously.

If you are interested in repeating these results, read the document posted here and feel free to send me any questions.

https://docs.google.com/uc?export=download&id=0B9WchRkSOWwJbi10MGhLWUljT2s

Mattah answered 13/2, 2014 at 23:56 Comment(0)
K
0

You can try to enable/disable some secured settings like Settings.Secure.USB_MASS_STORAGE_ENABLED or Settings.Secure.ADB_ENABLED (depending on what you call "connect" !)

This code should work (disabling USB mass storage):

Settings.Secure.putInt(getContentResolver(),Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);

Krauss answered 3/4, 2013 at 10:42 Comment(0)
B
0

Settings.Secure.putInt(getContentResolver(),Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);

Beestings answered 23/4, 2013 at 5:26 Comment(0)
S
0

InternetControl.java

public class InternetControl {
    public static void EnableInternet(Context context)
    {
        try {
            Log.i("Reached Enable", "I am here");
            setMobileDataEnabled(context,true);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } 
    }

    public static void DisableInternet(Context context)
    {
        try {
            Log.i("Reached Disable", "I am here");
            setMobileDataEnabled(context,false);
        } catch (Exception e) {
    System.out.println(e.getMessage());
        } 
    }

    private static void setMobileDataEnabled(Context context , boolean enabled) throws Exception{
           final ConnectivityManager conn = (ConnectivityManager)  context.getSystemService(Context.CONNECTIVITY_SERVICE);
           final Class connClass = Class.forName(conman.getClass().getName());
           final Field iConnectivityManagerField = connClass.getDeclaredField("mService");
           iConnectivityManagerField.setAccessible(true);
           final Object iConnectivityManager = iConnectivityManagerField.get(conn);
           final Class iConnectivityManagerClass =  Class.forName(iConnectivityManager.getClass().getName());
           final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
           setMobileDataEnabledMethod.setAccessible(true);
           setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
        }

}

Manifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET" />

Enable or Disable function are static so you can call by using
classname.functionname();

Silicosis answered 8/1, 2014 at 15:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.