Overview
This document contains my personal notes about how to setup my Android phone. It is mostly kept as a lightweight alternative to proper configuration management since I would expect that to be a PITA to setup on Android and overall probably not rewarding for a single device.
It also turns out that the apps to install and use are highly Android-version specific, hence this list explicitly mentions different sets of Apps that I installed on different Android versions.
My Android App List
Apps in parentheses were not installed on the most recent version.
Android 2.3.X (Samsung Galaxy XCOVER)
- GPS Test
- Hacker’s Keyboard
- (ES File Manager)
- (Android Reminder)
- (MuPDF viewer)
- (Geodesy)
- (Geolocation)
Android 7 (Blackview)
- NetGuard
- GPS Test
- QR & Barcode Scanner
- Hacker’s Keyboard
- Morse Code Agent
- Termux
- (ES File Manager)
- (MuPDF viewer)
- (Geodesy)
- (Geolocation)
- (Element)
Android 11 (Gigsaset GS5 Lite)
- No longer need a PDF viewer since it is included in the OS already
- No longer need a file manager since it is included in the OS already
- Currently missing a dedicated media player that supports a file/directory-centric approach. The default is insufficient in this regard?
App Name | Store |
---|---|
Maxima Keyboard | apkpure.com |
Maxima on Android | apkpure.com (v3.2.1) |
Morse Code Agent | apkpure.com (v2.2.0) |
GPS Test | apkpure.com (v1.6.3) |
GPS Test | f-droid.org |
Hacker’s Keyboard | f-droid.org |
NetGuard | f-droid.org |
OSMAnd~ | f-droid.org |
QR & Barcode Scanner x2 | f-dorid.org |
Termux | f-droid.org |
Termux:API | f-droid.org |
TI 84+ Emulator | f-droid.org + separate ROM |
Stashcat/Hermine | apkfun.com (Build 5409302) |
Daydream Digital Clock | ? forgot where it’s from ? |
Using the Phone as a Backup Server
By installing the correct apps and configuration, the phone can serve as a simple backup server. For my purposes, the backup server has two functions:
- Contain a separate copy of the backup from my main machine.
- Upload this backup to a remote location while idle. Specifically, Mega https://mega.nz is selected as the “remote location”
To achieve such a setup with Android, it is most useful ot rely on
Termux for receiving the data (through rsync
and
ssh
) and for uploading them to Mega (through
rclone
). This avoids less stable syncing that is being
criticised about the Android Mega App.
Important General Config
To ensure that this works at all, Termux has to run sufficiently continuously. While one can achieve this with a permanent “wakelock”, this drains batteries too quickly.
A more battery-saving choice is to enable the Screensaver aka. Daydream such that while charging, the phone stays on. This way, while charging, Termux stays active and data can be processed.
Termux Configuration
To perform the initial setup, the following commands are used in Termux:
pkg install vim openssh htop bmon nmap tmux wget iproute2 netcat-openbsd rsync rclone
termux-setup-storage
cp .../authorized_keys .ssh
chmod 600 ~/.ssh/authorized_keys
Connection through SSH is then possible for the follow-up configuration.
echo "set-window-option -g mode-keys vi" > ~/.tmux.conf
df -h
This identifies the SD card as /storage/2FD8-1F16
mkdir -p /storage/2FD8-1F16/masysma/termux
cp .../ma_termux_server.sh /storage/2FD8-1F16/masysma/termux/ma_termux_server.sh
RClone configuration for Mega
% rclone config
2022/10/17 15:58:44 NOTICE: Config file "/data/data/com.termux/files/home/.config/rclone/rclone.conf" not found - using defaults
No remotes found, make a new one?
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
Enter name for new remote.
name> mega
Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
[...]
30 / Mega
\ (mega)
[...]
Storage> 30
Option user.
User name.
Enter a value.
user> email
Option pass.
Password.
Choose an alternative below.
y) Yes, type in my own password
g) Generate random password
y/g> y
Enter the password:
password:
Confirm the password:
password:
Edit advanced config?
y) Yes
n) No (default)
y/n> n
Configuration complete.
Options:
- type: mega
- user: email
- pass: *** ENCRYPTED ***
Keep this "mega" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y
Current remotes:
Name Type
==== ====
mega mega
e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> q
Termux Autorun
One important thing to make this server run in battery-preserving
manner is to only start it while the phone is being charged. One can
achieve an automatic startup of the Mega synchronization by triggering
it from .bashrc
as follows:
if [ -n "$PS1" ]; then
/bin/sh -eu /storage/2FD8-1F16/masysma/termux/ma_termux_server.sh &
pidof sshd || sshd -p 8022
fi
Here, two commands are started if no suitable existent process could
be found: The first ma_termux_server.sh
serves two
purposes:
- Detect loss of connectivity and then shutdown Termux to save battery power.
- Detect changes in files to synchronize and then calling
rclone
accordingly.
The second command starts SSHD if it is not already running.
ma_termux_server.sh
The script content is described in the following. It most likely needs some tuning to your use case and hence is not given as a complete file here. If you must, concatenate all the code listings in this subsection to retrieve it.
#!/bin/sh -eu
# Script to Manage Termux Servers 1.1.1, (c) 2022 Ma_Sys.ma <info@masysma.net>
sync_source=/storage/2FD8-1F16/masysma/mega
sync_target=mega:/
sync_marker_new="$sync_source/../mega_status/new"
sync_marker_inp="$sync_source/../mega_status/inp"
sync_log="$sync_source/../mega.log"
At the begin of the script, source and target of the synchronization
are defined. Additionally, a sync_log
location is defined
to place the output of the rclone
command. It is important
to watch this log for anomalies.
has_network() {
ipmsg="$(ip addr show dev eth0 || echo NOTHING)"
if { echo "$ipmsg" | grep -qF ,UP,; } && \
{ echo "$ipmsg" | grep -qF "inet 192.168.1."; } && \
ping -w 1 -c 1 192.168.1.1 > /dev/null 2>&1; then
return 0
else
return 1
fi
}
This routine is intended to check network connectivity. As in my
example, the phone runs in network 192.168.1.0/24 with gateway
192.168.1.1
and network interface eth0
in
Termux, it is natural to check these conditions by ping
and
ip
# -- Avoid Duplicate Instances --
# 3 is normal: myself, my subshell and my grep!
if [ "$(LINES=999 ps auxw | grep -cF "ma_termux_server")" -gt 3 ]; then
echo ma_termux_server: already running. not starting another instance.
exit 0
fi
This detects other running instances of the same script and avoids running multiple instances at once because that would probably wreck havoc with synchronization if it were to happen.
# -- Check Network Connectivity --
echo ma_termux_server: detecting online connectivity
ipstatus=0
while [ "$ipstatus" -lt 10 ] && ! has_network; do
printf .
sleep 5
done
if [ "$ipstatus" = 10 ]; then
echo ma_termux_server: Internet connectivity did not appear in time. \
Exiting script.exit 0
fi
As a preliminary step to running the script, network connectivity has to be in place. Here, this is checked explicitly in order to ensure that running Termux without connectivity does not needlessly engage the script.
# -- Mainloop --
head -n 2 "$0" | tail -n 1 | cut -c 3-
ipstatus=0
while [ "$ipstatus" -le 2 ]; do
if has_network; then
ipstatus=0
if [ -f "$sync_marker_new" ] || [ -f "$sync_marker_inp" ]; then
if [ -f "$sync_marker_new" ]; then
mv -f "$sync_marker_new" "$sync_marker_inp"
fi
echo ma_termux_server: sync now
if ! rclone sync -v "$sync_source" "$sync_target" 2>&1 \
| tee "$sync_log"; then
echo ma_termux_server: sync failed. cancelled.
fi
rm "$sync_marker_inp"
fi
else
echo "ma_online_status: about to lose connection ctr=$ipstatus."
ipstatus=$((ipstatus + 1))
fi
sleep 30
done
The Mainloop checks the network connectivity every 30
sec. If it is present it continues to check the synchronization markers.
If the new
marker is present, it is renamed to
inp
(for in progress). Afterwards, the actual
rclone
call to sync source to target is invoked. Its output
is redundantly printed to stdout and the logfile. At the end of the
synchronization, the inp
marker is deleted.
The semantics behind the two markers is as follows:
new
signals that new data has arrived.inp
signals that synchronization is on-going.
The presence of any of the markers triggers a synchronization because:
- When new files arrive, the synchronization should commerce.
- When the
inp
marker is present but the script is not synchronizing at the moment (it knows this due to having only one single instance at a time) then this must have been caused by an interrupted preceding synchronization. It is then resumed by re-running therclone sync
command. - When new files arrive while the synchronization is already running,
at the end of that running synchronization the online state may be
inconsistent. But, as only
inp
is deleted,new
remains in place and after 30sec the next sync is triggered to correct any possible inconsistency from mid-sync data changes.
# -- Termination --
echo ma_online_status: offline condition detected. Enter \`killall sleep\` to \
avoid session exit in 1min.sleep 60
am startservice -a com.termux.service_stop com.termux/.app.TermuxService
sleep 5
kill -s TERM $(ps -o pid | grep -vF PID) || true
sleep 1
kill -s KILL $(ps -o pid | grep -vF PID) || true
The final lines of the script are only entered when the phone is detected to be offline. In that case, multiple ways are tried to terminate the running Termux session since any single command was not found to be exactly effective in stopping it…
The Source System Side
To synchronize data to Mega by using the phone as a backup server, a
client has to push data to the phone via SSH. A reliable way to achieve
this is by using rsync
. These commands and options work for
me:
mdb_web_ip=192.168.1.102
export RSYNC_RSH="ssh -o Port=8022 -i .../id_ed25519"
mdb_web_target="u0_a162@$mdb_web_ip:/storage/2FD8-1F16/masysma/mega"
sshtarget="${mdb_web_target%:*}"
rsync -virhLWO --size-only --progress --delete \
"$mdb_web_target"
sourcefiles... $RSYNC_RSH "$sshtarget" touch "$sshdir/../mega_status/new" || true
Adjust this to your situation as follows
- Set
mdvb_web_ip
to the address of the phone - Set
id_ed25519
path to the location of your SSH identity file - Set
mdb_web_target
to the connection string to use to target the phone. Notable things to modify areu0_a162
(the username on the Android side) and/storage/2Fd8-1F16/masysma/mega
(the location on the SD card). - Set
sourcefiles...
to the data to sync to the phone
Termux:API
Sometimes, SMS-TAN are required. In order to access them via SSH,
Termux:API provides a command to list SMS:
termux-sms-list
.
Be aware that after installing Termux:API, it must be “allowed” in
NetGuard, oterhwise the network connectivity is no longer possible with
the following observations: pings can be started, but no replies are
received. Also wget/curl times out without connecting. IP addresses
could still be resolved (as seen in ping
output)…
See also: https://github.com/termux/termux-app/issues/2778
Things that did not work when tested
This chapter collects all the various notes from trying out things that did not work out in the end. They may serve as a starting point if you want to try any of these things.
You are encouraged to report progress on any of these topics to
<info@masysma.net
> if you happen to achieve success
regarding any of the topics described in any of the following
subsections.
Megacmd
It looks easy enough:
pkg install megacmd
mega-login email password
mega-sync /storage/2FD8-1F16/masysma/mega /
However, this turned out not to work reliably. The following erroneous behaviour was observed:
- Locally deleted files would appear to be downloaded again from remote even if this was intended to be synchronized to remote.
- Locally changed files would be replaced by (older) on-line counterparts.
Hence, another approach was considered.
Commands for viewing the Mega status when using
megacmd
:
mega-sync
mega-transfers --show-syncs
Mega GUI Approach
Requires a lot of dependencies (tigervnc
and
icewm
were intended to be used later for displaying the
GUI). Note that this list was extended during compilation and is most
likely still incomplete. Also note that Termux does not have separate
-dev
packages!:
pkg install x11-repo tigervnc icewm git build-essential wget unzip pkg-config binutils qt5-qtsvg qt5-qtx11extras qt5-qttools
Download and extract the Mega sources (maybe
git clone --recursive https://github.com/meganz/MEGAsync.git
).
Then perform a lot of patches. You can take some inspiration from the following listings although I did not achieve a successful compilation even with all of them applied…
Patch
src/MEGASync/MEGASync.pro
Here we need to disable use drive notifications because udev is not available in Termux.
diff --git a/src/MEGASync/MEGASync.pro b/src/MEGASync/MEGASync.pro
index 75c8857e7..44690e976 100644--- a/src/MEGASync/MEGASync.pro
+++ b/src/MEGASync/MEGASync.pro
@@ -111,7 +111,7 @@ else {
}
# Drive notifications (for SDK)-CONFIG += USE_DRIVE_NOTIFICATIONS
+# CONFIG += USE_DRIVE_NOTIFICATIONS
include(gui/gui.pri) include(mega/bindings/qt/sdk.pri)
Patch src/configure
Here we also remove -N
(drive notification). Enable
-y
for dynamic linking.
diff --git a/src/configure b/src/configure
index 1d531a845..7e269ae63 100755--- a/src/configure
+++ b/src/configure
@@ -73,24 +73,26 @@ shift $((OPTIND-1))
# if archives are not yet downloaded
if [ ! -d "$archives" ]; then
mkdir $archives- ./MEGASync/mega/contrib/build_sdk.sh $FLAG_CRYPTOPP -n -N $FLAG_CARES $FLAG_LIBMEDIA $FLAG_CURL $FLAG_DISABLE_ZLIB $FLAG_RAW -w -s -v -u -o $archives
+ # MASYSMA CHANGES: Remove -N, Add -y
+ ./MEGASync/mega/contrib/build_sdk.sh -y $FLAG_CRYPTOPP -n $FLAG_CARES $FLAG_LIBMEDIA $FLAG_CURL $FLAG_DISABLE_ZLIB $FLAG_RAW -w -s -v -u -o $archives
rm_archives=1
fi
cd MEGASync/mega+# MASYSMA CHANGES: Remove -N, add -y
./contrib/build_sdk.sh \
$FLAG_CRYPTOPP \
-o $archives \
$FLAG_CARES $FLAG_CURL $FLAG_LIBMEDIA $FLAG_DISABLE_ZLIB $FLAG_RAW \
-l \
-n \- -N \
-c \
-t \
-s \
-v \
-I \
-u \+ -y \
-p $root_dir/MEGASync/mega/bindings/qt/3rdparty
Patch
src/MEGASync/mega/sdk_build/build/cryptopp820/config.h
This patch fixes some weird errors regarding intrinsics. It may not be needed since it may be possible to build without the vendored Crypto++ library by using a system-provided one instead. This patch was taken from https://github.com/cryfs/cryfs/issues/345. Similar patches may exist in other issues.
diff --git a/../vendor/cryptopp/vendor_cryptopp/config.h b/../../config.h
index 283c409..54ee6c2 100644--- a/../vendor/cryptopp/vendor_cryptopp/config.h
+++ b/../../config.h
@@ -733,7 +733,7 @@ NAMESPACE_END
// Limit the <arm_acle.h> include.
#if !defined(CRYPTOPP_ARM_ACLE_AVAILABLE)
# if defined(__aarch32__) || defined(__aarch64__) || (__ARM_ARCH >= 8) || defined(__ARM_ACLE)-# if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__APPLE__)
+# if !defined(__APPLE__)
# define CRYPTOPP_ARM_ACLE_AVAILABLE 1
# endif # endif
Patch
src/MEGASync/mega/sdk_build/build/cryptopp820/GNUmakefile
In case of building with vendored Crypto++, it may be necessary to
add the cpu-features.c
and cpu-features.h
files to the Crypto++ build directory. To make the build find them,
change Crypto++ GNUmakefile
accordingly.
I do not remember having to change the CC
variable
definition although it appears in the patch here…
--- GNUmakefile.orig 2019-04-29 01:36:50.000000000 +0200
+++ src/GNUmakefile.chg 2022-10-09 21:15:28.731611888 +0200
@@ -157,12 +157,6 @@
ZOPT = -O0
endif
-# On ARM we may compile aes_armv4.S though the CC compiler
-ifeq ($(GCC_COMPILER),1)
- CC=gcc
-else ifeq ($(CLANG_COMPILER),1)
- CC=clang
-endif
# Default prefix for make install
ifeq ($(PREFIX),)@@ -1060,7 +1054,7 @@
# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems.
OBJS := $(SRCS:.cpp=.o)-OBJS := $(OBJS:.S=.o)
+OBJS := $(OBJS:.S=.o) cpu-features.o
# List test.cpp first to tame C++ static initialization problems.
TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp dlltest.cpp fipsalgt.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp validat5.cpp validat6.cpp validat7.cpp validat8.cpp validat9.cpp validat10.cpp regtest1.cpp regtest2.cpp regtest3.cpp regtest4.cpp@@ -1570,6 +1564,9 @@
endif
endif
+cpu-features.o: cpu-features.c
+ $(CC) $(strip $(CXXFLAGS) -c) $<
+
validat1.o : validat1.cpp $(CXX) $(strip $(CXXFLAGS) $(ALTIVEC_FLAG) -c) $<
Patch
src/MEGASync/mega/configure.ac
Removes another place with an udev dependency.
diff --git a/configure.ac b/configure.ac
index d7d3139cc..c72fe6503 100644--- a/configure.ac
+++ b/configure.ac
@@ -318,7 +318,8 @@ AS_IF([test "x$enable_drive_notifications" = "xyes"], [
CXXFLAGS="$CXXFLAGS -DUSE_DRIVE_NOTIFICATIONS"
# Add lib to linker command
if test "x$LINUX" = "xyes"; then- LDFLAGS="$LDFLAGS -ludev"
+ # was -ludev
+ LDFLAGS="$LDFLAGS"
elif test "x$WIN32" = "xyes"; then
LDFLAGS="$LDFLAGS -lwbemuuid" elif test "x$DARWIN" = "xyes"; then
Patch
src/MEGASync/mega/contrib/build_sdk.sh
The original included a base64 encoded version of
cpu-features.c
and cpu-features.h
to put into
cryptopp directory. Its stats were as follows:
$ sha256sum cpu-features.?
cce1508673c364ee07ef1128e66e52bad99739e56b62dbc60c6e265510d565b1 cpu-features.c
c6c2107c5f2e3133c316e39e87148cb62dfc0bbcd887e338ff277e6281085b86 cpu-features.h
Here is the remainder of the patch (not directly applicable, do it by hand!):
if [ $android_build -eq 1 ]; then
cp ${ANDROID_NDK_ROOT}/sources/android/cpufeatures/cpu-features.h $cryptopp_dir/
cp ${ANDROID_NDK_ROOT}/sources/android/cpufeatures/cpu-features.c $cryptopp_dir/
package_build $name $cryptopp_dir "static -f GNUmakefile-cross"
package_install $name $cryptopp_dir $install_dir $cryptopp_md5 "-f GNUmakefile-cross"
else- package_build $name $cryptopp_dir static
+ package_build $name $cryptopp_dir static dynamic
package_install $name $cryptopp_dir $install_dir $cryptopp_md5
fi
}@@ -1058,7 +1060,7 @@ build_sdk() {
# enable libuv
if [ $enable_libuv -eq 1 ]; then- libuv_flags="--with-libuv=$install_dir"
+ libuv_flags="--with-libuv=/data/data/com.termux/files/usr"
else
libuv_flags="--without-libuv" fi
Patch `src/MEGASync/mega/src/gfx/freeimage.cpp
This patch is based on https://github.com/meganz/MEGAcmd/issues/632 and required to fix a compile issue:
diff --git a/src/gfx/freeimage.cpp b/src/gfx/freeimage.cpp
index eef623744..c94850b59 100644--- a/src/gfx/freeimage.cpp
+++ b/src/gfx/freeimage.cpp
@@ -313,7 +313,7 @@ bool GfxProviderFreeImage::readbitmapFfmpeg(FileSystemAccess* fa, const LocalPat
// Find decoder for video stream
AVCodecID codecId = codecParm->codec_id;- AVCodec* decoder = avcodec_find_decoder(codecId);
+ auto decoder = avcodec_find_decoder(codecId);
if (!decoder)
{
LOG_warn << "Codec not found: " << codecId;@@ -330,7 +330,7 @@ bool GfxProviderFreeImage::readbitmapFfmpeg(FileSystemAccess* fa, const LocalPat
// Force seeking to key frames
formatContext->seek2any = false;- videoStream->skip_to_keyframe = true;
+ //videoStream->skip_to_keyframe = true;
if (decoder->capabilities & CAP_TRUNCATED)
{ codecContext->flags |= CAP_TRUNCATED;
Try Build
./configure -g -i
qmake MEGASync/MEGASync.pro
lrelease MEGASync/MEGASync.pro
make
During the make
call, build errors were observed. No
solution was found beyond digging into the code to find out what’s the
matter here…
Post-Build
These are intended (untested) commands for VNC setup:
echo \$vncStartup = \"exec /data/data/com.termux/files/usr/bin/icewm\" > $HOME/.vncrc
mkdir ../usr/etc/X11/icewm
printf "%s\n\n%s\n" "#!/bin/sh -e" "/usr/bin/megasync &" > /etc/X11/icewm/startup
chmod +x /etc/X11/icewm/startup
Bashrc planned addition (untested)
[ -n "$(pidof vncserver)" ] || vncserver -geometry 1024x768 :0 &
Advanced Autorun
So far, no means was found to automatically trigger Termux while charging. While this would seem to be possible using an app like Easer, it did not reliably trigger the opening of the Termux client even when configured in various ways.
This section retains some of the notes about this configuration for later re-use.
- Start the Termux App by a command:
sleep 1; am start --user 0 -n com.termux/com.termux.app.TermuxActivity
- Use a Dropbear SSHD and stop it by a command:
am broadcast --user 0 -a org.galexander.sshd.STOP org.galexander.sshd
- Try to stop Termux (not the recommended way)
am kill com.termux
- Run commands in Termux from other app through an Android command:
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/mega-cmd --ez com.termux.RUN_COMMAND_BACKGROUND true
See Also
- More lightweight alternative to OSMAnd~ https://organicmaps.app/