安卓无障碍获取录屏权限

server/2024/12/22 6:59:12/

每次需要录屏操作时,都会弹窗需要用户手动授权比较麻烦,可以通过无障碍模拟用户点击进行授权。

方法主要有三种:

1.查找“立即开始”(华为手机是“允许”)节点,模拟点击;

 @Overridepublic void onAccessibilityEvent(AccessibilityEvent event) {Log.i("AccessibilityEvent", event.toString());if (event == null || !event.getPackageName().toString().contains("com.android.systemui"))//不写完整包名,是因为某些手机(如小米)安装器包名是自定义的return;/*某些手机安装页事件返回节点有可能为null,无法获取安装按钮例如华为mate10安装页就会出现event.getSource()为null,所以取巧改变当前页面状态,重新获取节点。该方法在华为mate10上生效,但其它手机没有验证...(目前小米手机没有出现这个问题)*/Log.i(TAG, "onAccessibilityEvent: " + event);AccessibilityNodeInfo eventNode = event.getSource();/*模拟点击->立即开始,只验证了小米5s plus(MIUI 9.8.4.26)、小米Redmi 5A(MIUI 9.2)、华为mate 10其它品牌手机可能还要适配,适配最可恶的就是出现安装广告按钮,误点安装其它垃圾APP(典型就是小米安装后广告推荐按钮,华为安装开始官方安装)*/AccessibilityNodeInfo nodeInfo= getRootInActiveWindow(); //当前窗口根节点if (rootNode == null)return;if (event.getClassName().toString().contains("MediaProjectionPermissionActivity")) {List<AccessibilityNodeInfo> nodes = nodeInfo.findAccessibilityNodeInfosByText("立即开始");Log.i(TAG, "findTxtClick: " + txt + ", " + nodes.size() + ", " + nodes);if (nodes == null || nodes.isEmpty()) {return;}Log.i(TAG, "findTxtClick: " + txt + ", " + nodes.size() + ", " + nodes);for (AccessibilityNodeInfo node : nodes) {node.performAction(AccessibilityNodeInfo.ACTION_CLICK);}// 回收节点实例来重用if (eventNode != null) {eventNode.recycle();}rootNode.recycle();}

2.查找buttonId;经我研究立即开始id是

android:id/button1
 List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId = rootNode.findAccessibilityNodeInfosByViewId("android:id/button1");Log.i(TAG, "findTxtClick: 立即开始"   + "button1 " + findAccessibilityNodeInfosByViewId.size());if (findAccessibilityNodeInfosByViewId.size() > 0) {System.out.println("5=====================" + findAccessibilityNodeInfosByViewId.size());Iterator<AccessibilityNodeInfo> it = findAccessibilityNodeInfosByViewId.iterator();while (it.hasNext()) {it.next().performAction(16);}return;}

3.某些手机不给你查找,只能查到”取消“,这时候需要模拟一个区域,计算这个区域位置与”允许“重合,进行点击。

  List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId2 = nodeInfo.findAccessibilityNodeInfosByViewId("android:id/button3");System.out.println("findTxtClick取消 " + findAccessibilityNodeInfosByViewId2.size());if (findAccessibilityNodeInfosByViewId2.size() == 0) {return;}AccessibilityNodeInfo accessibilityNodeInfo = findAccessibilityNodeInfosByViewId2.get(0);Rect rect = new Rect();accessibilityNodeInfo.getBoundsInScreen(rect);Path path = new Path();int screenWidth = getScreenWidth(this);int i = screenWidth - ((rect.left + rect.right) / 2);if (i < (screenWidth / 2) + 50 && i > (screenWidth / 2) - 50) {if (getResources().getConfiguration().orientation == 1) {float f = i;int i2 = rect.top;int i3 = rect.bottom;path.moveTo(f, ((i2 + i3) / 2) - (i3 - i2));} else {float f2 = i;int i4 = rect.top;int i5 = rect.bottom;path.moveTo(f2, ((i4 + i5) / 2) - (i5 - i4));}} else if (getResources().getConfiguration().orientation == 1) {path.moveTo(i, (rect.top + rect.bottom) / 2);} else {path.moveTo(i, (rect.top + rect.bottom) / 2);}Gesture(path, 50L, 0L);return;
 public void Gesture(final Path path, final long time, final long delay) {new Thread() { // from class: com.stardust.autojs.core.accessibility.AccessibilityService.1@Override // java.lang.Thread, java.lang.Runnable@SuppressLint({"NewApi"})public void run() {try {if (path.isEmpty()) {return;}if (Looper.myLooper() == null) {Looper.prepare();}Handler handler = new Handler(Looper.myLooper());Log.i(TAG, "findTxtClick: 立即开始"   + ", dispatchGesture" );dispatchGesture(new GestureDescription.Builder().addStroke(new GestureDescription.StrokeDescription(path, delay, time)).build(), new AccessibilityService.GestureResultCallback() { // from class: com.stardust.autojs.core.accessibility.AccessibilityService.1.1@Override // android.accessibilityservice.AccessibilityService.GestureResultCallbackpublic void onCancelled(GestureDescription gestureDescription) {Log.i(TAG, "findTxtClick: 立即开始"   + ", 没点击" );}@Override // android.accessibilityservice.AccessibilityService.GestureResultCallbackpublic void onCompleted(GestureDescription gestureDescription) {Log.i(TAG, "findTxtClick: 立即开始"   + ", 点击了" );MyApplication.getInstance().closetan=false;}}, handler);Looper.loop();} catch (Throwable th) {Log.i(TAG, "findTxtClick: 立即开始"   + ", th"+th.toString());th.printStackTrace();}}}.start();}

即便完成了以上操作,还需要配置不同系统版本的xml权限才能成功。

xml

<accessibility-servicexmlns:android="http://schemas.android.com/apk/res/android"android:description="@string/readme"android:packageNames="com.android.systemui"android:accessibilityEventTypes="typeAllMask"android:accessibilityFeedbackType="feedbackAllMask"android:notificationTimeout="100"android:settingsActivity="com.angcyo.SettingsActivity"android:accessibilityFlags="flagDefault"android:canPerformGestures="true"android:canRetrieveWindowContent="true"/>

xml30

<accessibility-servicexmlns:android="http://schemas.android.com/apk/res/android"android:description="@string/readme"android:packageNames="com.android.systemui"android:settingsActivity="com.angcyo.SettingsActivity"android:canRequestTouchExplorationMode="true"android:accessibilityEventTypes="typeAllMask"android:accessibilityFeedbackType="feedbackAllMask"android:notificationTimeout="10"android:accessibilityFlags="flagRetrieveInteractiveWindows|flagRequestFilterKeyEvents|flagReportViewIds|flagRequestEnhancedWebAccessibility|flagIncludeNotImportantViews"android:canRetrieveWindowContent="true"android:canRequestEnhancedWebAccessibility="true"android:canRequestFilterKeyEvents="false"android:canPerformGestures="true"android:canTakeScreenshot="true"/>

xml31

<accessibility-servicexmlns:android="http://schemas.android.com/apk/res/android"android:description="@string/readme"android:packageNames="com.android.systemui"android:settingsActivity="com.angcyo.SettingsActivity"android:canRequestTouchExplorationMode="true"android:accessibilityEventTypes="typeAllMask"android:accessibilityFeedbackType="feedbackAllMask"android:notificationTimeout="10"android:accessibilityFlags="flagRetrieveInteractiveWindows|flagRequestFilterKeyEvents|flagReportViewIds|flagRequestEnhancedWebAccessibility|flagIncludeNotImportantViews"android:canRetrieveWindowContent="true"android:canRequestEnhancedWebAccessibility="true"android:canRequestFilterKeyEvents="false"android:canPerformGestures="true"android:canTakeScreenshot="true"/>

全部代码我已上传 https://download.csdn.net/download/guodashen007/89874977


http://www.ppmy.cn/server/131572.html

相关文章

线性回归逻辑回归-笔记

一、线性回归&#xff08;Linear Regression&#xff09; 1. 定义 线性回归是一种用于回归问题的算法&#xff0c;旨在找到输入特征与输出值之间的线性关系。它试图通过拟合一条直线来最小化预测值与真实值之间的误差。 2. 模型表示 线性回归模型假设目标变量&#xff08;输…

Notepad++ 初学者指南

引言 对于初学者来说&#xff0c;选择合适的编程工具很重要&#xff0c;特别是考虑到易用性和计算机资源的需求。 虽然集成开发环境&#xff08;IDE&#xff09;如 Eclipse、IntelliJ IDEA 和 Visual Studio 提供了许多强大的功能&#xff0c;但对于刚开始学习编程的人来说&a…

键盘鼠标上一些主要按键的真实名称

鼠标上的主要按键通常有以下名称&#xff1a; **一、左键&#xff08;Primary Button&#xff09;**&#xff1a; - 通常也被称为主按键&#xff0c;是最常用的鼠标按键之一。 - 主要用于选择对象、点击菜单选项、确定操作等。比如在文件管理器中&#xff0c;左键点击文件可…

【算法】笨小猴

[NOIP2008]笨小猴_牛客题霸_牛客网 【描述】 eg1中&#xff0c;输入“error” “e”出现了1次&#xff0c;“r”出现了3次&#xff0c;“o”出现了1次 最大是3&#xff0c;最小是1&#xff0c;3-12&#xff0c;2是质数&#xff0c;所以输出“Lucky word”和这个单词 eg2中&…

Linux--多路转接之select

前言 多路转接&#xff08;也称为多路复用&#xff09;是一种用于管理多个I/O通道的技术&#xff0c;它能实现同时监听和处理多个I/O事件&#xff0c;而不是为每个I/O通道创建单独的线程或进程。其中&#xff0c;select是实现多路转接的一种常用方法。 select() select函数是…

GC1277和灿瑞的OCH477优势分析 可以用于电脑散热风扇,视频监控和图像处理的图像信号处理器中

GC1277和灿瑞的OCH477是两款用于视频监控和图像处理的图像信号处理器&#xff08;ISP&#xff09;。在对比这两款产品时&#xff0c;可以从以下几个方面考虑它们的优势和特点&#xff1a; 1. 图像处理能力 GC1277&#xff1a;通常具有更强的图像处理算法&#xff0c;支持多种…

数据库的相关概念

先看与数据库有关的几个名词&#xff1a; DB&#xff1a;database&#xff0c;数据库&#xff0c;里边保存了有组织的规范的数据。 DBMS&#xff1a;database management system &#xff0c; 数据库管理系统&#xff0c;简称数据库软件&#xff0c;数据库产品&#xff0c;数…

C#开源的一个能利用Windows通知栏背单词的软件

前言 今天给大家推荐一个C#开源且免费的能利用Windows通知栏背单词的软件&#xff0c;可以让你在上班、上课等恶劣环境下安全隐蔽地背单词&#xff08;利用摸鱼时间背单词的软件&#xff09;&#xff1a;ToastFish。 操作系统要求 目前该软件只支持Windows10及以上系统&…