Skip to content

How to write an ADB command to launch an app

Doug Nelson edited this page Oct 17, 2024 · 1 revision

ADB commands are the fastest and most reliable way to launch applications on your Android based media player devices. So, how do we write one that actually works? Great question!

Requirements:

  • A device to receive an ADB command
  • A way to send commands and see the response

The Easy Way

As outlined in this tutorial using the following ADB command after launching the app on your device will provide you with the output that you need:

adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp|mInputMethodTarget|mSurface'

Using Netflix as an example, running this command will return this result:

adb_response: mSurface=Surface(name=com.netflix.ninja/com.netflix.ninja.MainActivity)/@0xaf2310 mSurface=Surface(name=com.android.systemui.ImageWallpaper)/@0xc578b22 mInputMethodTarget in display# 0 Window{7707ec6 u0 com.netflix.ninja/com.netflix.ninja.MainActivity}

In this response, we find looking for in two places. com.netflix.ninja/com.netflix.ninja.MainActivity

This can be broken down into two sections:

  • The app name: com.netflix.ninja
  • The activity or intent: com.netflix.ninja.MainActivity

In the case of Netflix and maybe around 80% - 90% of the apps you will find, the ADB command that will launch this app for us will look like this:

adb shell am start -n com.netflix.ninja/com.netflix.ninja.MainActivity

Breaking it down

  • adb shell All ADB commands begin this way
  • am start -n Instructs the Activity Manager (am) to Start (start) an activity by its name (-n)
  • com.netflix.ninja/com.netflix.ninja.MainActivity The name of the app followed by the name of the intended activity in that app

That's it! It's as simple as that! unless...


When you need to dig deeper

What happens when you do all of that and it still doesn't work? In this case, we will have to learn more about the app itself and not rely on just looking at what it tells us is currently active.

For this example, let's use the Deezer app that was requested in #433 a while ago. When you follow the procedure above, you get this result (or similar)

adb_response: mSurface=Surface(name=)/@0x7af3d9 mSurface=Surface(name=deezer.android.tv/com.deezer.android.tv.ui.feature.authentication.AuthenticationActivity)/@0x3279e6c mSurface=Surface(name=com.android.systemui.ImageWallpaper)/@0x2ccc676 mCurrentFocus=Window{71a1937 u0 deezer.android.tv/com.deezer.android.tv.ui.feature.authentication.AuthenticationActivity} mFocusedApp=AppWindowToken{6762a0c token=Token{c5b413f ActivityRecord{9e4395e u0 deezer.android.tv/com.deezer.android.tv.ui.feature.authentication.AuthenticationActivity t4796}}}

So, the next logical step is to write this command and assume it will work:

adb shell am start -n deezer.android.tv/com.deezer.android.tv.ui.feature.authentication.AuthenticationActivity


But when you run that command, nothing happens. That's frustrating. When we take a look at the response our device sent us after issuing that command, we see this permissions error message:

adb_response: Starting: Intent { cmp=deezer.android.tv/com.deezer.android.tv.ui.feature.authentication.AuthenticationActivity }

Exception occurred while executing 'start': java.lang.SecurityException: Permission Denial: starting Intent { flg=0x10000000 cmp=deezer.android.tv/com.deezer.android.tv.ui.feature.authentication.AuthenticationActivity } from null (pid=8034, uid=2000) not exported from uid 10248 at com.android.server.wm.ActivityStackSupervisor.checkStartAnyActivityPermission(ActivityStackSupervisor.java:1032) at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1021) at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672) at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1100) at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1072) at com.android.server.am.ActivityManagerService.startActivityAsUserWithFeature(ActivityManagerService.java:3680) at com.android.server.am.ActivityManagerShellCommand.runStartActivity(ActivityManagerShellCommand.java:553) at com.android.server.am.ActivityManagerShellCommand.onCommand(ActivityManagerShellCommand.java:187) at android.os.BasicShellCommandHandler.exec(BasicShellCommandHandler.java:98) at android.os.ShellCommand.exec(ShellCommand.java:44) at com.android.server.am.ActivityManagerService.onShellCommand(ActivityManagerService.java:10611) at android.os.Binder.shellCommand(Binder.java:929) at android.os.Binder.onTransact(Binder.java:813) at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:5027) at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2885) at android.os.Binder.execTransactInternal(Binder.java:1159) at android.os.Binder.execTransact(Binder.java:1123)


To move ahead we need to take the app name that we already found (deezer.android.tv) and use it in a different ADB Shell command.

adb shell pm dump deezer.android.tv

This command tells the Android process manager (pm) to dump what it knows about the deezer.android.tv app. It has A LOT to say! The section of this reply that we need to look at is labeled Non-Data Actions:

   Non-Data Actions:
      com.sonymobile.media.dashboard.ACTION_VIEW_MUSIC_TILE:
        a5974eb deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity filter f72fde
          Action: "com.sonymobile.media.dashboard.ACTION_VIEW_MUSIC_TILE"
      android.intent.action.MEDIA_SEARCH:
        a5974eb deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity filter df6606
          Action: "android.intent.action.MEDIA_SEARCH"
          Category: "android.intent.category.DEFAULT"
      android.intent.action.MAIN:
        a5974eb deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity filter 2789248
          Action: "android.intent.action.MAIN"
          Category: "android.intent.category.LEANBACK_LAUNCHER"
          Category: "android.intent.category.LAUNCHER"
        a5974eb deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity filter 4d1b21d
          Action: "android.intent.action.MAIN"
          Action: "android.intent.action.MUSIC_PLAYER"
          Category: "android.intent.category.DEFAULT"
          Category: "android.intent.category.APP_MUSIC"
        a5974eb deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity filter 63d6260
          Action: "android.intent.action.MAIN"
          Category: "android.intent.category.LAUNCHER"
 ...

This app has a lot more to sort through than most, but don't be intimidated. What we need to find is a replacement for the deezer.android.tv/com.deezer.android.tv.ui.feature.authentication.AuthenticationActivity command that didn't work.

The most suitable replacement command will be found around some keywords like MAIN, LAUNCHER, or LEANBACK_LAUNCHER and we have a section above with all of those things in it!

      android.intent.action.MAIN:
        a5974eb deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity filter 2789248
          Action: "android.intent.action.MAIN"
          Category: "android.intent.category.LEANBACK_LAUNCHER"
          Category: "android.intent.category.LAUNCHER"

Do you see it? Do you see the ADB launch command we need to try next? Let's send it!

adb shell am start -n deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity

IT WORKS! The command started the app, and we received this instead of an error message

adb_response: Starting: Intent { cmp=deezer.android.tv/com.deezer.android.ui.activity.LauncherActivity }

Clone this wiki locally