Android - Determine which app is drawing on top of other apps?
Note:
- adb should already be setup in PC.
- For Android earlier than version 4.4.x, root access may be required.
- Some commands would not work on Android earlier than version 5.1.
- Jump to heading "Apps for apps" if you're unfamiliar or uncomfortable with command-line and/or the command-line fails to solve your issue.
Edit: cut the chase in the earlier solution and follow this edited section only.
Setup adb and run this command:
adb shell "dumpsys window windows | toybox grep -i system_alert_window"
You would get the output of all the active overlays on the screen. Example of an output with DU Screen Recorder, Tasker and AZ Screen Recorder showing active overlays on screen:
bash-4.3# adb shell "dumpsys window windows| toybox grep -i system_alert_window" mOwnerUid=10087 mShowToOwnerOnly=true package=net.dinglisch.android.tasker appop=SYSTEM_ALERT_WINDOW mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW mOwnerUid=10649 mShowToOwnerOnly=true package=com.duapps.recorder appop=SYSTEM_ALERT_WINDOW mOwnerUid=10649 mShowToOwnerOnly=true package=com.duapps.recorder appop=SYSTEM_ALERT_WINDOW mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW mOwnerUid=10638 mShowToOwnerOnly=true package=ninja.sesame.app.edge appop=SYSTEM_ALERT_WINDOW
The highlighted text next to package= and before appop is the package name(s) of the app(s) currently drawing overlay on the screen. In your case, the output including the package name(s) would differ.
Note down the package name(s) (henceforth as PKG) and execute this command:
adb shell am force-stop PKG
Replace PKG with the package name you noted down. If you had multiple package names, repeat the command with one package name at a time.
The command would forcefully stop the app and thereby discard the overlay. This should work. You may alternatively strip the permission of "Draw over other apps" (screen overlay in short) from the apps using this command:
adb shell appops set PKG SYSTEM_ALERT_WINDOW ignore
Again, replace PKG with package name as necessary. Furthermore, you may have to repeat the force-stop command for the PKG. If you decide to revert the changes, replace ignore with allow in aforesaid command.
You may alternatively use App Ops to manage the permissions from GUI.
To know which package name corresponds to which app you could try an open source app like Applications Info. Search by package name and you would get the App's name.
Edit finished
You really need not to read anymore now. I'm leaving the earlier solution (i.e. following section) intact because 21 people who voted it did find that helpful and I don't want to mess up anymore.
A simple way would be to find out all the apps having the permission "draw over other apps" and then single out them from the ones currently active on the screen. Afterwards, engage in force-stopping those common apps until you pin-point the app responsible for the active overlay.
Enumerate apps having permission for overlay
The permission required by an app to create an overlay is android.permission.SYSTEM_ALERT_WINDOW
(draw over other apps).
We need to find out all the installed apps having the said permission. It is up to you to find out a method for this. My answer here may aid you.
Note that we need the apps' package names and not their labels.
Cherry-pick from active windows
Execute the command
adb shell dumpsys window windows
This would give you details on whatsoever causing something to be displayed on the screen, including the component name of an app causing it.
How you would extract the name is up to you. You may try this command however
adb shell 'dumpsys window windows | grep "Window #"'
If you receive the error: 'grep' is not recognized as an internal or external command, on Windows try this alternative command:
adb shell "dumpsys window windows | grep 'Window #'"
Demo output
Window #4 Window{42065d50 u0 com.android.phone/com.mediatek.phone.UssdAlertActivity}: Window #5 Window{42197468 u0 ginlemon.flowerpro/ginlemon.flower.HomeScreen}: Window #6 Window{420fdb58 u0 com.android.systemui.ImageWallpaper}: Window #7 Window{421e3b88 u0 com.android.contacts/com.android.contacts.activities.DialtactsActivity}:
In the above output, anything succeeding u0
and preceding /
is the package name of an app. An app can have multiple components displaying something on the screen.
You've to create a list of those package names. If you have BusyBox installed, you can do
adb shell 'dumpsys window windows | grep "Window #" | sed -e "s/.*u0 //g" -e "s/\/.*//g" -e "s/}://g"'
Anyhow, now you would be having two lists:
- First list contains all the apps having the permission
android.permission.SYSTEM_ALERT_WINDOW
. - Second list contains all the apps actively displaying something on the screen.
Compare these two lists and single out apps which are common in both the lists. This third list would constitute of apps having the permission to draw overlay and are currently drawing an active overlay on screen.
Time to kill
Kill each of the apps from the third list one by one and notice the state of overlay. You can use am force-stop PACKAGE_NAME --user 0
or any other method that suits you. PACKAGE_NAME
is the package name of the app.
EDIT: It is not necessary to kill an app. You can consider denying the app the permission to draw over other apps. Use this command:
adb shell 'appops set PACKAGE SYSTEM_ALERT_WINDOW deny' # replace PACKAGE with package name of the app
To revert the changes, replace deny with allow in the said command and execute it.
If you're running Android Marshmallow, this answer by Andrew T. can be used.
Note: The aforesaid command is successfully tested on Android 5.1.1 and 6.0.1 (CM builds). It is also possible that the command works on Android 5.0.x but I can't guarantee. Execution of that command on Android version released prior to Lollipop would cause failure.
Since often the overlay is perceivable, it would instantly disappear the moment the app causing it is killed, hence, you would know which app was causing that overlay.
Apps for apps
Originally suggested by Izzy, you can use an app which has the functionality of listing permissions granted to installed apps, to single out the apps having the permission "draw over other apps". You can either search such an app on your own or use the the list Permission checker maintained by Izzy on his website.
You would also need a process/app manager to force-stop/kill some processes. I recommend OS Monitor but you're at liberty to use any competent app. See related apps under System Info.
For demonstration purposes only
I tried Advanced Permission Manager to list apps with permission to "draw over other apps". Afterwards, I switched to OS Monitor to see the apps running in foreground and background. I matched the output from both the apps and individually force-stopped the apps common in both. You can kill a process from inside the OS Monitor, so no need to switch to App settings.
(Click image to enlarge)
If you're using Android 6.0 Marshmallow, you can use its native permissions manager.
From an article on BGR,
Android 6.0 Marshmallow has a lot of highly anticipated new features and one of them is something iPhone users have had for years: Granular app permissions. Phone Arena installed the latest developer preview of Marshmallow and posted some terrific tips to help Android users make sure they’re only sharing data with apps that they specifically want to share.
To access Marshmallow’s permissions management feature, you’ll want to open up your Settings menu and then click on the Apps section. From there, click on the Gear icon that will then give you the option to go to app permissions manager.
To list the apps that can draw over other apps, go to Settings - Apps - Advanced (menu with gear icon) - Draw over other apps.
You can also enable/disable the feature temporarily by tapping the app, and toggle the "Permit drawing over other apps".
Image courtesy of Sebastiano Gottardo on Medium
Thanks a bunch @Firelord ! I have finally found the app which has been preventing me from installing apk's and performing adb backups.
For me I found it was an app called Battery Mix
Read on to see what I did and how I did it.
https://play.google.com/store/apps/details?id=jp.smapho.battery_mix
Many people have had issues with Installing apk's and not being able to press 'Install'. All answers I could find were mainly down to display dimming,tinting,power-saving apps. As I didn't use any or had removed all similar apps I had been struggling to find what was going on and which app was the culprit. And finally! After one simple command and a quick search, it has been solved :D
The offending app Battery Mix
is a simple battery monitoring app which had the function I used to displayed a thin line across the top of the screen to show the state of the battery level (a great little app).
So to diagnose, I used a command from Firelord
(above) to dump a text file and then to search for the app which was causing the android system to prevent me form clicking that Install button.
Execute command from PC
adb shell dumpsys window windows > dumpsys-windows.txt
Search for
SYSTEM_ALERT_WINDOW
To find any offending applications I searched for the above string
Which gave me the line:
mOwnerUid=10129 mShowToOwnerOnly=true package=jp.smapho.battery_mix appop=SYSTEM_ALERT_WINDOW
(See image upload for the section of text file)
immediately I could recognise which app it was referring to: jp.smapho.battery_mix
So now I know to kill that app whenever I plan to sideload or befor adb backups.