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 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>;
@@ -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
+ }