如何利用android辅助功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何利用android辅助功能相关的知识,希望对你有一定的参考价值。

下面是Service类:
public class MyService extends AccessibilityService
private int code = INSTALL;
private static final int INSTALL = 0;
private static final int NEXT = 1;
private static final int FINISH = 2;
/**
* 页面变化回调事件
* @param event event.getEventType() 当前事件的类型;
* event.getClassName() 当前类的名称;
* event.getSource() 当前页面中的节点信息;
* event.getPackageName() 事件源所在的包名
*/
@Override
public void onAccessibilityEvent(AccessibilityEvent event)
// 事件页面节点信息不为空
if (event.getSource() != null)
// 判断事件页面所在的包名
if (event.getPackageName().equals(getApplicationContext().getPackageName()))
switch (code)
case INSTALL:
click(event, "安装", TextView.class.getName());
Log.d("test=======", "安装");
code = NEXT;
break;
case NEXT:
click(event, "下一步", Button.class.getName());
Log.d("test=======", "下一步");
code = FINISH;
break;
case FINISH:
click(event, "完成", TextView.class.getName());
Log.d("test=======", "完成");
code = INSTALL;
break;
default:
break;


else
Log.d("test=====", "the source = null");



/**
* 模拟点击
* @param event 事件
* @param text 按钮文字
* @param widgetType 按钮类型,如android.widget.Button,android.widget.TextView
*/
private void click(AccessibilityEvent event, String text, String widgetType)
// 事件页面节点信息不为空
if (event.getSource() != null)
// 根据Text搜索所有符合条件的节点, 模糊搜索方式; 还可以通过ID来精确搜索findAccessibilityNodeInfosByViewId
List<AccessibilityNodeInfo> stop_nodes = event.getSource().findAccessibilityNodeInfosByText(text);
// 遍历节点
if (stop_nodes != null && !stop_nodes.isEmpty())
AccessibilityNodeInfo node;
for (int i = 0; i < stop_nodes.size(); i++)
node = stop_nodes.get(i);
// 判断按钮类型
if (node.getClassName().equals(widgetType))
// 可用则模拟点击
if (node.isEnabled())
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);







/**
* 中断AccessibilityService的反馈时调用
*/
@Override
public void onInterrupt()
Log.d("test=====", "Interrupt");



AccessibilityService里几个重要的方法:
onServiceConnected() - 可选。系统会在成功连接上你的服务的时候调用这个方法,在这个方法里你可以做一下初始化工作,例如设备的声音震动管理,也可以调用setServiceInfo()进行配置AccessibilityServiceInfo。
onAccessibilityEvent() - 必须。通过这个函数可以接收系统发送来的AccessibilityEvent,接收来的AccessibilityEvent是经过过滤的,过滤是在配置工作时设置的。
onInterrupt() - 必须。这个在系统想要中断AccessibilityService返给的响应时会调用。在整个生命周期里会被调用多次。
onUnbind() - 可选。在系统将要关闭这个AccessibilityService会被调用。在这个方法中进行一些释放资源的工作。

之后在AndroidManifest文件里注册并添加相应的权限:
<service
android:name=".MyService"
android:label="辅助功能"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
...
</service>
参考技术A put anything between

不会编程如何制作Android辅助功能?

最近一直在研究冰狐智能辅助,上次利用冰狐智能辅助实现了一个免费的个人收款系统,用起来还行,说实话刚开始我有怀疑过平台的稳定性,现在看来是有点多虑了。最近看官网更新了一个针对菜鸟设计的通过配置直接生成脚本功能「自动构建」,个人觉得很好奇,有点高大上,于是利用约会的时间研究了一把。用「自动构建」,没写一行代码,实现了一个薅羊毛程序(纯属个人兴趣研究,禁止用于任何商业用途),现把该薅羊毛程序作为例子进行讲解,分享菜鸟(不会编程的同学)是如何快速实现辅助功能的。

