RepoPilotOpen in app →

zfdang/Android-Touch-Helper

AdSkip — an Android assistant for automatically skipping app launch ads

Mixed

Single-maintainer risk — review before adopting

weakest axis
Use as dependencyMixed

top contributor handles 97% of recent commits; no tests detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 4w ago
  • 4 active contributors
  • MIT licensed
Show all 7 evidence items →
  • CI configured
  • Small team — 4 contributors active in recent commits
  • Single-maintainer risk — top contributor 97% of recent commits
  • No test directory detected
What would change the summary?
  • Use as dependency MixedHealthy if: diversify commit ownership (top <90%)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/zfdang/android-touch-helper?axis=fork)](https://repopilot.app/r/zfdang/android-touch-helper)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/zfdang/android-touch-helper on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: zfdang/Android-Touch-Helper

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/zfdang/Android-Touch-Helper shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Single-maintainer risk — review before adopting

  • Last commit 4w ago
  • 4 active contributors
  • MIT licensed
  • CI configured
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 97% of recent commits
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live zfdang/Android-Touch-Helper repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/zfdang/Android-Touch-Helper.

What it runs against: a local clone of zfdang/Android-Touch-Helper — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in zfdang/Android-Touch-Helper | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 56 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>zfdang/Android-Touch-Helper</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of zfdang/Android-Touch-Helper. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/zfdang/Android-Touch-Helper.git
#   cd Android-Touch-Helper
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of zfdang/Android-Touch-Helper and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "zfdang/Android-Touch-Helper(\\.git)?\\b" \\
  && ok "origin remote is zfdang/Android-Touch-Helper" \\
  || miss "origin remote is not zfdang/Android-Touch-Helper (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "app/src/main/java/com/zfdang/touchhelper/TouchHelperService.java" \\
  && ok "app/src/main/java/com/zfdang/touchhelper/TouchHelperService.java" \\
  || miss "missing critical file: app/src/main/java/com/zfdang/touchhelper/TouchHelperService.java"
test -f "app/src/main/java/com/zfdang/touchhelper/TouchHelperServiceImpl.java" \\
  && ok "app/src/main/java/com/zfdang/touchhelper/TouchHelperServiceImpl.java" \\
  || miss "missing critical file: app/src/main/java/com/zfdang/touchhelper/TouchHelperServiceImpl.java"
test -f "app/src/main/java/com/zfdang/touchhelper/Settings.java" \\
  && ok "app/src/main/java/com/zfdang/touchhelper/Settings.java" \\
  || miss "missing critical file: app/src/main/java/com/zfdang/touchhelper/Settings.java"
test -f "app/src/main/java/com/zfdang/touchhelper/MainActivity.java" \\
  && ok "app/src/main/java/com/zfdang/touchhelper/MainActivity.java" \\
  || miss "missing critical file: app/src/main/java/com/zfdang/touchhelper/MainActivity.java"
test -f "app/src/main/java/com/zfdang/touchhelper/PackageWidgetDescription.java" \\
  && ok "app/src/main/java/com/zfdang/touchhelper/PackageWidgetDescription.java" \\
  || miss "missing critical file: app/src/main/java/com/zfdang/touchhelper/PackageWidgetDescription.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 56 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~26d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/zfdang/Android-Touch-Helper"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

AdSkip is an Android accessibility service that automatically detects and clicks ad skip buttons on app launch screens. It works by inspecting on-screen UI elements via the Accessibility API and removes ads using keyword detection (looking for 'Skip' buttons), predefined widget patterns per-app, or configured screen positions. The entire app is built in Java with zero network/storage permissions and no data collection. Single-module Android app structure: app/src/main/java/com/zfdang/touchhelper/ contains the core logic split into service components (TouchHelperService.java, TouchHelperServiceImpl.java), configuration (Settings.java, PackageWidgetDescription.java), and UI fragments (HomeFragment.java, SettingsFragment.java). TouchHelperApp.java is the Application class. Resources live in app/src/main/res/ with drawable icons and layout XMLs.

👥Who it's for

Android users frustrated by splash ads in apps they use daily. Also relevant to Android developers and security researchers interested in accessibility service patterns and privacy-first automation tools. Contributors are typically Android developers who want to improve ad-skipping accuracy for specific apps.

🌱Maturity & risk

Moderately mature but entering maintenance mode. The project has been around several years (git rev-list shows 100+ commits), uses modern Android (compileSdkVersion 35, minSdkVersion 26), has CI/CD via GitHub Actions (.github/workflows/build_apk.yml), and is published on F-Droid and Google Play. However, the maintainer explicitly noted they no longer have much time for active development and recommend the community fork gkd-kit/gkd as a more actively maintained alternative.

Low technical risk but moderate maintenance risk. The codebase is pure Java (100% of files) with minimal external dependencies—no network libraries or complex dependency chains. However, it's a single-maintainer project that is no longer actively maintained, meaning bug fixes or major Android API changes may go unaddressed. The accessibility service pattern is inherently fragile against Android OS updates that change UI frameworks or add permission restrictions.

Active areas of work

No active development visible. The build is triggered via GitHub Actions on commits (build_apk.yml), but no recent PR activity or open issues are mentioned in the file structure. The maintainer is in maintenance mode, reviewing community contributions only. The project appears to receive occasional dependency/SDK updates but no new feature work.

🚀Get running

Clone and build with Gradle: git clone https://github.com/zfdang/Android-Touch-Helper.git && cd Android-Touch-Helper && ./gradlew build. To install on a connected device: ./gradlew installDebug. You'll need Android SDK 35 and minSdkVersion 26 compatibility. For signing releases, set KEYSTORE_PASSWORD, KEY_ALIAS, and KEY_PASSWORD environment variables (or gradle.properties).

Daily commands: No traditional 'dev server'. Build and run via Android Studio or command line: ./gradlew assembleDebug && adb install app/build/outputs/apk/debug/app-debug.apk. After installation, enable the accessibility service in Settings → Accessibility → Touch Helper. The app runs as a persistent background service once enabled.

🗺️Map of the codebase

  • app/src/main/java/com/zfdang/touchhelper/TouchHelperService.java — Core accessibility service entry point that intercepts system events and delegates ad-skipping logic; every contributor must understand the service lifecycle and event handling pattern
  • app/src/main/java/com/zfdang/touchhelper/TouchHelperServiceImpl.java — Implements the three skip strategies (keyword detection, UI controls, screen positions); contains the primary ad-detection and click-automation logic
  • app/src/main/java/com/zfdang/touchhelper/Settings.java — Manages configuration persistence and retrieval for per-app rules and global settings; any new skip strategy requires settings schema updates here
  • app/src/main/java/com/zfdang/touchhelper/MainActivity.java — Activity entry point and navigation hub for the UI; connects to ViewModel and fragments that expose settings to users
  • app/src/main/java/com/zfdang/touchhelper/PackageWidgetDescription.java — Data class defining UI control targets (widgets) for per-app ad skipping; understand this to add new widget-based skip rules
  • app/build.gradle — Build configuration with dynamic versioning (git count + date); controls SDK levels (min 26, target 35), multidex support, and release signing
  • app/src/main/res/xml/accessibility_service_config.xml — Declares accessibility service capabilities (event types monitored); changes here affect what system events the service can intercept

🛠️How to make changes

Add a new per-app skip strategy (e.g., gesture-based)

  1. Create a new data class in app/src/main/java/com/zfdang/touchhelper/ extending the pattern of PackageWidgetDescription.java (fields for rule parameters) (app/src/main/java/com/zfdang/touchhelper/PackageWidgetDescription.java)
  2. Add storage methods in Settings.java to persist and retrieve your new rule type using SharedPreferences (follow patterns for loadPackageWidget* and savePackageWidget*) (app/src/main/java/com/zfdang/touchhelper/Settings.java)
  3. Implement detection and click logic in TouchHelperServiceImpl.java within onAccessibilityEvent() or create a new helper method (e.g., skipByGesture) following the three existing skip paths (app/src/main/java/com/zfdang/touchhelper/TouchHelperServiceImpl.java)
  4. Add UI dialog or form in ManagePackageWidgetsDialogFragment.java to let users configure the new rule type for each app (app/src/main/java/com/zfdang/touchhelper/ui/settings/ManagePackageWidgetsDialogFragment.java)

Add a new settings preference to the global settings UI

  1. Define the preference entry in app/src/main/res/xml/touch_helper_preference.xml (add a CheckBoxPreference, ListPreference, or custom PreferenceScreen item) (app/src/main/res/xml/touch_helper_preference.xml)
  2. Add getter/setter methods in Settings.java to read/write the preference value from SharedPreferences (app/src/main/java/com/zfdang/touchhelper/Settings.java)
  3. Reference the setting in TouchHelperServiceImpl.java or TouchHelperService.java to use the preference value in the skip logic (app/src/main/java/com/zfdang/touchhelper/TouchHelperServiceImpl.java)

Add a new UI fragment or tab to the bottom navigation

  1. Create a new Fragment class in app/src/main/java/com/zfdang/touchhelper/ui/ following the pattern of HomeFragment.java or SettingsFragment.java (app/src/main/java/com/zfdang/touchhelper/ui/home/HomeFragment.java)
  2. Create a layout XML file in app/src/main/res/layout/ (e.g., fragment_newtab.xml) for the fragment's UI (app/src/main/res/layout/fragment_home.xml)
  3. Add a new menu item in app/src/main/res/menu/bottom_nav_menu.xml with a unique id, icon, and label (app/src/main/res/menu/bottom_nav_menu.xml)
  4. Register the fragment in app/src/main/res/navigation/mobile_navigation.xml by adding a new action or fragment entry pointing to your new Fragment class (app/src/main/res/navigation/mobile_navigation.xml)

🔧Why these technologies

  • Android Accessibility Service — Only framework-level API that permits real-time inspection of on-screen UI hierarchy without requiring root or reverse-engineering; directly aligns with app's mission to detect and click ad skip buttons
  • SharedPreferences for Settings — Lightweight, device-local persistence suitable for per-app skip rules and global preferences; avoids network I/O entirely to preserve privacy (no data uploaded)
  • Fragment-based MVVM UI — Enables modular UI (home, settings, about tabs) with separation of concerns; ViewModel survives configuration changes and keeps UI state consistent
  • Broadcast Receivers (PackageChangeReceiver, UserPresentReceiver) — System-level hooks to refresh app list on install/uninstall and reapply rules on device unlock without polling

⚖️Trade-offs already made

  • Accessibility Service as sole permission model

    • Why: Only way to inspect foreground UI and trigger clicks without root; aligns with privacy goal (no sensitive data collected)
    • Consequence: Requires user to manually enable in Settings → Accessibility; cannot skip ads silently before user awareness; dependent on OS not restricting service lifecycle
  • Three separate skip strategies (keyword, widget, position) rather than unified rule engine

    • Why: Incremental coverage: simpler, more intuitive for end users to configure per-app rules
    • Consequence: Added code complexity in TouchHelperServiceImpl; no priority/conflict resolution if multiple rules match; harder to maintain consistency across strategies
  • Dynamic APK versioning (git commit count + date)

    • Why: Automatic version bumps without manual edits; visible release history
    • Consequence: Build requires git history; version name not semantic; harder to distinguish release stability
  • Minify SDK 26 (Android 8) with target SDK 35 (Android 15)

    • Why: Broad device reach; supports modern OS features while maintaining backward compatibility
    • Consequence: Must test compatibility across 7 major OS versions; some newer UI widgets unavailable on lower versions

🚫Non-goals (don't propose these)

  • Does not handle authentication or user accounts (fully local, device-only)
  • Does not support cloud

🪤Traps & gotchas

Accessibility Service requires explicit user enablement in Settings—app cannot auto-enable itself. ProGuard minification (enabled for release) may obscure class names in logs; keep proguard-rules.pro in sync when refactoring. Keystore signing for releases requires KEYSTORE_PASSWORD, KEY_ALIAS, and KEY_PASSWORD environment variables or gradle.properties entries—missing these will fail the build. The app targets Android 26+ but compileSdk 35; compatibility issues may arise on cutting-edge Android versions if Accessibility APIs change. Pinyin resource exclusion in packagingOptions suggests the project was adapted from another codebase.

🏗️Architecture

💡Concepts to learn

  • Android Accessibility Service API — This is the entire foundation of AdSkip—it grants permission to inspect and interact with on-screen UI elements, but also why the app requires explicit user trust
  • AccessibilityNodeInfo tree traversal — TouchHelperServiceImpl must walk the AccessibilityNodeInfo hierarchy to find clickable widgets; understanding tree depth, filtering, and performance is critical for adding new skip strategies
  • ProGuard/R8 code obfuscation and shrinking — Release builds use ProGuard minification (minifyEnabled true in build.gradle); changes to class/method names and removed code must be tracked to avoid breakage
  • Broadcast Receivers for system events — PackageChangeReceiver and UserPresentReceiver listen for app installs and screen unlocks to trigger adaptive ad-skipping; understanding receiver lifecycle is essential for adding new triggers
  • SharedPreferences for app configuration — Settings.java persists per-app rules and user preferences; understanding SharedPreferences serialization is needed when modifying configuration models (PackageWidgetDescription, etc.)
  • MVVM pattern with Android ViewModel — HomeViewModel demonstrates lifecycle-aware data binding; new UI features should follow this pattern to avoid memory leaks and configuration change crashes
  • Multi-strategy pattern detection (keyword, widget, position) — AdSkip implements three orthogonal skip detection strategies; understanding the tradeoff between accuracy (widget matching) and robustness (position fallback) informs decisions to add or modify strategies
  • gkd-kit/gkd — Directly recommended by this project's maintainer as a more actively maintained alternative for ad-skipping automation with community rule sets
  • LGH1996/AccessibilityTool — Original inspiration and code source acknowledged in this project's README; demonstrates earlier accessibility service patterns for Android automation
  • google/android-open-source-project — AOSP accessibility framework documentation and source; required reading to understand AccessibilityEvent, AccessibilityNodeInfo, and service lifecycle
  • androidx/androidx — AndroidX libraries used implicitly (fragments, view models, lifecycle); critical for understanding modern Android patterns and future compatibility

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for TouchHelperServiceImpl.java core ad-skipping logic

The repo has no test directory despite critical accessibility service logic in TouchHelperServiceImpl.java that detects and clicks skip buttons. This class handles the three ad-skipping methods (keyword detection, UI controls, screen positions) and lacks coverage. Adding unit tests would catch regressions in ad-detection patterns and accessibility node parsing, which are core to the app's functionality.

  • [ ] Create app/src/test directory structure
  • [ ] Write unit tests for keyword detection matching logic in TouchHelperServiceImpl
  • [ ] Write unit tests for PackageWidgetDescription and PackagePositionDescription matching logic
  • [ ] Add tests for UI accessibility node filtering and coordinate calculations
  • [ ] Configure testInstrumentationRunner in build.gradle and add androidx.test dependencies

Add instrumentation tests for accessibility service integration with MainActivity UI workflows

The app has UI fragments (HomeFragment, SettingsFragment, ManagePackageWidgetsDialogFragment) for configuring ad-skip targets but no instrumentation tests to verify the UI correctly persists settings or integrates with TouchHelperService. This is critical since misconfiguration directly breaks ad-skipping functionality.

  • [ ] Create app/src/androidTest directory with proper structure
  • [ ] Write instrumentation test for SettingsFragment: verify package selection saves to Settings.java
  • [ ] Write instrumentation test for ManagePackageWidgetsDialogFragment: verify widget coordinates persist correctly
  • [ ] Add test for MainActivity bottom navigation fragment transitions
  • [ ] Configure androidTestImplementation dependencies (espresso, androidx.test.ext.junit)

Refactor monolithic TouchHelperService.java into separate handler classes and document the accessibility event flow

TouchHelperService.java likely contains mixed concerns (service lifecycle, event handling, matching logic, click execution) in one file. The file is missing from the partial file structure but referenced in the design. Additionally, there's no documentation explaining how PackageChangeReceiver, UserPresentReceiver, and TouchHelperService interact. Breaking these into focused classes (e.g., AccessibilityEventHandler, AdMatcher, ClickExecutor) would improve maintainability and add a CONTRIBUTING.md guide showing the event flow.

  • [ ] Create app/src/main/java/com/zfdang/touchhelper/handlers/ directory
  • [ ] Extract accessibility event listening into AccessibilityEventHandler.java
  • [ ] Extract ad matching logic into separate AdMatcherByKeyword.java, AdMatcherByWidget.java, AdMatcherByPosition.java classes
  • [ ] Extract click execution into ClickExecutor.java
  • [ ] Write CONTRIBUTING.md documenting the event flow: PackageChangeReceiver → TouchHelperService → Handlers → ClickExecutor
  • [ ] Add Javadoc comments to new handler classes

🌿Good first issues

  • Add unit tests for PackageWidgetDescription.java and PackagePositionDescription.java parsing logic—currently no test/ directory visible, making it easy for rule parsing bugs to slip through
  • Expand keyword detection in TouchHelperServiceImpl.java to support regex patterns or localization (currently hardcoded for 'Skip' in English)—add a resource file for keywords per language
  • Document the per-app rule format and create a guide in app/src/main/res/raw/ or wiki showing how to export/import configurations—currently only UI-driven configuration exists

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 037d2c0 — update build workflow JDK from 11 to 17 (zfdang)
  • 1ab7696 — upgrade deprecated GitHub Actions to latest versions (zfdang)
  • a3bb309 — fix proguard rules for navigation component crash (zfdang)
  • f91d396 — update readme (zfdang)
  • dc32c6f — upgrade (zfdang)
  • 367525c — Update build_apk.yml workflow configuration (zfdang)
  • ad1bf8e — Update README.md (zfdang)
  • 81ae646 — Update README.md (zfdang)
  • 3e118dc — Add files via upload (zfdang)
  • 6efe643 — Add files via upload (zfdang)

🔒Security observations

The Android-Touch-Helper project has moderate security concerns. The most critical issue is the presence of a keystore file in the repository,

  • High · Keystore File Committed to Repository — app/touch_helper.keystore. The keystore file 'app/touch_helper.keystore' is committed to the repository. This file contains the private key used for signing APKs and should never be stored in version control, as it could be extracted and used to sign malicious APKs that could be distributed as legitimate updates. Fix: Remove the keystore file from the repository immediately using 'git rm --cached app/touch_helper.keystore', add it to .gitignore, and regenerate the keystore with a new password. Store the keystore securely outside the repository, preferably in a secure CI/CD secret management system.
  • High · Sensitive Credentials in Build Configuration — app/build.gradle (signingConfigs.release block). Keystore credentials (KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD) are retrieved from project properties or environment variables in the build.gradle file. While environment variables are better than hardcoding, storing these in CI/CD systems or local machine requires proper access controls. If the CI/CD workflow file contains these secrets, they could be exposed. Fix: Ensure credentials are only stored in secure secret management systems (GitHub Secrets, GitLab Variables, etc.). Never log or print these values. Use masked output in CI/CD pipelines. Rotate credentials regularly.
  • Medium · Incomplete Build Configuration Output — app/build.gradle (android.applicationVariants.all block). The build.gradle file appears truncated in the android.applicationVariants.all block. The output configuration 'output.outputFi' is incomplete, which could indicate a build configuration issue or hidden code that wasn't fully displayed. Fix: Review and complete the build configuration block. Ensure all build outputs are properly configured and validated. Enable code review processes for build configuration changes.
  • Medium · Git Command Execution in Build Script — app/build.gradle (getDate() and gitVersion calculation). The build script executes 'git rev-list HEAD --count' directly without validation. This could be exploited if repository hooks or git configurations are compromised. Additionally, this approach fails in shallow clones or detached HEAD states. Fix: Use Gradle Git plugin instead of executing raw git commands. Implement error handling for edge cases (shallow clones, detached HEAD). Validate the output is a valid integer before processing.
  • Medium · Accessibility Service with Broad Permissions — app/src/main/java/com/zfdang/touchhelper/TouchHelperService.java, app/src/main/res/xml/accessibility_service_config.xml. The app implements an Accessibility Service (TouchHelperService) that can inspect on-screen content and perform clicks. While the project claims not to collect data, accessibility services have broad permissions to access sensitive on-screen information. Users should be explicitly informed of this capability. Fix: Ensure the accessibility service configuration has minimal required permissions. Implement clear user consent flows. Log all accessibility events for audit purposes. Consider implementing local-only data retention policies. Provide users ability to disable specific features.
  • Low · Resource Localization Limited to Chinese — app/build.gradle (resourceConfigurations = ['zh-rCN']). The app restricts resource configurations to only 'zh-rCN' (Simplified Chinese). While this reduces APK size, it limits the app's usability for non-Chinese users and may create confusion if the app is distributed globally. Fix: Consider supporting additional languages or making localization configurable. If intentionally limiting to Chinese market, ensure distribution channels reflect this restriction.
  • Low · ProGuard Configuration Not Fully Visible — app/proguard-rules.pro. The app uses ProGuard obfuscation (minifyEnabled true) in release builds, which is good for code protection. However, the actual ProGuard rules in 'app/proguard-rules.pro' were not provided for review to verify they don't accidentally expose sensitive code paths. Fix: Review ProGuard rules to ensure sensitive classes and methods are properly obfuscated. Keep exception handling rules minimal to avoid exposing stack traces. Test obfuscated builds thoroughly.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · zfdang/Android-Touch-Helper — RepoPilot