📱

Termuxで動作するAndroidのGUIを利用したアプリの作成

2021/10/01に公開

はじめに

Androidでターミナルエミュレーターが動作する「Termux」と言うアプリをご存知でしょうか?
https://wiki.termux.com/wiki/Main_Page

かなり高機能なアプリで、Linux向けのソフトウェアを気軽に動作させることも出来るため、Androidを利用されている開発者の方であれば既に触ったことがある方も多いかもしれません。
そんなTermuxですが、久々に触ってみたところ、

  • ダイアログを表示するなどしてGUIを用いて入力を取得する機能
  • ホーム画面にショートカットを設置し、ワンタップで任意のバイナリ/シェルスクリプトを実行できる機能

が存在することに気が付きました。これを用いれば、簡単な要件であればAndroidアプリの仕様に基づく制限(使用言語だったり開発環境だったり)を突破して、Termuxで動かすことのできる好きな言語でアプリを作成し、ちょっとした機能拡張を行えそうです。試してみたところこれがなかなかいい感じだったので紹介してみます。

Termuxの導入

Termuxをまだ導入されていない方は以下を参考に導入を行ってください。記載されている通り、F-Droidから導入されることをおすすめします。

https://wiki.termux.com/wiki/Installation

TermuxでGUIを通じてユーザーの入力を取り扱う

TermuxにはAndroidのGUIを取り扱ういくつかのコマンドが提供されています。今回はそのうちの一つのTermux-dialogを利用します。

https://wiki.termux.com/wiki/Termux-dialog

これは名前の通りダイアログの表示を介したユーザーの入力を取り扱うことが出来ます。

Termux-dialogを利用できる状態にする

Termux-dialogはTermuxをインストールした直後の状態では利用できません。これを利用できるようにするには、Termux-dialogを含む各種の機能拡張を提供する「Termux:API」を導入する必要があります。

https://wiki.termux.com/wiki/Termux:API

「Termux:API」は以下の手順で導入できます。

  1. F-DroidからTermux:APIをインストール
  2. Termux上でpkg install termux-apiを実行

Termux-dialogを触ってみる

Termux:APIの導入が完了した状態で以下のコマンドをTermux上で実行してください。

termux-dialog radio -t "フォーム" -v "りんご,もも,みかん"

すると以下のように "りんご,もも,みかん"の三つの選択肢を持ったダイアログが表示されます。

ここで、りんごを選択すると、以下のようなjsonが出力されます。

{
  "code": -1,
  "text": "りんご",
  "index": 0
}

それぞれ

  • code
    • CANCEL、ダイアログ外タップでキャンセル時に-2, OKタップ時に-1
  • text
    • タップした項目に表示されていたテキスト
  • index
    • タップした項目のindex番号。上から0, 1, 2...という感じです。項目をタップしていない状態で、CANCEL、OK、ダイアログ外タップをした場合にはこの値は渡されません。

という意味のパラメータとなります。これを利用することで、ユーザーが選択した項目を知ることが出来ます。

Termux上で実行されるバイナリはAndroidアプリに関する知識を持たなくても、このコマンドを使ってダイアログを利用したユーザーとの対話を実現できます。例えばgoの場合だと以下のようにexec.Commandを利用してこのコマンドを呼出し、その入力結果をコード中で扱うことができるようになります。

main.go
package main

import (
	"encoding/json"
	"os/exec"
	"strings"
)

type SelectedItem struct {
	Code  int    `json:"code"`
	Text  string `json:"text"`
	Index int    `json:"index"`
}

func main() {
	texts := []string{"りんご", "みかん", "もも"}

	cmd := exec.Command("termux-dialog", "radio", "-t", "フォーム", "-v", strings.Join(texts, ","))
	out, err := cmd.Output()
	if err != nil {
		panic(err)
	}

	var selectedItem SelectedItem
	err = json.Unmarshal(out, &selectedItem)
	if err != nil {
		panic(err)
	}
	
	// 何も選択されていない場合に処理を終了
	if selectedItem.Index == nil {
		return
	}

	// キャンセルされた際に処理を終了
	if selectedItem.Code != -1 {
		return
	}
	
	// selectedItemを利用した処理を以下に実装
	
}

今回の例では、単純なテキストに対応する選択肢を提供するダイアログを表示しましたが、他にも数字や日付の選択を要求するダイアログの表示も可能です。気になった方は公式ドキュメントを参照してみてください。

ホームにショートカットを置く

ここまでで色々な言語でAndroidのGUIを用いたユーザーの入力を取り扱うソフトウェアを作成できるようになりました。しかし、この方法で作成されたソフトウェアを動作させるにはTermux上で実行する必要があり、日常的に利用するには少し不便です。
Termuxにはこの問題を解決できるTermux:Widgetという拡張機能が用意されており、これを導入することでワンタップでTermux上でソフトウェアを動作させることができるAndroidのWidgetをホーム画面に設置できるようになります。

https://wiki.termux.com/wiki/Termux:Widget

Termux:Widgetを利用できる状態にする

F-DroidからTermux:Widgetをインストールすると完了です。
https://f-droid.org/packages/com.termux.widget/

Termux:Widgetの使い方

~/.shortcuts/tasksに実行したいシェルスクリプトまたはバイナリのファイルを配置し、chmod +xで実行可能にします。Termux:Widgetを導入した状態であれば、各種ホーム画面アプリのウィジェット設定画面でTermuxのWidgetが表示されているようになっているので、その後にホーム画面にTermuxのWidgetを設置します。すると~/.shortcuts/以下に配置されたファイルの一覧が表示されるので、実行したいファイルを選択します。こうするとAndroidのホーム画面にWidgetが配置されます。このWidgetをタップすることで該当のファイルを実行できます。

goを使っている場合、以下のようなMakefileを作成すると、make install を実行するだけで生成したバイナリの所定位置への配置も行ってくれるので便利です。

Makefile
GOCMD=go
GOBUILD=$(GOCMD) build
MAIN=main.go
BINARY_NAME=helloworld
TERMUX_TASKS_DIRECTORY=~/.shortcuts/tasks

build:
	$(GOBUILD) -o $(BINARY_NAME) $(MAIN)

install: build
	cp $(BINARY_NAME) $(TERMUX_TASKS_DIRECTORY)/$(BINARY_NAME)

おわりに

本記事ではTermuxを利用し、任意の言語でGUIを取り扱ったアプリケーションの作成方法を取り扱いました。筆者はこの方法でAndroidのホーム画面にSlackへ勤怠情報をポストするショートカットを設置し、便利に活用しています。この記事が、読者の皆さんが同じように思い思いの言語でAndroidの機能を拡張し、日頃の定形作業の自動化などに活用する一助となれば幸いです。

Discussion