假设我们有一个Android设备,并且在该设备上有1个以上的应用程序能够创建自己的浮动窗口(例如,持有SYSTEM_ALERT_WINDOW
权限)。另外,当然,可以有其他窗口不一定是独立浮动的(Spinner
,Dialog
等等。所有窗口都通过WindowManager
创建自己的窗口,仅用于在现有活动上显示)。
鉴于我从开发人员工具知道窗口内的像素坐标,我如何确定创建包含该像素的窗口的进程或应用程序? IOW,我怎样才能找出应该为某个窗口的存在负责的人呢?
我认为也许adb shell dumpsys window
会有这些信息,但如果确实如此,我就没有看到它。
请注意,我很乐意找到涉及开发工具的解决方案。我希望没有特殊权限,在运行时确定这些信息是困难的或不可能的。
答案 0 :(得分:2)
运行此命令adb shell dumpsys input
会给我以下输出:
[...bunch of stuff...]
6: name='Window{5e9310c u0 com.example.overlayservice/com.example.overlayservice.MainActivity}',
displayId=0, paused=false, hasFocus=true, hasWallpaper=false,
visible=true, canReceiveKeys=true, flags=0x81810120, type=0x00000001, layer=21010,
frame=[0,0][1440,2560], scale=1.000000, touchableRegion=[0,0][1440,2560],
inputFeatures=0x00000000, ownerPid=4086, ownerUid=10083, dispatchingTimeout=5000.000ms
[...bunch more stuff..]
由于我支持这个,我知道应用程序是" Overlay Service"它只是显示一个系统窗口。 "框架"信息将绑定像素和" ownerUid"会提供有关所有者的更多信息。 (我认为这个命令不仅仅是伪装的dumpsys window
命令,而且不适合你。)
虽然它并不是这个应用程序中的一个像素"映射,假设您在设备上看到相同的信息,这种技术可以帮助减少目标。
<强>交替强>
如果您有权访问设备或在模拟器上,以下是更直接的方法。
根据Input Dispatcher State类别下的dumpsys
文档,
输入调度员状态
InputDispatcher负责向应用程序发送输入事件。如下面的示例输出所示,其状态转储显示有关正在触摸的窗口,输入队列的状态,ANR是否正在进行等的信息。
进一步阅读:
触摸触摸屏并同时运行dumpsys后,TouchStates行正确识别您正在触摸的窗口。
具体来说,字符串&#34; TouchStates:...&#34;将在我们运行dumpsys
时确定我们正在触摸的窗口。
因此,我们应该能够运行dumpsys input
并查找字符串TouchStates
并打印以下几行以标识窗口。这是我的Windows命令行:
timeout 3 & adb shell dumpsys input | grep TouchStates -A 5
这是输出,将Window{e3cd95d u0 com.example.overlayservice/com.example.overlayservice.MainActivity}'
标识为被触摸的窗口。
TouchStatesByDisplay: 0:down = true,split = true,deviceId = 0,source = 0x00001002 视窗: 0:name =&#39; Window {e3cd95d u0 com.example.overlayservice / com.example.overlayservice.MainActivity}&#39;,pointerIds = 0x80000000,targetFlags = 0x107 视窗: 0:name =&#39; Window {ef28ce5 u0 NavigationBar}&#39;,displayId = 0,paused = false,hasFocus = false,hasWallpaper = false,visible = true,canReceiveKeys = false,flags = 0x21840068 ,type = 0x000007e3,layer = 231000,frame = [0,1794] [1080,1920],scale = 1.000000,touchableRegion = [0,1794] [1080,1920],inputFeatures = 0x00000000,ownerPid = 1632,ownerUid = 10027,dispatchingTimeout = 5000.000ms
如果没有触摸任何窗口,您将看到TouchStates: <no displays touched>
。
答案 1 :(得分:1)
来自adb shell dumpsys window
:
Window#3 Window {41b85d98 u10 com.example.app}: mDisplayId = 0 mSession = Session {41bc2e38 10536:u10a10030} mClient=android.os.BinderProxy@41b064c0 mOwnerUid = 1010030 mShowToOwnerOnly = true package = com.example.app appop = SYSTEM_ALERT_WINDOW mAttrs = WM.LayoutParams {(0,0)(395x110)gr =#55 sim =#20 ty = 2003 fl =#20008 fmt = -3} 要求w = 395 h = 110 mLayoutSeq = 1200 mHasSurface = true mShownFrame = [885.0,642.0] [1280.0,752.0] isReadyForDisplay()= true WindowStateAnimator {41d4d2a8}: 表面:显示=真实层= 91000 alpha = 1.0 rect =(885.0,642.0)395.0 x 110.0
在我看来,mShownFrame变量保存了确定窗口是否包含像素所需的数据。
答案 2 :(得分:1)
此选项如何:adb shell dumpsys window windows visible-apps
?
它打印可见窗口列表,每个窗口包含以下字段:
mOwnerUid
,package
,mFrame
,mShownPosition
,mIsFloatingLayer
等。
答案 3 :(得分:0)
我希望在运行时确定这些信息 没有特权的困难或不可能
最新的Android版本被大量锁定,以防止恶意软件欺骗&#34;信任&#34;网上银行应用程序等应用程序。
即使知道通过/proc
文件系统正在运行的其他进程现在也受到限制,因此您似乎不可能在不使用平台的情况下知道像素所有权(这将是获得相同的后门/proc
的信息将公开当前的前台进程。)