简体   繁体   English

AccessibilityService 如何利用其他应用程序?

[英]How does AccessibilityService draw on top of other apps?

Background背景

SAW (system alert window) permission can be used to draw content on top of other apps. SAW(系统警报窗口)权限可用于在其他应用程序之上绘制内容。

I was told a very long time ago that accessibility service can do this too, but I never found any tutorial, sample, documentation and even an app that does it... until recently:很久以前有人告诉我无障碍服务也可以做到这一点,但我从来没有找到任何教程、示例、文档甚至是可以做到这一点的应用程序......直到最近:

https://play.google.com/store/apps/details?id=com.github.ericytsang.screenfilter.app.android https://play.google.com/store/apps/details?id=com.github.ericytsang.screenfilter.app.android

In fact, this app seems to be able to draw everywhere, as opposed to SAW permission.事实上,这个应用程序似乎可以在任何地方绘制,而不是 SAW 许可。 It draws even on top of the settings app and system dialogs, while SAW permission isn't allowed as such.它甚至在设置应用程序和系统对话框的顶部绘制,而不允许 SAW 权限。

The problem问题

Sadly, as accessibility is quite a unique and rarely thing to use, just as I wrote, I couldn't find how such a thing works with drawing on top of other apps.可悲的是,由于可访问性是一种非常独特且很少使用的东西,就像我写的那样,我找不到这样的东西如何在其他应用程序之上绘图。

What I've found我发现了什么

The only thing I know is that this app somehow does it, and this is what it shows when it asks to grant it:我唯一知道的是这个应用程序以某种方式做到了,这就是它要求授予它时显示的内容:

在此处输入图像描述

But that's not enough.但这还不够。 I know that for some old POC I've made of using accessibility service, it showed the same, and checking it out, I can't see what triggers it.我知道对于我使用无障碍服务所做的一些旧 POC,它显示相同,并且检查它,我看不出是什么触发了它。 Pretty sure it's the minimal thing the users will see for any kind of accessibility service, so this won't help.可以肯定的是,对于任何类型的可访问性服务,用户都会看到最少的东西,所以这无济于事。

The questions问题

  1. How does AccessibilityService draw on top of other apps? AccessibilityService 如何利用其他应用程序?

  2. Does it work the same as SAW permission?它与 SAW 许可的工作方式相同吗? Can you, for example, handle touch events on what it draws?例如,你能处理它绘制的触摸事件吗?

  3. What are the restrictions of using it, if there are any?使用它有什么限制,如果有的话?

Using TYPE_ACCESSIBILITY_OVERLAY as type in the WindowManager.LayoutParams when adding the view from within the accessibility service seems to do the trick.从辅助功能服务中添加视图时,使用TYPE_ACCESSIBILITY_OVERLAY作为WindowManager.LayoutParams中的type似乎可以解决问题。 I did a quick test and the overlay window was shown even in the settings menu.我做了一个快速测试,甚至在设置菜单中也显示了覆盖 window。 The overlay window also received touch events.叠加层 window 也接收到触摸事件。 This worked also without the SYSTEM_ALERT_WINDOW permission in the manifest and also without setting the "Display over other apps" permission interactively by the user.这在清单中没有SYSTEM_ALERT_WINDOW权限的情况下也有效,也没有用户以交互方式设置“在其他应用程序上显示”权限。 I did my testing using target SDK 29.我使用目标 SDK 29 进行了测试。

Sorry, I cannot answer to your third question about what specific restrictions apply.抱歉,我无法回答您关于适用哪些具体限制的第三个问题。


EDIT: By looking at the old tutorial of Google here , here's a short sample:编辑:通过查看 Google here的旧教程,这里有一个简短的示例:

GlobalActionBarService.java GlobalActionBarService.java

public class GlobalActionBarService extends AccessibilityService {
    FrameLayout mLayout;

