tauri-plugin-android-accessibility-api 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -0
- package/dist-js/index.cjs +33 -0
- package/dist-js/index.d.ts +58 -0
- package/dist-js/index.js +27 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Tauri Plugin Android Accessibility
|
|
2
|
+
|
|
3
|
+
[简体中文](./README_zh-cn.md)
|
|
4
|
+
|
|
5
|
+
A mobile plugin based on Tauri v2 for Android accessibility bridging, providing the following capabilities:
|
|
6
|
+
|
|
7
|
+
- Check if accessibility services are enabled
|
|
8
|
+
- Jump to the system accessibility settings page
|
|
9
|
+
- Get a UI tree snapshot of the current foreground window
|
|
10
|
+
- Perform click/long press/focus by node ID (supports falling back to a clickable parent node)
|
|
11
|
+
|
|
12
|
+
## 1. Functional Description
|
|
13
|
+
|
|
14
|
+
This plugin is designed for Android and consists of a Kotlin accessibility service and a Rust/JS bridge.
|
|
15
|
+
|
|
16
|
+
- Rust plugin name: android-accessibility
|
|
17
|
+
- Kotlin plugin class: AndroidAccessibilityPlugin
|
|
18
|
+
- Kotlin accessibility service: TauriAccessibilityService
|
|
19
|
+
|
|
20
|
+
Implementation entry points:
|
|
21
|
+
|
|
22
|
+
- Rust commands are defined in [src/commands.rs](src/commands.rs)
|
|
23
|
+
- Mobile bridging is in [src/mobile.rs](src/mobile.rs)
|
|
24
|
+
- Android native implementation is in [android/src/main/java/com/tauri/plugin/androidaccessibility/AndroidAccessibilityPlugin.kt](android/src/main/java/com/tauri/plugin/androidaccessibility/AndroidAccessibilityPlugin.kt)
|
|
25
|
+
- Accessibility service is in [android/src/main/java/com/tauri/plugin/androidaccessibility/TauriAccessibilityService.kt](android/src/main/java/com/tauri/plugin/androidaccessibility/TauriAccessibilityService.kt)
|
|
26
|
+
|
|
27
|
+
## 2. Usage in Tauri App
|
|
28
|
+
|
|
29
|
+
Register the plugin on the application side:
|
|
30
|
+
|
|
31
|
+
```rust
|
|
32
|
+
tauri::Builder::default()
|
|
33
|
+
.plugin(tauri_plugin_android_accessibility::init())
|
|
34
|
+
.run(tauri::generate_context!())
|
|
35
|
+
.expect("error while running tauri application");
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
JS side (it is recommended to use bun for dependency installation and building):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
bun install
|
|
42
|
+
bun run build
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Example call:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
checkAccessibilityEnabled,
|
|
50
|
+
openAccessibilitySettings,
|
|
51
|
+
getFrontmostUiTree,
|
|
52
|
+
clickNode,
|
|
53
|
+
} from 'tauri-plugin-android-accessibility-api'
|
|
54
|
+
|
|
55
|
+
const status = await checkAccessibilityEnabled()
|
|
56
|
+
if (!status.enabled) {
|
|
57
|
+
await openAccessibilitySettings()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const tree = await getFrontmostUiTree({
|
|
61
|
+
maxDepth: 8,
|
|
62
|
+
maxChildrenPerNode: 40,
|
|
63
|
+
includeNonClickable: true,
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
await clickNode({
|
|
67
|
+
nodeId: '0.1.2',
|
|
68
|
+
action: 'click',
|
|
69
|
+
fallbackToClickableParent: true,
|
|
70
|
+
})
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 3. API List
|
|
74
|
+
|
|
75
|
+
### checkAccessibilityEnabled
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
|
|
79
|
+
- enabled: Whether the current app's accessibility service is enabled
|
|
80
|
+
- serviceId: Current service component ID
|
|
81
|
+
- enabledServices: List of accessibility services currently enabled by the system
|
|
82
|
+
|
|
83
|
+
### openAccessibilitySettings
|
|
84
|
+
|
|
85
|
+
Opens the system accessibility settings page, returns opened.
|
|
86
|
+
|
|
87
|
+
### getFrontmostUiTree
|
|
88
|
+
|
|
89
|
+
Parameters:
|
|
90
|
+
|
|
91
|
+
- maxDepth: Tree depth limit
|
|
92
|
+
- maxChildrenPerNode: Maximum number of child nodes per node
|
|
93
|
+
- includeNonClickable: Whether to include non-clickable leaf nodes
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
|
|
97
|
+
- timestampMs
|
|
98
|
+
- packageName
|
|
99
|
+
- root (recursive UI node)
|
|
100
|
+
|
|
101
|
+
### clickNode
|
|
102
|
+
|
|
103
|
+
Parameters:
|
|
104
|
+
|
|
105
|
+
- nodeId: Node path ID in the UI tree (e.g., 0.1.2)
|
|
106
|
+
- action: click | longClick | focus
|
|
107
|
+
- fallbackToClickableParent: Whether to fall back to a parent node click if the target fails
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
|
|
111
|
+
- success
|
|
112
|
+
- performedOnNodeId
|
|
113
|
+
- message
|
|
114
|
+
|
|
115
|
+
## 4. Android Specifications and Limitations
|
|
116
|
+
|
|
117
|
+
- Accessibility services are highly sensitive capabilities and must be manually authorized by the user in the system settings.
|
|
118
|
+
- This plugin does not attempt to bypass the system authorization process and will not silently enable accessibility.
|
|
119
|
+
- Reading the foreground app's UI tree depends on the system's visible windows and Android version behavior; results may be empty.
|
|
120
|
+
- Node clicks are affected by the target app's protection policies, dynamic UI states, and accessibility flags; 100% success is not guaranteed.
|
|
121
|
+
- Before submitting to an app store, please clearly inform users of the collection scope and purpose, and follow the app market's privacy and accessibility policies.
|
|
122
|
+
|
|
123
|
+
## 5. Permissions and Manifest
|
|
124
|
+
|
|
125
|
+
- Accessibility service declaration is located in [android/src/main/AndroidManifest.xml](android/src/main/AndroidManifest.xml)
|
|
126
|
+
- Service configuration is located in [android/src/main/res/xml/tauri_accessibility_service_config.xml](android/src/main/res/xml/tauri_accessibility_service_config.xml)
|
|
127
|
+
- The default set of Tauri plugin command permissions is located in [permissions/default.toml](permissions/default.toml)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@tauri-apps/api/core');
|
|
4
|
+
|
|
5
|
+
async function ping(value) {
|
|
6
|
+
return await core.invoke('plugin:android-accessibility|ping', {
|
|
7
|
+
payload: {
|
|
8
|
+
value,
|
|
9
|
+
},
|
|
10
|
+
}).then((r) => (r.value ? r.value : null));
|
|
11
|
+
}
|
|
12
|
+
async function checkAccessibilityEnabled() {
|
|
13
|
+
return await core.invoke('plugin:android-accessibility|check_accessibility_enabled');
|
|
14
|
+
}
|
|
15
|
+
async function openAccessibilitySettings() {
|
|
16
|
+
return await core.invoke('plugin:android-accessibility|open_accessibility_settings');
|
|
17
|
+
}
|
|
18
|
+
async function getFrontmostUiTree(payload = {}) {
|
|
19
|
+
return await core.invoke('plugin:android-accessibility|get_frontmost_ui_tree', {
|
|
20
|
+
payload,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function clickNode(payload) {
|
|
24
|
+
return await core.invoke('plugin:android-accessibility|click_node', {
|
|
25
|
+
payload,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.checkAccessibilityEnabled = checkAccessibilityEnabled;
|
|
30
|
+
exports.clickNode = clickNode;
|
|
31
|
+
exports.getFrontmostUiTree = getFrontmostUiTree;
|
|
32
|
+
exports.openAccessibilitySettings = openAccessibilitySettings;
|
|
33
|
+
exports.ping = ping;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export declare function ping(value: string): Promise<string | null>;
|
|
2
|
+
export interface AccessibilityPermissionStatus {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
serviceId: string;
|
|
5
|
+
enabledServices: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface Bounds {
|
|
8
|
+
left: number;
|
|
9
|
+
top: number;
|
|
10
|
+
right: number;
|
|
11
|
+
bottom: number;
|
|
12
|
+
}
|
|
13
|
+
export interface UiNode {
|
|
14
|
+
nodeId: string;
|
|
15
|
+
className?: string | null;
|
|
16
|
+
text?: string | null;
|
|
17
|
+
contentDescription?: string | null;
|
|
18
|
+
resourceId?: string | null;
|
|
19
|
+
packageName?: string | null;
|
|
20
|
+
bounds?: Bounds | null;
|
|
21
|
+
clickable: boolean;
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
focusable: boolean;
|
|
24
|
+
focused: boolean;
|
|
25
|
+
scrollable: boolean;
|
|
26
|
+
selected: boolean;
|
|
27
|
+
checkable: boolean;
|
|
28
|
+
checked: boolean;
|
|
29
|
+
longClickable: boolean;
|
|
30
|
+
children: UiNode[];
|
|
31
|
+
}
|
|
32
|
+
export interface UiTreeRequest {
|
|
33
|
+
maxDepth?: number;
|
|
34
|
+
maxChildrenPerNode?: number;
|
|
35
|
+
includeNonClickable?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface UiTreeResponse {
|
|
38
|
+
timestampMs: number;
|
|
39
|
+
packageName?: string | null;
|
|
40
|
+
root?: UiNode | null;
|
|
41
|
+
}
|
|
42
|
+
export interface ClickNodeRequest {
|
|
43
|
+
nodeId: string;
|
|
44
|
+
action?: 'click' | 'longClick' | 'focus';
|
|
45
|
+
fallbackToClickableParent?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface ClickNodeResponse {
|
|
48
|
+
success: boolean;
|
|
49
|
+
performedOnNodeId?: string | null;
|
|
50
|
+
message?: string | null;
|
|
51
|
+
}
|
|
52
|
+
export interface OpenSettingsResponse {
|
|
53
|
+
opened: boolean;
|
|
54
|
+
}
|
|
55
|
+
export declare function checkAccessibilityEnabled(): Promise<AccessibilityPermissionStatus>;
|
|
56
|
+
export declare function openAccessibilitySettings(): Promise<OpenSettingsResponse>;
|
|
57
|
+
export declare function getFrontmostUiTree(payload?: UiTreeRequest): Promise<UiTreeResponse>;
|
|
58
|
+
export declare function clickNode(payload: ClickNodeRequest): Promise<ClickNodeResponse>;
|
package/dist-js/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
2
|
+
|
|
3
|
+
async function ping(value) {
|
|
4
|
+
return await invoke('plugin:android-accessibility|ping', {
|
|
5
|
+
payload: {
|
|
6
|
+
value,
|
|
7
|
+
},
|
|
8
|
+
}).then((r) => (r.value ? r.value : null));
|
|
9
|
+
}
|
|
10
|
+
async function checkAccessibilityEnabled() {
|
|
11
|
+
return await invoke('plugin:android-accessibility|check_accessibility_enabled');
|
|
12
|
+
}
|
|
13
|
+
async function openAccessibilitySettings() {
|
|
14
|
+
return await invoke('plugin:android-accessibility|open_accessibility_settings');
|
|
15
|
+
}
|
|
16
|
+
async function getFrontmostUiTree(payload = {}) {
|
|
17
|
+
return await invoke('plugin:android-accessibility|get_frontmost_ui_tree', {
|
|
18
|
+
payload,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function clickNode(payload) {
|
|
22
|
+
return await invoke('plugin:android-accessibility|click_node', {
|
|
23
|
+
payload,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { checkAccessibilityEnabled, clickNode, getFrontmostUiTree, openAccessibilitySettings, ping };
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tauri-plugin-android-accessibility-api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "ShizukuAqua",
|
|
5
|
+
"description": "A Tauri plugin that supports Android accessibility features, allowing Tauri applications to interact with Android's accessibility services for enhanced functionality and user experience.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/zhangnjsd/tauri-plugin-android-accessibility.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/zhangnjsd/tauri-plugin-android-accessibility/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/zhangnjsd/tauri-plugin-android-accessibility#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"tauri",
|
|
17
|
+
"tauri-plugin",
|
|
18
|
+
"android",
|
|
19
|
+
"accessibility"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"types": "./dist-js/index.d.ts",
|
|
23
|
+
"main": "./dist-js/index.cjs",
|
|
24
|
+
"module": "./dist-js/index.js",
|
|
25
|
+
"exports": {
|
|
26
|
+
"types": "./dist-js/index.d.ts",
|
|
27
|
+
"import": "./dist-js/index.js",
|
|
28
|
+
"require": "./dist-js/index.cjs"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist-js",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "rollup -c",
|
|
36
|
+
"prepublishOnly": "bun run build",
|
|
37
|
+
"pretest": "bun run build"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@tauri-apps/api": "^2.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@rollup/plugin-typescript": "^12.0.0",
|
|
44
|
+
"rollup": "^4.9.6",
|
|
45
|
+
"typescript": "^5.3.3",
|
|
46
|
+
"tslib": "^2.6.2"
|
|
47
|
+
}
|
|
48
|
+
}
|