Google Fit was paired with WearOS wearable. The phone application is not a default application, and it must be downloaded from the Play Store. The findings show that the app will automatically log activity without user intervention.  For example, Josh walked from his parked car to the front door of the local Target, and his activity was logged as a walk; He was parked ~50 yards from the storefront.  Location data may or may not be associated with the activity and appeared to be sporadic.  Josh also had instances where his walking was automatically logged just walking around inside of a store if he walked long enough.   

Since location is a “Dangerous” Permission, access has to be granted both on the phone app and on a paired WearOS wearable. The data resides in two locations: 

USERDATA/data/com.google.android.gms/databases/fitness.db.[GMAIL ACCOUNT NAME] 

  •  This is not automatically present. The user has to sign into the app in order for this to appear on the device.

  •  For Josh, the file name is fitness.db.thisisdfir_gmail.com

  •  The ability to add accounts in Google Fit exists, so it is possible more than one database could reside in this location. 

  •  This database contains a lot of the same data seen in the others from com.google.android.apps.fitness.   

  •  Entries in this database appear to correspond to the Google Fit Takeout data for the account. 

  •  This file also exists on any WearOS device that is paired to the phone, using the same Google account as the phone, and is using Google Fit.  File name and location within WearOS is the same. 

  •  There may be data in this table that was generated elsewhere (another device on which the user has signed into the app). 

Table: 

Sessions

Activity codes: 

7 =  Walk 

8 =  Run 

72 = Sleep 

NOTE: These are the codes that have been tested. Others may exist.

Query: 

 SELECT 

datetime(Sessions.start_time/1000,'unixepoch') AS "Activity Start Time (UTC)", 

datetime(Sessions.end_time/1000,'unixepoch') AS "Activity Stop Time (UTC)", 

Sessions.app_package AS "Contributing App", 

CASE 

WHEN Sessions.activity=7 THEN "Walking" 

WHEN Sessions.activity=8 THEN "Running" 

WHEN Sessions.activity=72 THEN "Sleeping" 

END AS "Activity Type", 

Sessions.name AS "Activity Name", 

Sessions.description AS "Activity Description" 

FROM 

Sessions 

ORDER BY "Activity Start Time (UTC)" ASC 

USERDATA/data/com.google.android.apps.fitness 

  •  Most of the interesting data is located in ~/files/accounts/%ACCOUNT_NUMBER%/ 

  •  Account numbers start with "1" 

  •  Folder contains a mix of protobuf and database files 

  •  Files of interest: 

  •  session_database.db 

  •  Table:  session_entries 

  •  Column id can contain the start/end times of the activity or the source.  In cases of the source, the format is as follows:  

  •  IDENTIFIER:activemode:[ACTIVITY]:Start time (UNIX EPOCH) 

  •  IDENTIFIER:watch-activemode:[ACTIVITY]:Start Time (UNIX EPOCH) (for activity tracked by WearOS wearable) 

  •  Usually, the start time value is the same as that seen in the column "start_time_ms" 

  •  Columns "start_time_ms" and end_time_ms are start/end times in Unix Epoch 

  •  Column activity_type contains numerical code for activity: 

  •  Type 8 = Run 

  •  Type 7 = Walk 

  •  Type 72 = Sleep (Sleep)  

  •  **Josh has seen other activity_type values, but these three seem to be consistent.   

  •  journal_database.db 

Table:  journal_entries  - populates the Journal tab in the app UI 

Column “id” contains the source of the entry.  Entries with “header” mark the beginning of the next day.  I had to use two bridging apps:  FitToFit (to import Fitbit data)  and Health Sync (to import Garmin data).   

For WearOS devices, the entries are different.  For example: 

IDENTIFIER:watch-activemode:running:[UNIX TIMESTAMP] 

Entries for phone-only tracked activities are different.  For example: 

IDENTIFIER:activemode:walking:[UNIX TIMESTAMP] 

The timestamps appear to be the starting time of the activity.  The "watch" portion (probably the "WearOS device used" portion) is absent. 

Column “journalEntry” contains protobuf.  The protobuf describes the entry.  Contained within is the title of the journal entry (e.g., “Morning Run”), start and end times, activity type code (see codes from session_database.db), length of activity (in milliseconds), source app package (e.g., com.google.android.apps.fitness).   

For the bridging apps (FitToFit for Fitbit and Health Sync for Garmin), the blobs for those entries contain the actual source of the activity (Fitbit or Garmin).  Again, thank you Josh Hickman for your level of effort on Android Health research.