Mobile Development 9 min read

Effective Screenshot Capture in Android Black‑Box Testing Using ActivityController and ProcessObserver

This article explains how to implement reliable screen‑capture during Android black‑box testing by leveraging ActivityController, custom Shell services, IProcessObserver, and optional root‑level getevent commands, providing code examples and an integrated workflow for detecting page changes and handling crashes.

360 Quality & Efficiency
360 Quality & Efficiency
360 Quality & Efficiency
Effective Screenshot Capture in Android Black‑Box Testing Using ActivityController and ProcessObserver

The article introduces common challenges in Android black‑box testing for capturing useful screenshots and proposes three main approaches: using third‑party screenshot services, implementing a custom Shell service started via app_process , and employing ActivityController to monitor activity changes.

It recommends a custom Shell service because it continues running even if the test script crashes and works on Android R and later where uiautomator 1.0 is no longer supported. The service records screenshots on activity changes, process state changes, and app crashes or ANRs.

To capture activity changes, the article shows how to register an IActivityController implementation:

IActivityController mActivityController = new IActivityController.Stub() { @Override public boolean activityStarting(Intent intent, String pkg) throws RemoteException { return true; } @Override public boolean activityResuming(String pkg) throws RemoteException { return true; } @Override public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, long timeMillis, String stackTrace) throws RemoteException { return false; } @Override public int appEarlyNotResponding(String s, int i, String s1) throws RemoteException { return 0; } @Override public int appNotResponding(String processName, int pid, String processStats) throws RemoteException { return -1; } @Override public int systemNotResponding(String msg) throws RemoteException { return 0; } };

The article also discusses drawbacks of ActivityController, such as interference when multiple processes register the service and the inability to detect fragment switches.

To complement ActivityController, it introduces IProcessObserver for monitoring process lifecycle events, providing code:

IProcessObserver mProcessObserver = new IProcessObserver.Stub() { @Override public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) throws RemoteException { /* handle */ } @Override public void onProcessStateChanged(int pid, int uid, int importance) throws RemoteException { } @Override public void onProcessDied(int pid, int uid) throws RemoteException { } };

Both services are combined into an integrated workflow: ActivityController detects page changes, IProcessObserver validates them, a timer captures screenshots every 2 seconds, compares the new bitmap with the previous one using image similarity (threshold 0.8), and re‑registers the ActivityController if no updates occur within 5 seconds.

For rooted devices, the article presents a special method using the Linux getevent command to read raw touch events (e.g., ABS_MT_POSITION_X/Y, BTN_TOUCH) and derive click or swipe actions, which can then trigger screenshot capture and optionally draw the event trajectory on the image.

AndroidautomationshellScreenshotblack-box testingactivitycontrollerprocessobserver
360 Quality & Efficiency
Written by

360 Quality & Efficiency

360 Quality & Efficiency focuses on seamlessly integrating quality and efficiency in R&D, sharing 360’s internal best practices with industry peers to foster collaboration among Chinese enterprises and drive greater efficiency value.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.