Termux integration with custom button feature

Support for Android version of Total Commander

Moderators: Hacker, petermad, Stefan2, white

Tcrocks
Junior Member
Junior Member
Posts: 12
Joined: 2024-11-22, 07:21 UTC

Re: Termux integration with custom button feature

Post by *Tcrocks »

Thanks, that was the important factor to get it to work! The Play Store version did not work AT ALL with 3rd party apps:
Sorry for slow response, I hadn't been at a PC for a while. I'm glad you were able to get some of it working using the github version. I wish I had mentioned it earlier!

In regards to the error message you're seeing, your suspicions are correct. The `com.termux.permission.RUN_COMMAND` permission is required to start the `RunCommandService`
as you know, the app that executees the `adb shell` commands is the ADB itself, however, ADB doesn't have a package name or a UI component that can request permissions.

you can try granting it with

Code: Select all

adb shell pm grant com.termux android.permission.INTERACT_ACROSS_USERS
This may not work as the `com.termux.permission.RUN_COMMAND` permission is a custom permission defined by Termux.

if that doesn't work you could try using the `--user 0` flag with the `am startservice` command:

Code: Select all

adb shell am startservice --user 0 -n com.termux/com.termux.app.RunCommandService \
  -a com.termux.RUN_COMMAND \
  --es com.termux.RUN_COMMAND_PATH '/data/data/com.termux/files/usr/bin/top' \
  --esa com.termux.RUN_COMMAND_ARGUMENTS '-n,5' \
  --es com.termux.RUN_COMMAND_WORKDIR '/data/data/com.termux/files/home' \
  --ez com.termux.RUN_COMMAND_BACKGROUND 'false' \
  --es com.termux.RUN_COMMAND_SESSION_ACTION '0'
The system user should have the necesary permissions to start the `RunCommandService`. If that still doesn't work, you can try granting the `com.termux.permission.RUN_Command`
permission to the `com.android.adb` package like so:

Code: Select all

adb shell pm grant com.android.adb com.termux.permission.RUN_COMMAND
My guess is that it happens because the Termux service isn't running when Termux itself isn't running. I have to start both Termux and Total Commander manually to be able to send commands from Total Commander to Termux.
You are correct, this is due to the way Android handles background services and permissions after 8.0. When the Termux service is stopped, and its process is terminated, you can't start it from the background when the app is not in the foreground without the users knowledge (usually through a popup)

The `checkSelfPermission(termuxPermission)` method returning `PackageManager.PERMISSION_GRANTED` is not relevant in this case, as the permission check is not the issue. The problem is that the Termux service is not running, and your app is trying to start it from the background.

you could any of the following to resolve this:

As you've already discovered, starting both Termux and Total Commander manually allows you to send commands from Total Commander to Termux.

You can modify your app to use a foreground service, which can run even when the app is not in the foreground. However, this requires displaying a notification to the user, indicating that the service is running.

You can try using a workaround, such as starting Termux using an `am start` command, like this:

Code: Select all

adb shell am start -n com.termux/.app.TermuxActivity
This will start the Termux activity, which should also start the Termux service.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50383
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Termux integration with custom button feature

Post by *ghisler(Author) »

I don't understand why Termux uses a service to accept commands, it just doesn't make any sense to me. They should just do what all other apps do, accept commands via Intent sent to the activity. This launches the activity when it isn't running yet, and sends a "new intent" event if the activity is already running.
Author of Total Commander
https://www.ghisler.com
Tcrocks
Junior Member
Junior Member
Posts: 12
Joined: 2024-11-22, 07:21 UTC

Re: Termux integration with custom button feature

Post by *Tcrocks »

ghisler(Author) wrote: 2025-01-05, 08:27 UTC I don't understand why Termux uses a service to accept commands, it just doesn't make any sense to me. They should just do what all other apps do, accept commands via Intent sent to the activity. This launches the activity when it isn't running yet, and sends a "new intent" event if the activity is already running.
some scripts or tasks can take a long time to run as termux emulates a linux machine, most things you can do in linux you should be able to do within termux. Some you would even want to run consecutively with other work you are doing. If a task is running and it gets destroyed before it is finished that could be problematic.

so using Broadcast as a reciever is too short lived (max ~15s)

Activity is also not used because they can be sent to background and similarly be destroyed prematurely.

Termux manages, stores, and recieves shell commands even if app is in background and activity is not in foreground. Android currently requires a foreground service for running long term tasks. This provides a lot of flexibility in your termux scripts especially if you are using them to manage server tasks or performing complex multi-step file operations
ie. scanning video files for duplicates by comparing snapshots at a time that all videos share.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50383
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Termux integration with custom button feature

Post by *ghisler(Author) »

