[英]How do apps detect that SAW permission is currently being used?
I've noticed many times, that when I use an app that uses SAW (system-alert-window, AKA "display over other apps) permission (example here ), and I open Chrome web browser and reach some website that requires a permission (example here , taken from here ), it won't let me grant/deny the permission:我多次注意到,当我使用使用 SAW(系统警报窗口,又名“在其他应用程序上显示”)权限的应用程序( 此处示例)时,我打开 Chrome web 浏览器并访问一些需要权限的网站(这里的例子,取自这里),它不会让我授予/拒绝许可:
I can't find how they did it, and from which Android version it's possible to check it.我找不到他们是怎么做到的,也不知道从哪个 Android 版本可以查到。
Sadly as much as I've searched, I actually had more questions.遗憾的是,尽管我搜索了很多,但实际上我还有更多问题。
For example, how come the web browser can't detect which app is showing on top, and tell us to disable it?例如,为什么 web 浏览器无法检测到哪个应用显示在顶部,并告诉我们禁用它?
Or, now that Android 12 might arrive, there seem to be a new permission to block SAW ( here ):或者,现在 Android 12 可能到达,似乎有一个新的权限来阻止 SAW( 此处):
HIDE_OVERLAY_WINDOWS Added in Android S
HIDE_OVERLAY_WINDOWS 添加于 Android S
public static final String HIDE_OVERLAY_WINDOWS Allows an app to prevent non-system-overlay windows from being drawn on top of it
public static final String HIDE_OVERLAY_WINDOWS 允许应用防止非系统覆盖 windows 在其上绘制
Constant Value: "android.permission.HIDE_OVERLAY_WINDOWS"
常数值:“android.permission.HIDE_OVERLAY_WINDOWS”
Perhaps for this case there aren't many that have asked about it, or for some reason I didn't choose the correct things to write in order to search for an answer.也许对于这种情况,没有多少人问过它,或者由于某种原因我没有选择正确的东西来写以寻找答案。
How can I detect if some app is using SAW permission while I show something?当我展示某些内容时,如何检测某些应用程序是否正在使用 SAW 权限?
Is there a way to detect which app does that?有没有办法检测哪个应用程序执行此操作?
What can the API offer for this, and from which version is it available? API 可以为此提供什么,它可以从哪个版本获得?
I remember I was told that accessibility can be used to draw on top.我记得有人告诉我可访问性可用于在顶部绘制。 Sadly I failed to find a tutorial on how to do this, and also of an example of such apps.
遗憾的是,我没有找到有关如何执行此操作的教程,也没有找到此类应用程序的示例。 Would this API be able to detect them too?
这个 API 也能检测到它们吗? Or this isn't considered as SAW?
或者这不被视为 SAW? Where can I find a tutorial on how to do it, so that I could check it out?
我在哪里可以找到有关如何操作的教程,以便我可以查看?
Bonus: how on Android S do you use the new permission to hide SAW?奖励:如何在 Android S 上使用新权限隐藏 SAW?
FLAG_WINDOW_IS_OBSCURED
(or FLAG_WINDOW_IS_PARTIALLY_OBSCURED
for API 29+):FLAG_WINDOW_IS_OBSCURED
(或FLAG_WINDOW_IS_PARTIALLY_OBSCURED
29+ 的 FLAG_WINDOW_IS_PARTIALLY_OBSCURED)检测 window 覆盖有一种常见的方法: Regarding Chrome, you can find the implementation in the source code: ModalDialogView.java#L203关于Chrome,可以在源码中找到实现: ModalDialogView.java#L203
Actually you can ask MotionEvents if the window is obscured (an alert is being shown over them) so you can tell that you're obscured, but you cannot tell which app is doing it实际上,您可以询问 MotionEvents window 是否被遮挡(在它们上方显示警报),这样您就可以知道您被遮挡了,但您无法确定哪个应用程序正在执行此操作
There are some similar questions that has required explanations How to detect when my Activity has been obscured?有一些类似的问题需要解释如何检测我的活动何时被遮挡?
Android detect or block floating/overlaying apps Android 检测或阻止浮动/覆盖应用程序
I'm not sure about item 4, but usually application who use accessibility to reas the screen and show you something magical (like that banned Voodoo app) also require SAW permission and as much as I can remember, Accessibility services are just some callbacks.我不确定第 4 项,但通常使用可访问性来查看屏幕并向您展示一些神奇的应用程序(例如被禁止的 Voodoo 应用程序)也需要 SAW 许可,据我所知,可访问性服务只是一些回调。
setHideOverlayWindows(true)
setHideOverlayWindows(true)
https://developer.android.google.cn/about/versions/12/features#hide-application-overlay-windows https://developer.android.google.cn/about/versions/12/features#hide-application-overlay-windows
OK I've made a sample to show all ways to detect it, including what happens when you use the new API ( setHideOverlayWindows ) to hide apps that are shown on top:好的,我制作了一个示例来展示检测它的所有方法,包括当您使用新的 API ( setHideOverlayWindows ) 隐藏顶部显示的应用程序时会发生什么:
manifest显现
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lb.detect_floating_app">
<uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" />
<application
android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true"
android:theme="@style/Theme.DetectFloatingApp">
<activity
android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.kt主活动.kt
class MainActivity : AppCompatActivity() {
var isObscured: Boolean? = null
var isPartiallyObscured: Boolean? = null
var isHidingFloatingApp = false
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(R.id.textView).setOnTouchListener(object : View.OnTouchListener {
var isObscured: Boolean? = null
var isPartiallyObscured: Boolean? = null
override fun onTouch(p0: View?, ev: MotionEvent): Boolean {
val checkIsObscured = ev.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0
val checkIsPartiallyObscured = ev.flags and MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED != 0
if (checkIsObscured != isObscured || checkIsPartiallyObscured != isPartiallyObscured) {
isObscured = checkIsObscured
isPartiallyObscured = checkIsPartiallyObscured
Log.d("AppLog", "${System.currentTimeMillis()} setOnTouchListener isObscured:$isObscured isPartiallyObscured:$isPartiallyObscured")
}
return false
}
})
findViewById<View>(R.id.toggleHideFloatingAppButton).setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
isHidingFloatingApp = !isHidingFloatingApp
window.setHideOverlayWindows(isHidingFloatingApp)
} else
Toast.makeText(this, "need Android API 31", Toast.LENGTH_SHORT).show()
}
}
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
val checkIsObscured = ev.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0
val checkIsPartiallyObscured = ev.flags and MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED != 0
if (checkIsObscured != isObscured || checkIsPartiallyObscured != isPartiallyObscured) {
isObscured = checkIsObscured
isPartiallyObscured = checkIsPartiallyObscured
Log.d("AppLog", "${System.currentTimeMillis()} dispatchTouchEvent isObscured:$isObscured isPartiallyObscured:$isPartiallyObscured")
}
return super.dispatchTouchEvent(ev)
}
}
FloatingDetectorFrameLayout.kt FloatingDetectorFrameLayout.kt
class FloatingDetectorFrameLayout : FrameLayout {
var isObscured: Boolean? = null
var isPartiallyObscured: Boolean? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
override fun onFilterTouchEventForSecurity(ev: MotionEvent): Boolean {
val checkIsObscured = ev.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0
val checkIsPartiallyObscured = ev.flags and MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED != 0
if (checkIsObscured != isObscured || checkIsPartiallyObscured != isPartiallyObscured) {
isObscured = checkIsObscured
isPartiallyObscured = checkIsPartiallyObscured
Log.d("AppLog", "${System.currentTimeMillis()} onFilterTouchEventForSecurity isObscured:$isObscured isPartiallyObscured:$isPartiallyObscured")
}
return super.onFilterTouchEventForSecurity(ev)
}
}
activity_main.xml activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"
android:orientation="vertical" tools:context=".MainActivity">
<com.lb.detect_floating_app.FloatingDetectorFrameLayout
android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#f00"
android:padding="100dp">
<Button
android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.lb.detect_floating_app.FloatingDetectorFrameLayout>
<Button android:id="@+id/toggleHideFloatingAppButton"
android:text="toggle hide floating app"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.