使用Android设备使用Termux,Termux-x11安装xfce4桌面环境,并安装Android Studio,Code Server(VSCode)等软件,搭配Termux-API,Termux-Widget配置快捷启动图标
转载请注明出处,本文仅用于学习交流,不对之处,恳请指正 ,部分图片摘取网络,如有侵权请联系
开源工具
termux-toy 作者很谦虚,说只是个开源玩具(啊?好像作者是我自己)
# 推荐清空数据后使用
bash <(curl -fsSL https://raw.githubusercontent.com/AlainLam/termux-toy/main/start.sh)
Termux系列软件安装包
安装包
Termux:https://f-droid.org/repo/com.termux_118.apk
Termux-x11:https://github.com/termux/termux-x11/suites/16954107083/artifacts/968612187
Termux-API:https://f-droid.org/repo/com.termux.api_51.apk
Termux-Widget:https://f-droid.org/repo/com.termux.widget_13.apk
如果下载不了,可以暂时用我下面的链接
4个APK压缩包:https://public-static.alainlam.cn/7g5mAuLfebuSyWOv/termux.zip
Termux初始化安装
# 安装库
pkg install x11-repo root-repo -y
# 更新
pkg upgrade -y
# 安装openssh(可选)
pkg install openssh
# 设置密码
passwd
# 获取存储权限(可选)
termux-setup-storage
# 安装桌面相关软件
pkg install termux-x11-nightly pulseaudio virglrenderer-android -y
Termux中安装proot-distro,并安装Debian系统
pkg install proot-distro -y
proot-distro install debian
Debian安装浏览器等常用软件,并新增普通用户
-
登录进debian系统
proot-distro login debian --shared-tmp
-
安装软件以及配置
# 更新 apt-get update && apt-get dist-upgrade -y #安装软件 apt-get install sudo nano wget firefox-esr p7zip-full -y # 新增用户,并按提示输入信息 adduser alain
-
给普通账户添加sudo权限
nano /etc/sudoers
在
root ALL=(ALL:ALL) ALL
之后添加alain ALL=(ALL:ALL) ALL
, 就像下面这样# User privilege specification root ALL=(ALL:ALL) ALL alain ALL=(ALL:ALL) ALL
-
加入到video跟audio的用户组
usermod -aG audio,video alain
Debian安装xfce4桌面环境,并解决中文乱码
-
切换到普通用户
su - alain
-
安装桌面
sudo apt install xfce4 xfce4-goodies
-
设置时区
sudo ln -sf /usr/share/zoneinfo/Hongkong /etc/localtime
-
解决中文乱码
##### 解决中文乱码 # 参考: https://wiki.archlinuxcn.org/wiki/Locale # 命令行环境还是使用英语比较友好,所以我的设置均为en_US.UTF-8,你可以自行替换为zh_CN.UTF-8 # # 安装语言环境以及文泉驿字体 # sudo apt install locales fonts-wqy-zenhei -y # 安装区域环境以及思源字体 sudo apt install locales fonts-noto-cjk -y # 生成区域设置 sudo dpkg-reconfigure locales # 选择97. en_US.UTF-8 UTF-8 # 回车后选择3. en_US.UTF-8 # 相当于nano /etc/locale.gen取消注释en_US.UTF-8 UTF-8后,locale-gen # 设置系统区域 # 因为无法使用localectl set-locale LANG=en_US.UTF-8 # 所以直接设置到配置文件当中 # echo "LANG=en_US.UTF-8" > /etc/locale.conf
你可以单独设置用户的语言环境(可选)
nano ~/.profile
写入以下代码(locale输出内容)
LANG=en_US.UTF-8
-
安装输入法
sudo apt install fcitx5* -y
编辑~/.profile,追加以下代码
# Use the fcitx5 im GTK_IM_MODULE=fcitx QT_IM_MODULE=fcitx XMODIFIERS=@im=fcitx SDL_IM_MODULE=fcitx GLFW_IM_MODULE=ibus if [ ! -d ~/log ]; then mkdir -p ~/log fi fcitx5 > ~/log/im.log 2>&1 &
Termux安装VSCode(Code-Server)
如果不需要VSCode(Code-Server),你可以直接跳过并进入下一节
注意,此节是在Debian环境中,并切换到普通用户
安装VSCode(Code-Server)
# 创建下载目录
mkdir ~/Downloads
# 进入下载目录
cd ~/Downloads
# 下载 comandlline工具
wget https://github.com/coder/code-server/releases/download/v4.17.1/code-server-4.17.1-linux-arm64.tar.gz
# 解压
mkdir -p ./tmpcoder
tar -xvf code-server-*.tar.gz -C ./tmpcoder/
# 创建目录
mkdir -p ~/Applications
# 移动VSCode到对应目录并删除临时目录
mv ./coder/code-server-* ~/Applications/coder
rm -rf ./tmpcoder
# 如果~/.config/code-server不存在,则先创建它
mkdir ~/.config/code-server
# 创建配置文件,注意修改其中的值
echo "bind-addr: 127.0.0.1:${code_server_port}
auth: password
password: ${code_server_pwd}
cert: false" > ~/.config/code-server/config.yaml
# 运行
~/Applications/coder/bin/code-server
Termux安装Android Studio
如果不需要Android Sutdio,你可以直接跳过并进入下一节
注意,此节是在Debian环境中,并切换到普通用户
安装JDK 17(Proot-distro中的Android Studio必须JDK17以上)
sudo apt install openjdk-17-jre -y
安装Android SDK(Commandline-tools)
# 创建下载目录
mkdir ~/Downloads
# 进入下载目录
cd ~/Downloads
# 下载 comandlline工具
wget https://dl.google.com/android/repository/commandlinetools-linux-10406996_latest.zip
# 解压
unzip commandlinetools-linux-*.zip
# 创建目录
mkdir -p ~/Android/Sdk/cmdline-tools/latest
# 移动工具到对应目录
mv ~/Downloads/cmdline-tools/* ~/Android/Sdk/cmdline-tools/latest/
# 进入该目录
cd ~/Android/Sdk/cmdline-tools/latest/bin/
# 默认同意全部许可申请
yes | ./sdkmanager --licenses
配置Android环境变量
-
在
~/.profile
中追加以下代码# Android Environments export ANDROID_HOME=$HOME/Android/Sdk export ANDROID_SDK_HOME=$ANDROID_HOME export ANDROID_USER_HOME=$HOME/.android export ANDROID_EMULATOR_HOME=$ANDROID_USER_HOME export ANDROID_AVD_HOME=$ANDROID_EMULATOR_HOME/avd/ export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
-
使它生效
source ~/.profile
安装Android Studio
# 进入下载目录
cd ~/Downloads
# 下载Android Studio
wget https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2022.3.1.20/android-studio-2022.3.1.20-linux.tar.gz
# 解压
tar -xvf android-studio-*-linux.tar.gz
# 移动工具到Android studio目录
mv ./android-studio ~/Android
Termux修复aapt2等编译工具问题
https://github.com/termux/termux-packages/issues/8350
https://github.com/lzhiyong/android-sdk-tools
https://github.com/lzhiyong/android-sdk-tools/releases
# 进入下载目录
cd ~/Downloads
# v34.0.3
wget https://github.com/lzhiyong/android-sdk-tools/releases/download/34.0.3/android-sdk-tools-static-aarch64.zip
# v33.0.3
# wget https://github.com/lzhiyong/android-sdk-tools/releases/download/33.0.3/android-sdk-tools-static-aarch64.zip
# 解压
unzip android-sdk-tools-static-aarch64.zip
# 创建目录
mkdir ~/Android/android-sdk-tools
# 移动到指定目录
mv platform-tools ~/Android/android-sdk-tools/
mv build-tools ~/Android/android-sdk-tools/
自动软链接aapt2等编译工具
此节是为了以后下载其他版本的SDK时,自动替换对应的编译工具,具有一定的性能损耗
而且很多设备并不足以支持inotify的运行
如果不需要,并希望手动管理,则可以跳过此节
-
脚本需要使用到inotifywait命令,所以需要安装inotify-tools
sudo apt install inotify-tools -y
-
创建存放脚本的目录,你可以放在你喜欢的文件夹当中,我喜欢把自定义脚本放在同一个文件夹中
mkdir ~/scripts
-
编写脚本
nano ~/scripts/fix_sdk_tools.sh
写入以下代码
#!/bin/bash # Author: https://www.alainlam.cn #### 定义变量 ANDROID_SDK_PATH=$ANDROID_SDK_HOME MONITOR_DIRS=("platform-tools" "build-tools") TARGET_DIRS=("/home/alain/Android/android-sdk-tools") #### 下载编译工具 # if [ ! -d "$TARGET_DIRS" ]; then # mkdir -p ~/Download && cd ~/Downloads # # v34.0.3 # wget https://github.com/lzhiyong/android-sdk-tools/releases/download/34.0.3/android-sdk-tools-static-aarch64.zip # # 解压 # unzip android-sdk-tools-static-aarch64.zip # # 创建目录 # mkdir $TARGET_DIRS # # 移动到指定目录 # mv platform-tools $TARGET_DIRS # mv build-tools $TARGET_DIRS # fi #### #### 监听SDK目录文件变化 checking_files() { local checking_file=$1 file_name=$(basename "$checking_file") # 如果是目录的话,需要重新遍历整个目录 # 因为可能是整个目录移入的情况 if [ -d "$checking_file" ]; then files=($(ls "$checking_file")) for file in "${files[@]}"; do checking_files "$checking_file/$file" done else # 跳过已经是软链接的文件 if [ ! -L "$checking_file" ]; then target_file="" for dir in "${TARGET_DIRS[@]}"; do # 检查编译工具目录中是否有对应的文件 target_file=$(find "$dir" -name "$file_name" -type f -print -quit) # 如果找到文件就中止循环 if [ -n "$target_file" ]; then break fi done # 找到对应的编译工具文件 if [ -n "$target_file" ]; then # 删除原来的编译工具文件 rm -rf "$checking_file" # 创建软链接 ln -s "$target_file" "$checking_file" echo "Created symlink $checking_file -> $target_file" fi fi fi } # 设置文件监听 inotifywait --exclude '^.*\.temp/.*$' -mrq -e create,move "$ANDROID_SDK_PATH" | while read -r directory event file; do for monitor_dir in "${MONITOR_DIRS[@]}"; do if [[ "$directory$file" =~ "$ANDROID_SDK_PATH$monitor_dir" ]]; then checking_files "$directory$file" fi done done ####
-
修改权限
chmod 700 ~/scripts/fix_sdk_tools.sh
-
在
~/.profile
调用它nano ~/.profile
追加以下代码
bash ~/scripts/fix_sdk_tools.sh > ~/log/sdktools.log 2>&1 &
修复NDK问题
# 进入下载目录
cd ~/Downloads
# 下载lzhiyong编译号的NDK,有需要的话你也可以自己编译
# https://github.com/Lzhiyong/termux-ndk/tree/master/docs
wget https://github.com/lzhiyong/termux-ndk/releases/download/ndk-r23/android-ndk-r23c-aarch64.zip
# 解压
unzip android-ndk-r23c-aarch64.zip
# 移动至目标目录
mv ./android-ndk-r23c $ANDROID_SDK_HOME/ndk/
后续你需要在你项目的gradle.properties文件中配置ndk的目录,效果类似这样的
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Sat Oct 07 18:42:35 UTC 2023
sdk.dir=/home/alain/Android/Sdk
ndk.dir=/home/alain/Android/Sdk/ndk/android-ndk-r23c
修复模拟器导致无法运行程序的问题
https://developer.android.com/studio/emulator_archive
这并不能在termux中运行Android emulator
后续我会进行一些尝试
理论上来说,如果装上了qemu的话,应该或许可能是可行的
# 进入下载目录
cd ~/Downloads
# 下载emulator-linux_x64的版本
wget https://redirector.gvt1.com/edgedl/android/repository/emulator-linux_x64-10696886.zip
# 解压缩
unzip emulator-linux_x64-*.zip
# 拷贝到对应的文件夹
mv ./emulator $ANDROID_SDK_HOME/
# 下载package.xml
wget https://public-static.alainlam.cn/7g5mAuLfebuSyWOv/package.xml -O $ANDROID_SDK_HOME/emulator/package.xml
# 需要注意的是如果你下载的emulator跟我的版本不同的话
# 你需要自行修改package.xml中的内容中的32为你下载的emulator版本
# <revision><major>32</major><minor>1</minor><micro>15</micro></revision>
到这里,我们已经准备好Android的编译环境了
Android12以上修复Termux进程数问题
https://cloud-atlas.readthedocs.io/zh_CN/latest/android/apps/android_12_background_limit_termux.html
在Termux中自动修改max_phantom_processes
打开Android设备的WiFi调试功能(Wireless debugging),并进行配对。
~/Android/android-sdk-tools/platform-tools/adb pair 127.0.0.1:${your_pair_port}
# 输入配对码
# 配对成功后
~/Android/android-sdk-tools/platform-tools/adb connect 127.0.0.1${your_connect_port}
# 连接成功后,查看当前系统配置
~/Android/android-sdk-tools/platform-tools/adb shell "/system/bin/dumpsys activity settings"
# 其中有一个max_phantom_processes=32,我们需要修改它
~/Android/android-sdk-tools/platform-tools/adb shell "device_config put activity_manager max_phantom_processes 32768"
~/Android/android-sdk-tools/platform-tools/adb shell "/system/bin/device_config set_sync_disabled_for_tests persistent"
# 查看修改是否成功
~/Android/android-sdk-tools/platform-tools/adb shell "/system/bin/dumpsys activity settings"
Termux自动连接ADB
因为是想用来写写Android的代码(强行生产力,不止爱奇艺),所以就有了这个需求,主要是为了自己方便
-
需要先安装nmap
sudo apt install nmap -y
-
自动连接adb
# 我喜欢把自定义脚本放在同一个文件夹中 # mkdir ~/scripts # 编写 nano ~/scripts/adb_magic_connection.sh
写入以下代码
#!/bin/bash # Author: https://www.alainlam.cn # 本脚本需要已经配对过的情况下 ### 配置变量配置 # # adb路径 adb() { ~/Android/android-sdk-tools/platform-tools/adb "$@" } # 用于存放以往的端口 adb_port_file=~/log/adb_port.txt # 用于端口号不存在或者失效时,扫描的端口范围 # 我的平板端口号开的范围比较大,请适当调整 port_range="30000-50000" # ###### connect_to_ports() { local ports=("$@") for port in "${ports[@]}"; do # 尝试连接 echo "adb connecting localhost:$port" adb_output=$(adb connect localhost:"$port" 2>&1) # 检查是否连接成功 if [[ $adb_output =~ connected ]]; then echo "adb connected localhost:$port" # 修改max_phantom_processes echo "update max_phantom_processes to 32768" adb -s localhost:$port shell device_config put activity_manager max_phantom_processes 32768 # 端口号写入文件中 echo "$port" >$adb_port_file # 如果start-server非空的话,则一开始没有打开过adb,那么结束adb if [ $kill_adb -eq 1 ]; then adb kill-server echo "adb killed server" fi # 结束代码 exit 0 else echo "Failed to connect to port $port" # 避免在adb devices列出过多的设备 adb disconnect localhost:"$port" fi done echo "Failed to connect to any port" # 如果start-server非空的话,则一开始没有打开过adb,那么结束adb if [ $kill_adb -eq 1 ]; then adb kill-server echo "adb killed server" fi } # 开启adb kill_adb=0 if ! pgrep -x "adb" >/dev/null; then adb start-server kill_adb=1 fi # 尝试连接以前的端口 if [ -f "$adb_port_file" ]; then adb_port=$(cat "$adb_port_file") else echo "Port file $adb_port_file does not exist" directory=$(dirname "$adb_port_file") # 如果目录不存在,先创建目录 if [ ! -d "$directory" ]; then mkdir -p "$directory" fi fi # 检查端口是否开启 if [ -n "$adb_port" ]; then echo "pending the localhost:$adb_port" nmap_output=$(nmap -p "$adb_port" localhost) if [[ $nmap_output == *"$adb_port/tcp"*open* ]]; then echo "Port $adb_port is open" # 尝试连接 connect_to_ports "$adb_port" else echo "Port $adb_port is closed" fi fi # 提示用户选择一种方式 selected_port_method="" while [[ $selected_port_method != "1" && $selected_port_method != "2" && $selected_port_method != "3" ]]; do read -p " Please choose the method you want: 1. Enter the special port(Manual) 2. Use nmap to scan the ports(Slowly) 3. Skip for now Your choice(1/2/3): " selected_port_method done if [[ $selected_port_method == "1" ]]; then read -p "Please enter a special port(1-65535)" enter_port echo "pending the localhost:$enter_port" connect_to_ports "$enter_port" fi if [[ $selected_port_method == "2" ]]; then # 如果端口已经无效或不存在,则扫描端口并保存到adb_test_ports中 echo "pending the localhost:[$port_range]" nmap_output=$(nmap -p "$port_range" localhost) while IFS= read -r line; do if [[ $line =~ ^[0-9]+/tcp.*open.* ]]; then echo "$line" port=$(echo "$line" | awk -F/ '{print $1}') adb_test_ports+=("$port") fi done <<<"$nmap_output" # 尝试连接端口 connect_to_ports "${adb_test_ports[@]}" fi
-
修改权限
chmod 700 ~/scripts/adb_magic_connection.sh
-
后面在启动脚本中会调用这个脚本
-
至此,所有配置均已完成,那么我们可以开启桌面模式了
# 先退出debian # ctrl+d 到termux的shell
启动桌面
# 开启pulseaudio服务
pulseaudio --start --load="module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1" --exit-idle-time=-1
# pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
# 设置显示变量为0
export DISPLAY=:0
# 启动termux-x11并设置到:0显示器
termux-x11 :1 &
# 一些设备只输出带有光标的黑屏需要使用传统绘图选项,比如Galaxy S8+
# https://github.com/termux/termux-x11/blob/master/README.md#running-graphical-applications
# termux-x11 :0 -legacy-drawing &
# 启动VirGL服务
virgl_test_server_android &
# 进入debian系统
proot-distro login debian --user alain --shared-tmp
# 或者直接执行以下命令
# proot-distro login debian --user alain --shared-tmp -- bash -c "export DISPLAY=:1;PULSE_SERVER=tcp:127.0.0.1; dbus-launch --exit-with-session startxfce4"
如果使用proot-distro login debian --user alain --shared-tmp
进入Debian时,我们仍然需要执行以下命令来启动桌面环境
export DISPLAY=:0
PULSE_SERVER=tcp:127.0.0.1
dbus-launch --exit-with-session startxfce4
Termux一键启动桌面
mkdir .shortcuts
nano .shortcuts/DebianX.sh
写入以下代码, 然后长按桌面添加新控件
#!/bin/bash
# Author: https://www.alainlam.cn
# 关闭所有xfce的进程
processes=$(pgrep -f xfce4)
for pid in $processes; do
echo "killing $pid"
kill $pid
done
# 关闭所有x11的进程
processes=$(pgrep -f com.termux.x11)
for pid in $processes; do
echo "killing x11 server: $pid"
kill $pid
done
# 关闭所有pulseaudio的进程
processes=$(pgrep -f pulseaudio)
for pid in $processes; do
echo "killing pulseaudio: $pid"
kill $pid
done
# 关闭所有 virgl renderer的进程
processes=$(pgrep -f virglrenderer-android)
for pid in $processes; do
echo "killing virglrenderer-android: $pid"
kill $pid
done
echo "Starting X11 server"
XDG_RUNTIME_DIR=$TMPDIR
termux-x11 :0 -ac &
sleep 3
echo "Starting pulseaudio server"
pulseaudio --start --load="module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1" --exit-idle-time=-1
echo "Starting Virgl Renderer"
virgl_test_server_android &
# 自动连接adb
adb_magic_connection='
script_path=~/scripts/adb_magic_connection.sh
if [ -f "$script_path" ]; then
echo "ADB: Attempting to automatically connect to localhost(device)"
bash "$script_path"
else
echo "Skipped ADB connection"
fi
'
proot-distro login debian --shared-tmp --user alain -- bash -c "$adb_magic_connection"
# 跳转到Termux X11
am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity
# 启动桌面环境
proot-distro login debian --user '"$normal_user_name"' --shared-tmp -- bash -c "export DISPLAY=:0 PULSE_SERVER=tcp:127.0.0.1; dbus-launch --exit-with-session startxfce4"
文章评论