Termux:API commands hang due to "Invalid action: com.termux.service_api" - Proposed Broadcast Fix
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.3k
- Forks
- 920
- PR merge metrics
- No merged PRs in 30d
Description
Disclaimer:
This report has been prepared by Gemini 3.0. It has successfully solved the issue for me and, while I do not have a complete understanding of what it has done, I hope this might be useful anyway.
Gemini has been debugging a user's local Termux environment where termux-api commands were failing. I am reporting the specific findings, logs, and a confirmed working solution derived from this session to assist the mantainers. Happy to help further, if needed.
Environment
- Device: Android (Xiaomi/MIUI environment detected in logs)
- Termux App Version: 0.118.3 (F-Droid signature)
- Termux:API App Version: 0.53.0 (F-Droid signature)
- termux-api package: 0.59.1 (aarch64)
The Issue
Execution of any API command (e.g., termux-battery-status, termux-vibrate) hangs indefinitely. The commands never return output and eventually timeout if a timeout is enforced.
Logcat Analysis:
When running termux-battery-status, the system log shows TermuxService rejecting the intent:
ActivityManager: Logging startService for com.termux, ... intent=Intent { act=com.termux.service_api cmp=com.termux/.app.TermuxService ... }
Termux:TermuxService: Invalid action: "com.termux.service_api"
It appears the current termux-api binary (C helper) attempts to start com.termux.app.TermuxService with the action com.termux.service_api. The main Termux app's service implementation (in onStartCommand) falls through or explicitly logs this action as invalid/unhandled.
Investigation & Attempts
- Standard Execution: Confirmed
am startservice -a com.termux.service_api ...fails with the log error above. - Service Execute: Tried
am startservice -a com.termux.service_execute ...(which is handled byTermuxService), but this expects a plugin execution context/runner and did not successfully bridge to the API logic. - Targeting the Receiver directly:
We analyzed theTermux:APImanifest anddumpsys.com.termux.api.TermuxApiReceiveris a registered receiver. Although declared withandroid:exported="false", it shares the same signature and user ID as the main Termux app, allowing interaction via root or same-user contexts.
The Solution (Verified)
We created a Python shim to replace /data/data/com.termux/files/usr/libexec/termux-api.
Instead of calling am startservice targeting the main app, the shim calls am broadcast targeting the API receiver directly.
Old Command (failing):
am startservice --user 0 -n com.termux/com.termux.app.TermuxService -a com.termux.service_api --es api_method BatteryStatus ...
New Command (Working):
am broadcast --user 0 -n com.termux.api/.TermuxApiReceiver --es api_method BatteryStatus ...
Verification
We verified this fix locally by replacing the libexec/termux-api binary with a Python script implementing the broadcast logic.
- BatteryStatus: Returns JSON correctly.
- Vibrate: Vibrates the device (permissions granted).
- Clipboard: Works correctly (implemented stdin reading in the shim to pass to the input socket).
- JobScheduler: Successfully lists and schedules jobs.
Recommendation
The issue seems to be a disconnect between how the termux-api C binary invokes the service and how the TermuxService (in the main app) expects to be called (or has stopped supporting service_api).
Updating the termux-api.c client to use an Intent Broadcast targeting com.termux.api/.TermuxApiReceiver (rather than starting the main TermuxService) appears to resolve the issue entirely on this version combination.
Key technical note for the fix:
If implementing this in the C binary, ensure the input socket handling (stdin) is maintained, as the TermuxApiReceiver logic appears to handle the socket connections correctly once triggered via Broadcast.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with termux-api.c and the attached termux_api_shim.py; compare the proposed broadcast invocation with TermuxApiReceiver and the existing TermuxService path. Run termux-battery-status, termux-vibrate, clipboard, and JobScheduler commands, including clipboard stdin handling, and verify they return or complete without hanging.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, c, java, python
- Domain
- api, cli, mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100