准备工作

  1. 手机端安装「冰狐智能辅助」,详细安装过程请看这里
  2. 手机端安装「爱奇艺极速版」v1.10.6,注意,必须安装这个版本,不同的版本操作界面可能不同,可能会导致辅助功能失效。点击这里从豌豆荚官网下载该版本
  3. 注册「爱奇艺极速版」用户并登陆。

制作辅助功能

  1. 进入「移动端」/「自动构建」,新建名为”爱奇艺极速版“的自动构建。
  2. 点击“配置源码”按钮,将如下json数据粘贴进去,保存。
    
    	"type": "root",
    	"children": [
    		"type": "declareVar",
    		"var": [
    			"name": "ret",
    			"type": "normal",
    			"initType": "null",
    			"initValue": "null"
    		, 
    			"name": "view",
    			"type": "normal",
    			"initType": "null",
    			"initValue": "null"
    		, 
    			"name": "viewContainer",
    			"type": "normal",
    			"initType": "null",
    			"initValue": "null"
    		, 
    			"name": "item",
    			"type": "normal",
    			"initType": "null",
    			"initValue": "null"
    		],
    		"desc": "变量声明"
    	, 
    		"type": "launchApp",
    		"packageName": "com.qiyi.video.lite",
    		"findTag": "txt:首页-",
    		"failed": "exitPopup",
    		"maxStep": "30",
    		"children": [
    			"type": "log",
    			"log": "启动app成功",
    			"desc": "启动成功日志",
    			"info": ["string-app启动成功"],
    			"log_type": "log"
    		, 
    			"type": "switchPage",
    			"returnVar": "",
    			"findTag": "txt:开宝箱-",
    			"checkTag": "txt:活动规则-",
    			"root": "",
    			"click": "true",
    			"failed": "exitPopupWithAD",
    			"descendant": "[]",
    			"duration": "500",
    			"maxStep": "5",
    			"beforeWait": "0",
    			"afterWait": "0",
    			"children": [
    				"type": "log",
    				"desc": "开始日志",
    				"log_type": "log",
    				"info": ["string-进入任务"]
    			, 
    				"type": "task",
    				"scrollCount": "2",
    				"returnTag": "txt:活动规则-",
    				"taskDeal": [
    					"key": "txt^:免费抽大奖-",
    					"value": 
    						"type": "switchPage",
    						"desc": "切换到幸运大转盘",
    						"returnVar": "",
    						"findTag": "txt^:免费抽大奖-",
    						"checkTag": "txt:幸运大转盘-",
    						"root": "",
    						"click": "true",
    						"failed": "exitPopupWithAD",
    						"descendant": [],
    						"duration": "500",
    						"maxStep": "5",
    						"beforeWait": "0",
    						"afterWait": "0",
    						"children": [
    							"type": "loop",
    							"desc": "循环多次处理抽奖",
    							"class": "2",
    							"startIndex": "0",
    							"endIndex": "20",
    							"children": [
    								"type": "findView",
    								"desc": "搜索控件",
    								"viewDeal": [
    									"key": "txt^:恭喜到账-traverse_one_by_one",
    									"value": 
    										"type": "loop",
    										"desc": "退出到账",
    										"class": "4",
    										"container": "view",
    										"descendant": "[-1,-1]",
    										"children": [
    											"type": "if",
    											"desc": "条件处理",
    											"expr": "item.clickable",
    											"children": [
    												"type": "log",
    												"desc": "日志",
    												"log_type": "log",
    												"info": ["string-click x,and exit"]
    											, 
    												"type": "click",
    												"desc": "点击控件",
    												"class": "2",
    												"click": "true",
    												"descendant": [],
    												"beforeWait": "0",
    												"afterWait": "0",
    												"target": "item"
    											, 
    												"type": "break",
    												"desc": "跳出循环"
    											]
    										]
    									
    								, 
    									"key": "txt$:后再来-",
    									"value": 
    										"type": "break",
    										"desc": "跳出循环"
    									
    								, 
    									"key": "txt^:lottery-list-",
    									"value": 
    										"type": "custom",
    										"desc": "抽奖",
    										"code": "var txt = view.parent.parent.parent[2][0].text;\\nconsole.log('txt:' + txt);\\nvar num = parseInt(txt);\\nif (num > 0) \\ngestureClick((view.left + view.right) / 2, (view.top + view.bottom) / 2, afterWait: 8000);\\nconsole.log('点击开始抽奖');\\n else \\nconsole.log('抽奖结束');\\nbreak;\\n"
    									
    								, 
    									"key": "txt^:lottery-list-",
    									"value": 
    										"type": "if",
    										"desc": "条件处理",
    										"expr": "parseInt(view.parent.parent.parent[2][0].text)>0",
    										"children": [
    											"type": "click",
    											"desc": "点击控件",
    											"class": "4",
    											"duration": "500",
    											"beforeWait": "0",
    											"afterWait": "8000",
    											"x": "0",
    											"y": "0",
    											"unit": "px"
    										]
    									
    								],
    								"root": "",
    								"failed": "exitPopupWithAD",
    								"duration": "500",
    								"maxStep": "10",
    								"beforeWait": "0",
    								"afterWait": "0",
    								"false": 
    									"type": "break",
    									"desc": "跳出循环"
    								
    							],
    							"descendant": []
    						, 
    							"type": "back2Page",
    							"desc": "返回页面",
    							"returnVar": "",
    							"tag": "txt:我的|txt:活动规则-",
    							"root": "",
    							"backFirst": "true",
    							"failed": "",
    							"duration": "500",
    							"maxStep": "5",
    							"beforeWait": "0",
    							"afterWait": "0"
    						],
    						"false": 
    							"type": "log",
    							"desc": "日志",
    							"log_type": "error",
    							"info": ["string-切换到大转盘失败"]
    						
    					
    				, 
    					"key": "txt:开宝箱领金币|txt$:每日可领-",
    					"value": 
    						"type": "click",
    						"desc": "点击控件",
    						"class": "2",
    						"click": "true",
    						"descendant": [],
    						"beforeWait": "0",
    						"afterWait": "1000",
    						"target": "view"
    					
    				],
    				"maxDealCount": "8",
    				"failed": "exitPopupWithAD",
    				"desc": "任务处理",
    				"removeTag": true
    			, 
    				"type": "log",
    				"desc": "结束日志",
    				"log_type": "log",
    				"info": ["string-任务结束"]
    			],
    			"desc": "切换到任务频道",
    			"false": 
    				"type": "log",
    				"desc": "日志",
    				"log_type": "error",
    				"info": ["string-进入任务失败"]
    			
    		, 
    			"type": "switchPage",
    			"returnVar": "",
    			"findTag": "txt:首页-",
    			"checkTag": "txt:电视剧-",
    			"root": "",
    			"click": "true",
    			"failed": "exitPopupWithAD",
    			"descendant": [],
    			"duration": "500",
    			"maxStep": "5",
    			"beforeWait": "0",
    			"afterWait": "0",
    			"children": [
    				"type": "mainLoop",
    				"minRunTime": "2",
    				"maxRunTime": "5",
    				"minScrollCount": "1",
    				"maxScrollCount": "3",
    				"containerTag": "cn:androidx.recyclerview.widget.RecyclerView-",
    				"failed": "exitPopupWithAD",
    				"children": [
    					"type": "log",
    					"log": "开始看视频了哦",
    					"desc": "日志",
    					"info": ["string-开始看电视了哦"],
    					"log_type": "log"
    				, 
    					"type": "loopPicker",
    					"desc": "从循环中挑选某些项处理",
    					"startIndex": "1",
    					"lastIndex": "1",
    					"random": true,
    					"children": [
    						"type": "click",
    						"desc": "点击电视",
    						"class": "2",
    						"click": "true",
    						"descendant": [],
    						"beforeWait": "0",
    						"afterWait": "0",
    						"target": "sChild"
    					, 
    						"type": "findView",
    						"desc": "查看是否进入电视",
    						"returnVar": "",
    						"tag": "txt*:/|txt:金蛋奖励-",
    						"root": "",
    						"failed": "exitPopup",
    						"duration": "500",
    						"maxStep": "5",
    						"beforeWait": "0",
    						"afterWait": "0",
    						"children": [
    							"type": "loop",
    							"desc": "看电视",
    							"breakTag": "txt:完成-",
    							"failed": "",
    							"minRunTime": "0.5",
    							"maxRunTime": "1.2",
    							"class": 1
    						],
    						"viewDeal": [
    							"key": "txt*:/|txt:金蛋奖励-",
    							"value": 
    								"type": "loop",
    								"desc": "看电视",
    								"class": 1,
    								"breakTag": "txt:完成-",
    								"failed": "exitPopup",
    								"minRunTime": "0.7",
    								"maxRunTime": "1.2",
    								"descendant": [],
    								"children": [
    									"type": "click",
    									"desc": "关闭广告",
    									"class": 1,
    									"tag": "txt:关闭此广告-",
    									"root": "",
    									"click": "true",
    									"failed": "",
    									"descendant": [],
    									"duration": "500",
    									"maxStep": "5",
    									"beforeWait": "0",
    									"afterWait": "0"
    								]
    							
    						],
    						"false": 
    							"type": "log",
    							"desc": "日志",
    							"log_type": "log",
    							"info": ["string-进入电视失败"]
    						
    					, 
    						"type": "click",
    						"desc": "领金币",
    						"class": 1,
    						"tag": "txt:领金币-",
    						"root": "",
    						"click": "true",
    						"failed": "",
    						"descendant": [],
    						"duration": "500",
    						"maxStep": "5",
    						"beforeWait": "0",
    						"afterWait": "0"
    					, 
    						"type": "click",
    						"desc": "领不固定金币",
    						"class": 1,
    						"tag": "txt^:领-",
    						"root": "",
    						"click": "true",
    						"failed": "",
    						"descendant": [],
    						"duration": "500",
    						"maxStep": "5",
    						"beforeWait": "0",
    						"afterWait": "0"
    					, 
    						"type": "back2Page",
    						"desc": "返回页面",
    						"returnVar": "",
    						"tag": "txt:我的-",
    						"root": "",
    						"backFirst": "true",
    						"failed": "",
    						"duration": "500",
    						"maxStep": "5",
    						"beforeWait": "0",
    						"afterWait": "0"
    					]
    				],
    				"returnTag": "txt:我的-",
    				"skipProb": "80",
    				"desc": "滚动屏幕看电视",
    				"findContainerFailed": 
    			],
    			"desc": "切换到电视剧频道",
    			"false": 
    				"type": "log",
    				"desc": "日志",
    				"log_type": "error",
    				"info": ["string-进入看电视失败"]
    			
    		, 
    			"type": "switchPage",
    			"desc": "切换到短视频",
    			"returnVar": "",
    			"findTag": "txt:短视频-",
    			"checkTag": "txt:推荐-",
    			"root": "",
    			"click": "true",
    			"failed": "exitPopupWithAD",
    			"descendant": [],
    			"duration": "500",
    			"maxStep": "5",
    			"beforeWait": "0",
    			"afterWait": "0",
    			"false": 
    				"type": "log",
    				"desc": "切换失败日志",
    				"log_type": "error",
    				"info": ["string-切换短视频失败"]
    			,
    			"children": [
    				"type": "mainLoop",
    				"desc": "主循环",
    				"containerTag": "cn:androidx.recyclerview.widget.RecyclerView-",
    				"returnTag": "-",
    				"skipProb": "0",
    				"failed": "exitPopup",
    				"minRunTime": "2",
    				"maxRunTime": "3",
    				"minScrollCount": "1",
    				"maxScrollCount": "1",
    				"children": [
    					"type": "log",
    					"desc": "日志",
    					"log_type": "log",
    					"info": ["string-开始看小视频了"]
    				, 
    					"type": "loop",
    					"desc": "循环",
    					"breakTag": "",
    					"failed": "",
    					"minRunTime": "0.1",
    					"maxRunTime": "0.5",
    					"class": 1
    				, 
    					"type": "break",
    					"desc": "跳出循环"
    				]
    			]
    		],
    		"false": 
    			"type": "log",
    			"log": "启动APP失败",
    			"desc": "日志",
    			"log_type": "error",
    			"info": ["string-启动app失败"]
    		,
    		"desc": "启动APP"
    	, 
    		"type": "popup",
    		"name": "exitPopup",
    		"exitPopupDeal": [
    			"key": "txt:暂不升级|txt:我知道了-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "true",
    				"descendant": [],
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		, 
    			"key": "txt:猜你想看-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": 1,
    				"tag": "txt:取消-",
    				"root": "",
    				"click": "true",
    				"failed": "",
    				"descendant": [],
    				"duration": "500",
    				"maxStep": "5",
    				"beforeWait": "0",
    				"afterWait": "0"
    			
    		, 
    			"key": "txt^:再赚-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "false",
    				"descendant": [],
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		, 
    			"key": "txt:恭喜获得-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "true",
    				"descendant": [-1, 4],
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		, 
    			"key": "txt^:恭喜到账-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "true",
    				"descendant": [-1, 2, 0],
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		, 
    			"key": "txt:继续赚钱-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "true",
    				"descendant": "[-1,-1,-1,1]",
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		, 
    			"key": "txt^:打开日历提醒-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "true",
    				"descendant": "[-1,7]",
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		],
    		"false": "[]",
    		"desc": "处理弹窗"
    	, 
    		"type": "popup",
    		"name": "exitPopupWithAD",
    		"exitPopupDeal": [],
    		"false": ["exitPopup", "dealAD"],
    		"desc": "处理弹窗和广告"
    	, 
    		"type": "ad",
    		"enterWindowList": "[\\"com.mcto.sspsdk.ssp.activity.QyTrueViewActivity\\"]",
    		"enterTags": "txt*:s后可领取奖励-",
    		"breakTags": "txt:开宝箱|txt:我的|txt^:再赚|txt:继续赚钱|txt:幸运大转盘-",
    		"exitDeal": [
    			"key": "txt:关闭-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "true",
    				"descendant": [],
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		, 
    			"key": "txt:恭喜获得-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": "2",
    				"click": "true",
    				"descendant": [-1, 4],
    				"beforeWait": "0",
    				"afterWait": "0",
    				"target": "view"
    			
    		, 
    			"key": "cn:android.widget.ImageView-find_all|clickable",
    			"value": 
    				"type": "loop",
    				"desc": "循环",
    				"class": "4",
    				"container": "viewContainer",
    				"children": [
    					"type": "custom",
    					"desc": "自定义模块,直接写入代码",
    					"code": "if (item.width == item.height && item.width < 80 && item.width > 40 && item.top < 100 && item.right > (rsScreenWidth - 20)) \\nclick(item, click: true);\\nconsole.log('click x');\\nbreak;\\n"
    				],
    				"descendant": "[]"
    			
    		, 
    			"key": "txt:继续观看视频可获得奖励-",
    			"value": 
    				"type": "click",
    				"desc": "点击控件",
    				"class": 1,
    				"tag": "txt:继续观看-",
    				"root": "",
    				"click": "true",
    				"failed": "",
    				"descendant": [],
    				"duration": "500",
    				"maxStep": "5",
    				"beforeWait": "0",
    				"afterWait": "0"
    			
    		],
    		"desc": "处理广告"
    	, 
    		"type": "windowChange",
    		"windowDeal": [],
    		"desc": "窗口变化处理"
    	, 
    		"type": "notification",
    		"children": [],
    		"filter": "",
    		"desc": "通知处理"
    	],
    	"desc": "根模块"
    

  3. 点击“编译”按钮,把构建编译成js代码。
  4. 进入「移动端」/「移动端脚本」,系统会自动创建一个“爱奇艺极速版”js脚本,点击“发布”按钮,发布脚本。
  5. 点击“运行”按钮,选择设备,执行脚本,一个自动薅羊毛的辅助程序就完成啦😊。

