Files
android-tether-api/README.md
Giovanni Harting 708833e97c Prepare for open source release under GPLv3
- 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)
2025-12-19 06:33:04 +01:00

218 lines
4.8 KiB
Markdown

# 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 carrier
- `ACCESS_FINE_LOCATION` - Required by Android 10+ for signal strength
- `POST_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:**
```json
{
"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:**
```json
{"status": "ok"}
```
### GET /
API information.
**Response:**
```json
{
"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
```bash
curl http://192.168.42.1:8765/status
```
### Auto-discover phone IP
```bash
#!/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:**
```json
{
"custom/phone": {
"exec": "~/.local/bin/phone-status.sh",
"return-type": "json",
"interval": 10,
"format": "{}"
}
}
```
**~/.local/bin/phone-status.sh:**
```bash
#!/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
```python
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:
```bash
curl -s http://192.168.42.1:8765/status | jq -r '"\(.connection.type) \(.connection.signal_bars)/4 \(.battery.level)%"'
```
## Building
### Debug build
```bash
./gradlew assembleDebug
# Output: app/build/outputs/apk/debug/app-debug.apk
```
### Release build
1. Generate a keystore:
```bash
keytool -genkey -v -keystore keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias release
```
2. Build with signing:
```bash
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](CONTRIBUTING.md) for guidelines.
## License
GPLv3 - see [LICENSE](LICENSE)