termux / termux/termux-api

Termux:API commands hang due to "Invalid action: com.termux.service_api" - Proposed Broadcast Fix

Open
#844 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
4.3k
Forks
920
PR merge metrics
No merged PRs in 30d

Description

termux_api_shim.py

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
  1. Standard Execution: Confirmed am startservice -a com.termux.service_api ... fails with the log error above.
  2. Service Execute: Tried am startservice -a com.termux.service_execute ... (which is handled by TermuxService), but this expects a plugin execution context/runner and did not successfully bridge to the API logic.
  3. Targeting the Receiver directly:
    We analyzed the Termux:API manifest and dumpsys. com.termux.api.TermuxApiReceiver is a registered receiver. Although declared with android: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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.