Last active
October 18, 2024 13:36
-
-
Save lmgarret/10201a1448ce244c43a1ed846bfc722c to your computer and use it in GitHub Desktop.
This script takes an ADB backup `backup.ab` of PhoneTrack, and outputs a GPX file with timestamps and other metadata. Run with `uv run --script phonetrack_ab_to_gpx.py`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# /// script | |
# requires-python = ">=3.12" | |
# dependencies = [ | |
# "gpxpy", | |
# "android_backup", | |
# ] | |
# /// | |
import sqlite3 | |
import subprocess | |
import tarfile | |
import os | |
from datetime import datetime | |
from android_backup.android_backup import AndroidBackup | |
import gpxpy | |
import gpxpy.gpx | |
# Path to your .ab file | |
backup_ab = "backup.ab" | |
# Output .tar file | |
backup_unpacked = "backup.ab.unpacked" | |
with AndroidBackup(backup_ab) as ab: | |
ab.unpack(backup_unpacked) | |
# Verify the file extraction | |
db_path = os.path.join(backup_unpacked, "apps", "net.eneiluj.nextcloud.phonetrack", "db", "NEXTCLOUD_PHONETRACK") | |
print(f"DB extracted at: {db_path}") | |
print(f"Reading PhoneTrack db file...") | |
# Connect to the SQLite database | |
conn = sqlite3.connect(db_path) | |
cursor = conn.cursor() | |
# Query to retrieve data from the LOCATIONS table | |
cursor.execute("SELECT LAT, LON, TIME, BEARING, ALTITUDE, SPEED, ACCURACY FROM LOCATIONS") | |
rows = cursor.fetchall() | |
print(f"Found {len(rows)} locations") | |
# Create a GPX object | |
gpx = gpxpy.gpx.GPX() | |
# Create a GPX track | |
gpx_track = gpxpy.gpx.GPXTrack() | |
gpx.tracks.append(gpx_track) | |
# Create a GPX track segment | |
gpx_segment = gpxpy.gpx.GPXTrackSegment() | |
gpx_track.segments.append(gpx_segment) | |
# Add points to the GPX segment | |
for row in rows: | |
lat, lon, time, bearing, altitude, speed, accuracy = row | |
gpx_point = gpxpy.gpx.GPXTrackPoint( | |
latitude=lat, | |
longitude=lon, | |
time=datetime.utcfromtimestamp(time), | |
elevation=altitude | |
) | |
gpx_point.bearing = bearing | |
gpx_point.speed = speed | |
gpx_point.hdop = accuracy | |
gpx_segment.points.append(gpx_point) | |
print("Writing locations to 'output.gpx'...") | |
# Write the GPX file | |
with open("output.gpx", "w") as f: | |
f.write(gpx.to_xml()) | |
print("Done!") | |
# Close the database connection | |
conn.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
My previous phone's screen had died and my Nextcloud instance had only records up until 01.2024 even though I was sure to have started the log job in 2022 on the broken phone.
I spent quite some time trying to enable USB debugging to get access to the phone using
scrcpy
. Once in, I manually exported the logjob to a GPX only to have the same findings as you did: the timestamps are not included. I even saw that a recent commit temporarily disabled the feature so I looked into other means of getting this location data back. Here's how I managed to extract the location data from my phone:adb
, with:this will require accepting the backup on the phone
Once the backup is done, you should have a
backup.ab
file. It contains the app's database! We will extract it using a small python script I wrote.Ideally, you should install
uv
to run the script with its dependencies. You can also manually pip install the script's dependencies and run it.The script is here
phonetrack_ab_to_gpx.py
. It does not take inputs, just run it withuv run --script phonetrack_ab_to_gpx.py
.ab
file into a local dirapps/net.eneiluj.nextcloud.phonetrack/db/NEXTCLOUD_PHONETRACK
LOCATIONS
tableoutput.gpx
fileYou should now have an
output.gpx
file with all locations, complete with timestamp, altitude, speed etc...!Hopefully this very niche script will help somebody :)