Track down the source of android toast
There are many ways to tell which app sends a toast, the most quickest way is to install third-party app such as Toast Source or Toaster, if you don’t want to install apps, then the following method can do the job.
Use dumpsys
AppOps service of dumpsys can show app operations such as READ/WRITE external storage, it can also show which app sends an toast with specific time when it sends it and its duration, like this:
$ dumpsys appops
...
Uid u0a75:
state=top
startNesting=1
Package com.sdsmdg.demoexample:
TOAST_WINDOW (allow):
Access: top = 2019-08-03 17:21:42.853 (-3s933ms)
Running start at: +3s933ms
startNesting=1
READ_EXTERNAL_STORAGE (allow):
Access: cch = 2019-08-03 17:21:20.630 (-26s156ms)
WRITE_EXTERNAL_STORAGE (allow):
Access: cch = 2019-08-03 17:21:20.630 (-26s156ms)
...
The above example was generated by TastyToast, before build, commit 1c7bd7 needs to be applied to avoid build failure.
export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
echo 'sdk.dir = /opt/sdk' > local.properties
./gradlew assemble
This method can be used to find which package sends a toast after you see it.
Use uiautomator
Another way is via uiautomator, but you need to issue command before the toast was sent, if a toast shows up, an event with type of TYPE_WINDOW_CONTENT_CHANGED will be shown in the log, the toast message can also be seen in the log:
$ uiautomator events
Use Accessibility service
There is an answer in stackoverflow mentioned AccessibilityService
can be extented by overriding method onAccessibilityEvent()
like this to show
which package sends a toast or notification:
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() != AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)
return; // event is not a notification
String sourcePackageName = (String) event.getPackageName();
Parcelable parcelable = event.getParcelableData();
if (parcelable instanceof Notification) {
// Statusbar Notification
}
else {
// something else, e.g. a Toast message
String log = "Message: " + event.getText().get(0)
+ " [Source: " + sourcePackageName + "]";
// write `log` to file...
}
}
This should work, but not tested.