原理分析

看到这,其实最核心的就是如何得到配置json数据。下面我们一起来看下我是如何配置的:

进入「移动端」/「自动构建」,选择“爱奇艺极速版”,然后点击“配置构建”按钮。这时候弹出一个配置界面,如下图所示:

 配置由模块组成,每个模块由模块属性和子模块组成。一般的模块会直接执行子模块,有的带条件的模块,当条件为true或者执行结果为true时才执行子模块,注意:子模块是按按顺序执行。整个配置其实就是一个树形结构,上图就是根模块。下面来介绍下每个模块作用:

变量声明

        声明一些后面模块要用的通用变量,系统会自动生成几个常用的变量,个人感觉绝大部份情况下系统默认生成的就够用了😄。点击“编辑”按钮,再点击“查看/编辑变量声明”,显示如下变量:

启动APP

        如果打算启动和处理APP,必须添加这个模块。点击该模块的“编辑”按钮,属性和子模块如下图所示:

「每个属性行的最后都有一个说明,鼠标移动上去会自动显示详细说明。」

属性如下:

  1. packageName,APP的包名
  2. findTag,这个是用来检测app是否已经启动。app启动了,首页中如果出现该tag,则表示启动成功。
  3. false,启动app失败后会执行该模块,打了个log😯。
  4. failed,用来处理随机弹窗的问题,如果系统随机弹出什么升级啊等窗口时,这个可以自动处理🐂。
  5. maxStep,检测是否启动,最多find几次tag,默认好像是30次。

