-
-
Notifications
You must be signed in to change notification settings - Fork 72
How to write an ADB command to launch an app
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
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...
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 }