- Add GPLv3 LICENSE file - Add CONTRIBUTING.md with guidelines - Update README: remove Play Store section, add license and contributing refs - Fix feature graphic (remove grid lines, replace Waybar chip with No root)
4.8 KiB
4.8 KiB
Tether API
Android app that exposes your phone's connection status via HTTP API, accessible from tethered devices.
Features
- Auto-start on tether: Server automatically starts/stops when tethering is enabled/disabled
- Real-time status: Connection type (5G/LTE/3G/WIFI), signal strength, carrier, battery level
- Simple REST API: JSON responses, easy to integrate with any client
- No root required: Works with standard Android permissions
Installation
Build with Android Studio or use the release APK.
Required permissions:
READ_PHONE_STATE- Network connection type and carrierACCESS_FINE_LOCATION- Required by Android 10+ for signal strengthPOST_NOTIFICATIONS- Service status notification
API Reference
Default port: 8765
Common gateway IPs when tethering:
- USB tethering:
192.168.42.1 - WiFi hotspot:
192.168.43.1
GET /status
Returns full phone status.
Response:
{
"connection": {
"type": "LTE",
"signal_dbm": -89,
"signal_bars": 3,
"carrier": "T-Mobile",
"operator": "310260",
"roaming": false
},
"battery": {
"level": 73,
"charging": false
},
"network": {
"wifi_ssid": null,
"ip_addresses": ["192.168.42.129"]
},
"timestamp": 1702915200
}
Fields:
| Field | Description |
|---|---|
connection.type |
5G, LTE, HSPA, 3G, 2G, WIFI, CELLULAR, NONE |
connection.signal_dbm |
Signal strength in dBm (-999 if unavailable) |
connection.signal_bars |
0-4 signal bars |
connection.carrier |
Network operator name |
connection.operator |
MCC+MNC code |
connection.roaming |
Whether roaming is active |
battery.level |
Battery percentage (0-100) |
battery.charging |
Whether device is charging |
network.wifi_ssid |
WiFi SSID if connected via WiFi |
network.ip_addresses |
List of device IP addresses |
timestamp |
Unix timestamp of response |
GET /health
Health check endpoint.
Response:
{"status": "ok"}
GET /
API information.
Response:
{
"name": "Tether API",
"version": "1.0.0",
"endpoints": [
{"path": "/status", "method": "GET", "description": "Get phone status"},
{"path": "/health", "method": "GET", "description": "Health check"}
]
}
Client Examples
Basic curl
curl http://192.168.42.1:8765/status
Auto-discover phone IP
#!/bin/bash
for ip in 192.168.42.1 192.168.43.1 192.168.44.1; do
if curl -s --connect-timeout 1 "http://$ip:8765/health" | grep -q "ok"; then
echo "$ip"
exit 0
fi
done
exit 1
Waybar module
~/.config/waybar/config:
{
"custom/phone": {
"exec": "~/.local/bin/phone-status.sh",
"return-type": "json",
"interval": 10,
"format": "{}"
}
}
~/.local/bin/phone-status.sh:
#!/bin/bash
PHONE_IP="${PHONE_IP:-192.168.42.1}"
PORT="${PORT:-8765}"
status=$(curl -s --connect-timeout 2 "http://$PHONE_IP:$PORT/status")
if [ -z "$status" ]; then
echo '{"text": "N/A", "tooltip": "Phone not connected", "class": "disconnected"}'
exit 0
fi
type=$(echo "$status" | jq -r '.connection.type')
bars=$(echo "$status" | jq -r '.connection.signal_bars')
battery=$(echo "$status" | jq -r '.battery.level')
case $bars in
4) signal="▂▄▆█" ;;
3) signal="▂▄▆░" ;;
2) signal="▂▄░░" ;;
1) signal="▂░░░" ;;
*) signal="░░░░" ;;
esac
echo "{\"text\": \"$type $signal $battery%\", \"tooltip\": \"$type | Signal: $bars/4 | Battery: $battery%\", \"class\": \"$type\"}"
Python client
import requests
def get_phone_status(ip="192.168.42.1", port=8765):
try:
r = requests.get(f"http://{ip}:{port}/status", timeout=2)
return r.json()
except:
return None
status = get_phone_status()
if status:
print(f"Connection: {status['connection']['type']}")
print(f"Signal: {status['connection']['signal_bars']}/4")
print(f"Battery: {status['battery']['level']}%")
KDE Plasmoid / Generic widget
Most desktop widgets can execute shell commands. Use the curl/jq approach:
curl -s http://192.168.42.1:8765/status | jq -r '"\(.connection.type) \(.connection.signal_bars)/4 \(.battery.level)%"'
Building
Debug build
./gradlew assembleDebug
# Output: app/build/outputs/apk/debug/app-debug.apk
Release build
- Generate a keystore:
keytool -genkey -v -keystore keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias release
- Build with signing:
export KEYSTORE_PASSWORD="your-password"
export KEY_ALIAS="release"
export KEY_PASSWORD="your-key-password"
./gradlew assembleRelease
# Output: app/build/outputs/apk/release/app-release.apk
Contributing
See CONTRIBUTING.md for guidelines.
License
GPLv3 - see LICENSE