成功启动app后,会自动按顺序执行子模块:

  1. 打log,用于调试吧。
  2. 切换到任务频道,做任务。
  3. 切换到电视剧频道,看电视剧。
  4. 切换到短视频频道,看短视频。

处理弹窗

        用于处理app随机弹出的各种窗口,比如:升级、青少年模式、处理成功等等对话框。

 属性如下:

  1. exitPopupDeal,用于处理弹窗。点击后面的"查看/编辑map"

  1. false,模块数组。当无法处理弹窗时,会按顺序执行模块,如果返回true则不执行,否则继续执行下一个。

处理弹窗和广告

        用于即有可能出现弹窗也有可能出现广告的场景。false属性值["exitPopup","dealAD"],表示先处理弹窗,如果失败,则看看是否是广告,处理广告。

处理广告

        处理弹出广告的情况,当广告完成后自动退出广告。广告不会自动触发,一般是在点击某个按钮后弹出广告。

 属性如下:

  1. enterWindows,广告窗口className的数组,当出现其中一个窗口时,表示进入广告。
  2. enterTags,广告窗口中某个标识性控件的tag数组,当出现其中一个tag时,表示进入了广告。
  3. breakTags,广告退出后显示页面的标志性tag数组,当出现其中一个tag时,表示广告已经退出。
  4. exitDeal,退出处理,当出现点击退出广告的按钮时,点击按钮。

窗口变化处理

        可以用于处理比如。当窗口改变后,系统会自动触发该模块。

通知处理

        用于处理各种通知,比如微信消息,短信等等。当出现通知时,系统会自动触发该模块。

总结

        通过这几天的研究,总体感觉还可以,能通过配置完成绝大多数功能。但也有缺点,就是文档太少了,很多属性需要自己研究,希望官方以后会多多完善文档。

        本文只介绍了部分模块,还有其他模块这里没有介绍完,如果大家感兴趣的话,我后续再继续出专题,有任何问题,欢迎大家留言,一起交流😊

以上是关于如何利用android辅助功能的主要内容,如果未能解决你的问题,请参考以下文章

如何启用从设置中删除动画-> 辅助功能 android

如何在 Android 中启动我的 APP 的辅助功能设置页面?

Android检测辅助功能是不是开启

Android辅助功能基本操作

如何检查其他应用程序是不是在 Android 中使用辅助功能(BIND_ACCESSIBILITY_SERVICE)权限

GPS 学习记录1——辅助定位