Search code examples
androidcommand-lineandroid-serviceadb

Start an Android Service from Command Line in Version-Agnostic way


A 4.0.4 device will start a server successfully without a --user option, but fails with it. A 4.2.1 device requires the --user option and fails without it.

How can I start the service in a way that will work on all Android devices?

Or if not possible, what is the criteria to determine when the --user is needed?

$ adb shell getprop ro.build.version.release
4.0.4

$ adb shell am startservice --user 0 -ei 123 -a com.a.activity.myservice
Error: Unknown option: --user
usage: am [subcommand] [options] 
   { usage info deleted

$ adb shell getprop ro.build.version.release
4.2.1

$ adb shell am startservice  -ei 123 -a com.a.activity.myservice
Starting service: Intent { act=com.a.activity.myervice (has extras) }
~/dev/dcf/Applications/Spin (master) $ adb shell am startservice  -ei 123 -a com.a.activity.myservice
Starting service: Intent { act=com.apportable.a.myservice (has extras) }
java.lang.SecurityException: Caller uid=2000 is not privileged to communicate with user=-2
    at android.os.Parcel.readException(Parcel.java:1425)

Solution

  • After Alex's suggestion, I wrote the following python fragment:

        results = env.Execute([env['ADB'], 'shell', 'am'])
        if "--user" in results:
            user_option = "--user 0"
        else:
            user_option = ""
    
        exec_line = 'am startservice ' + user_option + ' -a ' + app_id + '.GdbServerService --es command start --es gdbserver_name ' + remote_gdbserver + ' --ei gdbserver_port ' + str(env['ANDROID_REMOTE_DEBUG_PORT'])