准备工作

首先,当然是一部手机啦。安卓版本不应该低于5.0Termux最新已不支持安卓7.0以下,但Termux 73版本前仍然支持安卓5.0。再低,可能兼容性异常。

对于其他配置无关紧要,GPS模块正常即可。同时你得祈祷你的手机厂商不作妖,搞些奇奇怪怪的安全限制

一张手机卡/物联卡。野外是不可能有WIFI的,怎么能想着无线网络呢?

一颗聪明好奇的小脑瓜

部署代码

先试试一键部署

你应该明白,这个项目覆盖大量自定义参数。精度要求较高,几乎是没有任何现成的数据源。
所谓的“一键部署”,也仅是安装部署源码。所有参数均需自定义。你仍然需要完整的阅读本篇文档,否则,不出意外的话,你的程序是跑不起来的。

  • 给予termux获取存储空间的权限
  • 部署(还原代码)
1
2
3
4
5
6
7
8
9
termux-setup-storage  # 如果没有得到权限,再次申请

cd /data/data/com.termux/files # 进入虚拟容器文件目录

tar -zxf 下载源码包绝对路径.tar.gz --recursive-unlink --preserve-permissions # 还原文件压缩包

# 如果未修改文件名称且文件在根目录下,则为:

tar -zxf /sdcard/termux-backup.tar.gz --recursive-unlink --preserve-permissions
  • 重启Termux,查看是否输出:

一些小细节

在开始之前,你应该完整的阅读国光对Termux的 完整概述及基础教程

核心Python环境

Start开始启动

Start.py是程序每天启动的入口函数。它将自动创建数据表,请求数据,开启所有服务并检测。

.zshrc文件中,启动窗口将自动运行本文件。

启动窗口将会锁定CPU,运行start.py文件,检验SSH是否开启

查看Start.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 文件函数导入
from inspect import config_sql, check_complate, config_updata, today_tables, creat_sql
from send_message import push_message
from location import get_and_updata
import json
import requests

def get_weather(): # 获取一次天气信息,api参照https://lbs.amap.com/api/webservice/guide/api/weatherinfo
url = "https://restapi.amap.com/v3/weather/weatherInfo?city=城市代码&key=JSapi Key"
weather = json.loads(requests.get(url).text)
state = weather["info"]
if state == "OK":
city = weather["lives"][0]["city"]
wea = weather["lives"][0]["weather"]
temperature = weather["lives"][0]["temperature"]
winddirection = weather["lives"][0]["winddirection"]
windpower = weather["lives"][0]["windpower"]
humidity = weather["lives"][0]["humidity"]
# reporttime=weather["lives"][0]["reporttime"]
# print(state, city, wea, temperature, winddirection, windpower, humidity)
# data = city + "&" + wea + "&" + temperature + "&" + winddirection + "&" + windpower + "&" + humidity
data = "今天{}{}天,气温:{}℃,{}风,风力{}级,能见度{}。".format(city, wea, temperature, winddirection, windpower, humidity)
return data


if config_sql("start") == "false": # 获取本地数据库中服务是否已开启
# 状态未开放时
print("服务正在启动...")
if today_tables() != "OK": # 数据库中无今日表时自动创建
creat_sql()
check_complate() # 完整性检验
get_and_updata(0.01) # 初始化,更新一次位置,并设置初始Risk=0.01(此处0.01为初始化,除外不应该带值)
config_updata("start", "true") # 更新状态
push_message.main("start", "服务已成功开启!\n\n你可以打开APP开始实时查看位置!&\n\n{}".format(get_weather()), "all")
# 推送信息

Inspect自检程序

此文件主要包含自检的函数,逻辑关系

在执行该py文件时,会检测Apache服务状态,以及Frpc穿透。

默认使用的是免费的frpc服务器,有时候服务会存在不稳定。

所以在自检穿透失败,重启仍然失败时。将使用cpolar穿透SSH登陆服务,并微信测试号提示。

远程SSH

Location定位服务

此文件为定位主文件,由Cron自动任务控制执行。在内部,将自动判断是否执行定位。

该文件有两种工作方式,备注模式与记录模式。