    @Override
    protected void onServiceConnected() {
        // Create an overlay and display the action bar
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        mLayout = new FrameLayout(this);
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
        lp.format = PixelFormat.TRANSLUCENT;
        lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        lp.gravity = Gravity.TOP;
        LayoutInflater inflater = LayoutInflater.from(this);
        inflater.inflate(R.layout.action_bar, mLayout);
        wm.addView(mLayout, lp);
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }

    @Override
    public void onInterrupt() {
    }
}

manifest显现

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    package="com.lb.myapplication">

    <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.MyApplication" tools:ignore="AllowBackup">
        <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>

        <service
            android:name=".GlobalActionBarService" android:exported="false"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
                android:name="android.accessibilityservice" android:resource="@xml/global_action_bar_service" />
        </service>
    </application>

</manifest>

global_action_bar_service.xml global_action_bar_service.xml

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault"
    android:canPerformGestures="true" android:canRetrieveWindowContent="true" />

action_bar.xml action_bar.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="wrap_content" android:orientation="horizontal">

    <Button
        android:id="@+id/power" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="@string/power" />

    <Button
        android:id="@+id/volume_up" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="@string/volume" />

    <Button
        android:id="@+id/scroll" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="@string/scroll" />

    <Button
        android:id="@+id/swipe" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="@string/swipe" />
</LinearLayout>

The answer is: You must use WindowManager which puts views to a window in the service to draw it on top of other apps.答案是:您必须使用 WindowManager 将视图放入服务中的 window 以将其绘制在其他应用程序之上。

    val typeApplication =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        else
            WindowManager.LayoutParams.TYPE_PHONE

    val layoutParams = WindowManager.LayoutParams(
        windowWidth,
        ViewGroup.LayoutParams.WRAP_CONTENT,
        typeApplication,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT
    )
    // inflater view with above layoutParams variable

And the application granted the Overlay permission and make sure accessibility is enabled in the device setting (Setting-> Accessibility -> Enable your app).并且应用程序授予了覆盖权限并确保在设备设置中启用了可访问性(设置-> 辅助功能-> 启用您的应用程序)。 Or use this intent to go to it或者使用这个意图来 go 到它

Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)

. . You can check the Overlay permission by the following code您可以通过以下代码检查 Overlay 权限

  // check
  Settings.canDrawOverlays(applicationContext)
  // Use this intent to enable permision
  Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
         Uri.parse("package:$packageName"))

Does it work the same as SAW permission?它与 SAW 许可的工作方式相同吗? Can you, for example, handle touch events on what it draws?例如,你能处理它绘制的触摸事件吗? I've never used SAW before so I'm not sure about this question.我以前从未使用过 SAW,所以我不确定这个问题。

Hope can help you!希望能帮到你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何阅读窗口内容(使用accessibilityService)并使用绘制来激活UI而不是Android中的其他应用程序权限? - How to read window content (using accessibilityService) and evoking UI using draw over other app permission in Android? 如何使用AccessibilityService检索正在运行的其他应用程序的内容? - How can I use AccessibilityService to retrieve content of other apps running..? 如何绘制抽取其他应用程序的应用程序? - 确定优先顺序? - How to draw over apps that draw over other apps? - Setting Priorities? 如何在键盘下绘制其他应用程序? - How to draw over other apps but under keyboard? 如何检查将其他应用程式的绘图设为True的应用程式? - How to check for apps which has Draw over other apps as True? 如何使用AccessibilityService向我正在观察的应用程序添加窗口? - How to add a window to apps I am observing using AccessibilityService? 如何在React-native中使用其他应用程序? - How to draw over other apps in React-native? 如何以编程方式授予 android 中的“绘制其他应用程序”权限? - How to programmatically grant the "draw over other apps" permission in android? 如何在彼此之上绘制 3 个圆圈,每个圆圈的透明度不同? - How to draw 3 circles on top of each other that are each transparent differently? 可以在未经许可的情况下在屏幕顶部绘制的应用 - Apps that can draw on top of the screen without permission
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM