Is it possible to run termux commands through Activity Starter?

Termux is a self contained terminal app, that can run linux commands.

There is a guide to calling termux from a third party app (written in java)

RunCommandService.java

I have a termux session up and running on my device, and I have created the setting for external apps in .termux/termux-properties (allow-external-apps = true)

This is what I have so far in my blocks, but I am getting FAIL back from ResolveActivity:

(I am trying to run a simple ls command on the "HOME" directory, in which I have created two files, one.txt and two.txt. I have checked in the /usr/bin for the ls command, and this works directly in termux)

In the java, one of the instructions is:

Third-party program must declare
com.termux.permission.RUN_COMMAND
permission and it should be granted by user.

This doesn't seem possible from within App Inventor (and there does not appear to be anywhere in termux to set the permission) ? Any suggestions or ideas ?

You can create a dummy extension to enable a custom permission in your compiled app.

Btw, why some text blocks have trailing whitespaces? :thinking:

That is just how Download all blocks as image does it sometimes, other times the text spills out beyond the block!

I will need to get some help with that :wink:

There you go

// TermuxPermission.java
package test.termux.permission;

import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.runtime.*;
import com.google.appinventor.components.common.*;

@DesignerComponent(version = 1,
                   description = "Grants Termux permission",
                   category = ComponentCategory.EXTENSION,
                   nonVisible = true,
                   iconName = "images/extension.png")
@SimpleObject(external = true)
@UsesPermissions(permissionNames = "com.termux.permission.RUN_COMMAND")
public class TermuxPermission extends AndroidNonvisibleComponent {

    public TermuxPermission(ComponentContainer container) {
        super(container.$form());
    }  
}

You may compile it using Appybuilder extension IDE online.

2 Likes

@pavi2410 That is very kind, thank you.

Just upload the java file and it will be compiled fast:

http://bot.colintree.cn:8048/

1 Like

Thanks to all for your input, and to Sunny for compiling the aix.

Sadly, I am still getting the Error 601, no corresponding activity found (FAIL). Tested with companion and compiled version on Android 10. I tried moving things around, renaming but to no avail.

So more work to do.

I will run app/termux through logcat, and see if there is anything different in the package/class/action requirements...

Other suggestions most welcome :slight_smile:

1 Like

Is there anything in here we need to be handling ? (from the java file)

if (allowExternalApps() && RUN_COMMAND_ACTION.equals(intent.getAction())) {
            Uri programUri = new Uri.Builder().scheme("com.termux.file").path(parsePath(intent.getStringExtra(RUN_COMMAND_PATH))).build();

            Intent execIntent = new Intent(TermuxService.ACTION_EXECUTE, programUri);
            execIntent.setClass(this, TermuxService.class);
            execIntent.putExtra(TermuxService.EXTRA_ARGUMENTS, intent.getStringArrayExtra(RUN_COMMAND_ARGUMENTS));
            execIntent.putExtra(TermuxService.EXTRA_CURRENT_WORKING_DIRECTORY, parsePath(intent.getStringExtra(RUN_COMMAND_WORKDIR)));
            execIntent.putExtra(TermuxService.EXTRA_EXECUTE_IN_BACKGROUND, intent.getBooleanExtra(RUN_COMMAND_BACKGROUND, false));

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                this.startForegroundService(execIntent);
            } else {
                this.startService(execIntent);
            }
        }

        runStopForeground();

        return Service.START_NOT_STICKY;
    }

Yes, Activity Starter component can't start a service because it calls startActivity()/startActivityForResult() but to start a Service you need to call startService()/startForegroundService().

1 Like

Hmmm, so adding this to the Extras (which I already have...) is not enough?

image

No, Activity Starter can't start a service.
That extra value defines whether service should be sticky(auto start itself when killed) or not.

Made some progress, using

Activity Package = com.termux
Activity Class = com.termux.app.TermuxActivity

I can at least open termux from AppInventor and return with the back button.

Done some logcats on termux and the test app. can't find anything of much use.

If anyone wants a scour through some code: (note, i attempted many things so some errors were caused rather than embedded)

controltermux.txt (944.8 KB) termux.txt (16.0 KB)

You can always start an Activity using Activity Starter Component.

I forgot to put up the aix file for completeness

test.termux.permission.aix (4.2 KB)

Current blocks, in case there is anything wrong there:

Is it working? :thinking:

Unfortunately not. Error 601 no corresponding activity....

Other than installing the extension, should I be doing anything with it? There are no blocks to do anything...

An extension is needed which can start service by taking intent parts as parameter(s).
I think that also needs to be added in the component.

Here are a few (relevant) lines of the Manifest from a decompiled Termux app:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

<service android:exported="false" android:name="com.termux.app.TermuxService"/>
<service android:exported="true" android:name="com.termux.app.RunCommandService" android:permission="com.termux.permission.RUN_COMMAND">
<intent-filter>
<action android:name="com.termux.RUN_COMMAND"/>
</intent-filter>
</service>

As you can see, there are some services declared.
I guess these are missing in yours.

1 Like

Because "Android" (or Termux or AppInventor's Activity Starter, or a combination of all three) is making it so difficult (for me, at least), I decided to search out an alternative approach.

This I found in Termux, with the ability to setup an apache http server with php. With a simple php file in Termux's htdocs directory, I am able to send linux commands using shell_exec, and receive back the standard output just using the web component. This works in a similar fashion to Juan's terminal extension. Termux provides the user with a much broader range of commands and programs to use than that which is available on most devices, plus it also has r/w access to the device storage directories, sdcard and files.

I will write a more detailed guide once I have had time to flesh out my demo app.

In the meantime, if someone is able to get things working using activityStarter (and/or an extension), then I am all ears :slight_smile:

1 Like