December 19, 2015

Android Shell. Part 2: Starting Сomponents You Need – The Activity Manager Client

This is the second post in the series about useful commands in Android Shell. Make sure you’ve read the first one on Mocking Battery Status.

With Android Studio you can configure what activity is launched when you run a developed mobile app. This can be very useful when you want to test a particular screen. A recent Instant Run feature advances this even further and completely changes the Android development experience.

But what if you want to test how your Activity handles different Intent data or want to test a service or a broadcast receiver? Activity manager client available in the command line will help in this case.

Here’s how we can pass a specific extra to your activity:

$ adb shell am start -n your.pckg.name/.MainActivity \

   -e name1 string-value -ei name2 21

This would start an activity and the following code would pass in onCreate():

Intent intent = getIntent();

assert "string-value".equals(intent.getStringExtra("name1"));

assert intent.getIntExtra("name2", -1) == 21;

And here’s how we can open Twitter application to view a post:

$ adb shell am start -a android.intent.action.VIEW \

   -c android.intent.category.BROWSABLE \

   -d https://twitter.com/roman_mazur/status/672758680669036545

In fact this will simulate an Intent sent by a browser when some link is clicked on a page.

Starting a Service is not harder: simply replace start with startservice. Options you can use to specify an Intent remain the same.

$ adb shell startservice -n your.pckg.name/.YourPlaybackService \

   -a your.pckg.name.action.START

In your onStartService  on onHandleIntent  (if you use an IntentService) the following would pass:

assert "your.pckg.name.action.START".equals(intent.getAction())

But remember that only exported components can be started from shell. Otherwise you can activate them only from your internal process. Components can be exported implicitly if they get an intent filter definition in your manifest. Or explicitly, if you specify android:exported=”true” on your component element.

You usually do not want your components to be exported for security sake. To avoid changing your manifest on every run from shell you can add explicit exported attributes to the debug manifest of your app leveraging Android build system.

To finish this post let’s configure Android system status bar to display icons you want using a simple demo mode intent protocol it supports since KitKat.

To enable this demo mode we’ll need to change a special system setting first:

$ adb shell settings put global sysui_demo_allowed 1

Now we can use the activity manager client to send command to system UI. The following command will remove all the notification icons from the status bar:

$ adb shell am broadcast -a com.android.systemui.demo -e action enter

$ adb shell am broadcast -a com.android.systemui.demo \

   -e action notifications -e visible false

This way you will get rid of the debug icon on your screenshots. You will find a complete documentation and more examples in AOSP sources.

Do not forget to exit the demo mode:

$ adb shell am broadcast -a com.android.systemui.demo -e action exit

We’ll talk more about different Android system settings in the future posts. Stay tuned!