备注模式是在绘制地图边界时使用,将对该位置定位多次,求平均值。

1
# location.py -i 100 10 循环记录100次,每次间隔10秒。 记录某一个地点,可以定位10次求平均值

记录模式是正常工作状态下,由风控Risk决定是否定位执行,将定位记录,并计算风险。

GetRisk风险判断

风险计算核心

首先读取数据库,判断(射线法)本次定位点是否在风险预警区域内,如果在,将直接微信报警。

求阈值

若不在预警预期内,计算本次位置与上次位置相隔距离,以及对风险区域相隔距离。再综合判断电量,时间等因素。计算风险阈值,作为下一次定位时间的依据。

风险阈值

在距离500m以上时,风险将被视为极小。提醒距离由客户端设置。

SeedMessage微信提醒

基于微信测试号实现

限制: 不能更改名字,消息无法展示在聊天列表。被收录为订阅号中,但是能添加星标,使其通知栏提示消息。

微信测试号地址

SeedMessage文件已经封装,在其中配置APPID(测试号账户),APPSECRET(密钥),TEMPLATE_ID(模板ID)

测试号

在我封的脚本中,需要配置多个模板ID,以满足不同的通知提醒要求

模板ID

同时支持配置多个用户ID

用户ID

在调用时,写法如下

1
push_message.main("ssh", "远程访问服务开启&出于未知原因错误,服务异常,等待远程处理......", "all")

多模板ID

其中SSH为选择的通知模板,消息通知解析格式为”标题&内容“,all表示通知列表中所有用户。可以改为特定用户的ID

Server酱

聊天列表可见,免费版本调用上限5次/日

参考Server文档

Downline服务下线

通俗易懂,下线服务。


前端Web与PHP服务

前端地图由高德地图开发平台完成,在此之前,你应该对高德JS API 2.0示例,以及基础开发文档有了解

PHP服务由Apache2构建;不推荐在Termux上使用Nginx,因为我没run起来,奇奇怪怪的问题有点多。

Apache2及相关PHP安装参照国光的安装文档

基础地图绘制-JS

3D立体模型-JS

路径(折线)绘制-JS

风险区域绘制-PHP

风险区域控制-PHP

标记点(图标)-JS

即时位置展示-PHP

TermuxAPI构建-PHP

加密方法(SHA256)-PHP

Device设备信息-PHP


内网Frpc穿透服务

普通80穿透

异常SSH穿透


手机APP控制操作

浏览器基础

API调用模板


基础Termux服务

cron定时任务执行

由于安卓中特殊的环境,无法通过linux自带的crontab等工具直接实现定时任务

对于此,官方解决办法是Termux:tasker+Tasker实现,即通过第三方软件执行定时任务,拉起termux,执行脚本

但是我觉得此办法比较臃肿,最重要的是,Tasker并不免费。

高德地图在关于后台定位中,通过在cpu休眠前点亮屏幕。使得CPU不能休眠,后台存活,但这办法比较耗电,不优雅。

Termux有CPU唤醒锁的设置,首先在系统设置中,把Termux能开的都开上,例如后台不限制,电源不限制…..

1
2
3
termux-wake-lock 锁定CPU唤醒

termux-wake-unlock 解锁CPU唤醒

使用APSchedulerpython任务管理器,实现定时执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time
from apscheduler.schedulers.blocking import BlockingScheduler


def job(text):
t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
print('{} --- {}'.format(text, t))


scheduler = BlockingScheduler()
# 每隔 1分钟 运行一次 job 方法
scheduler.add_job(job, 'interval', minutes=1, args=['job1'])
scheduler.start()

1
2
3
4
5
6
7
8
9
10
11
要替换已删除的配置文件而不清除软件包,您可以执行以下操作:

sudo apt-get -o DPkg::Options::="--force-confmiss" --reinstall install apache2
要完全删除apache2配置文件,您应该

sudo apt-get purge apache2
然后,您可以按照通常的方式重新安装

sudo apt-get install apache2
需要清除才能删除所有配置文件-如果删除配置文件但仅删除软件包,则将记住此信息,默认情况下不会重新安装丢失的配置文件。

Termux-server服务管理


启动服务

致谢