So what is the recommended way to launch a command when Termux isn't running yet?
Author of Total Commander
https://www.ghisler.com
Tcrocks
Junior Member
Junior Member
Posts: 12
Joined: 2024-11-22, 07:21 UTC

Re: Termux integration with custom button feature

Post by *Tcrocks »

ghisler(Author) wrote: 2025-01-06, 07:57 UTC So what is the recommended way to launch a command when Termux isn't running yet?
It's recommended to use the `am startservice` command with the `--user 0` flag. This will start the Termux service and execute the `top` command, as an example, with the specified arguments.

Code: Select all

am startservice --user 0 -n com.termux/com.termux.app.RunCommandService -a com.termux.RUN_COMMAND --es com.termux.RUN_COMMAND_PATH '/data/data/com.termux/files/usr/bin/top' --esa com.termux.RUN_COMMAND_ARGUMENTS '-n,5'
you could also tell termux to run that in the background

Code: Select all

am startservice --user 0 -n com.termux/com.termux.app.RunCommandService -a com.termux.RUN_COMMAND --es com.termux.RUN_COMMAND_PATH '/data/data/com.termux/files/usr/bin/top' --esa com.termux.RUN_COMMAND_ARGUMENTS '-n,5' --ez com.termux.RUN_COMMAND_BACKGROUND true
you could also use `termux-exec` which will start the Termux service and execute the specified command, if Termux is not already running.

Code: Select all

termux-exec top -n 5
and to run in the backround just add a `b` flag

Code: Select all

termux-exec -b top -n 5
`termux-exec` may be more convenient because it doesn't require specifying the Intent and the command path.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50383
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Termux integration with custom button feature

Post by *ghisler(Author) »

It's recommended to use the `am startservice` command
That's not what I mean - what you describe would be from a PC via ADB.

What I mean is the following: The user has created a button in Total Commander to execute a command via Termux. But after a reboot, Termux isn't running. The user presses the button and gets an error back.
Author of Total Commander
https://www.ghisler.com
Tcrocks
Junior Member
Junior Member
Posts: 12
Joined: 2024-11-22, 07:21 UTC

Re: Termux integration with custom button feature

Post by *Tcrocks »

ghisler(Author) wrote: 2024-12-29, 09:58 UTC I have a strange problem: When I close both Total Commander and Termux via Task Manager, and then try to send a command to Termux via Termux service, I get the following error:
Not allowed to start service Intent { act=com.termux.RUN_COMMAND flg=0x10000000 cmp=com.termux/.app.RunCommandService (has extras) }: app is in background uid null
although checkSelfPermission(termuxPermission) returns PackageManager.PERMISSION_GRANTED.

My guess is that it happens because the Termux service isn't running when Termux itself isn't running. I have to start both Termux and Total Commander manually to be able to send commands from Total Commander to Termux.
I must have missed this message earlier. From what I understand, there are restrictions after Oreo on background execution. https://developer.android.com/about/versions/oreo/android-8.0-changes
https://stackoverflow.com/questions/47209662/error-app-is-in-background-uid-null

can you try using

Code: Select all

am start-foreground-service
and see if it loads it up? I don't know the exact implimentation of your start app functionality but perhaps you could leverage that to open the app and then run the service in one go.
ghisler(Author) wrote: 2025-01-07, 08:16 UTC
It's recommended to use the `am startservice` command
That's not what I mean - what you describe would be from a PC via ADB.

What I mean is the following: The user has created a button in Total Commander to execute a command via Termux. But after a reboot, Termux isn't running. The user presses the button and gets an error back.
I believe I understand what you mean. I've been playing around with the button feature for a bit. you can actually pass the am start using the 'sh' functionaliy (at least in the 3.30 version) but it all has to be on one line. I cant actually confirm it yet because im not going to modify your app without proper permission, but the error i get (a truncated pop-up) matches what others get when trying the same thing through adb, namely that the RUN_COMMAND permissions are not granted. which is what i would expect and want. I've tried a lot of things but this is what seems to produce that message:

in the parameters field of the send shell command all as one line:

Code: Select all

am start-foreground-service --user 0 -n com.termux/com.termux.app.RunCommandService -a com.termux.RUN_COMMAND --es com.termux.RUN_COMMAND_PATH '/data/data/com.termux/files/usr/bin/top' --esa com.termux.RUN_COMMAND_ARGUMENTS '-n,5' --es com.termux.RUN_COMMAND_WORKDIR '/data/data/com.termux/files/home' --ez com.termux.RUN_COMMAND_BACKGROUND 'false' --es com.termux.RUN_COMMAND_SESSION_ACTION '0'
These constants can be imported by adding the termux-shared library to your program to make it more user-friendly. I hope im understanding the issue you're experiencing. Was the error you sent earlier the one you kept getting?

You could also try if that doesn’t work:
Disabling battery optimizations
Granting draw over permissions
Post Reply