Skip to content

Disk usage structure

Lineflyer edited this page Dec 15, 2021 · 13 revisions

This is the c:geo storage usage structure (after implementing issue #4963, #4964 and #4957).

Note: Migration path from previous versions have been removed here. See history of this article to see them.

General Android Directories

Used Android directories:

# Logical Name Example(s) Android API User Accessible Delete on uninstall
1 System Internal /data/data/cgeo.geocaching Context.getFilesDir()
2 Internal Storage /sdcard/Android/data/cgeo.geocaching/files, /storage/emulated/0/Android/data/cgeo.geocaching/files, /mnt/sdcard/Android/data/cgeo.geocaching/files Context.getExternalFilesDir(null)
3 External Storage /sdcard/cgeo Deprecated - Replaced by custom folder using scoped storage (SAF) (Legacy: Environment.getExternalStorageDirectory() + "cgeo"
4 Pictures /sdcard/Pictures/cgeo no longer used since version 2021.04.15 (SAF) (legacy: Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES))
5 External SD Card /storage/extSdCard/Android/data/cgeo.geocaching/files, /storage/sdcard1/Android/data/cgeo.geocaching/files, /storage/1234-ABCD/Android/data/cgeo.geocaching/files Context.getExternalFilesDirs(null)[1+]

How different data is stored

Database

There are two options to store the c:geo database depending on user setting:

  • <1>/databases/ (default, internal memory, removed on uninstall)
  • <2>/databases/ (isDbOnSd setting, emulated sdcard, removable sd on some devices, removed on uninstall)

Additional data for caches

Additional geocache data is stored in the subdirectory "GeocacheData". As users requested not to store cache data on the emulated internal sdcard but on the real sdcard, we implemented different choices in user settings. We have three options implemented:

  • <2>/GeocacheData/ (default, emulated sdcard, removable sd on some devices, removed on uninstall)
  • <5>/GeocacheData/ (choice in settings, real sdcard, removed on uninstall)
  • <1>/GeocacheData/ (fallback if neither emulated nor real sdcard is available)

Backup

Backups should be easily accessible by the user, therefore we store them in a visible directory, in subdirs of <3>/cgeo/backup/ named by date & time (format: YYYY-MM-DD HH-MM). Backup file of database will be named cgeo.sqlite, backup of program settings cgeo-settings.xml.

GPX Import/Export

The default directory for GPX export/import targets a subdirectory of <3>/cgeo/ namely gpx in order to have everything at a single place. Still the user should be able to select his preferred directory.

Logfiles

Logfiles created by using one of the debug functions in c:geo are stored in <3>/cgeo/logfiles/.

Offline map files

If no user-defined map directory is set, a downloaded offline map file will be stored in <3>/cgeo/maps/.

Field note export

Field notes are exported to <3>/cgeo/field-notes/.

Local spoiler images

Local spoiler images can be read from <3>/cgeo/GeocachePhotos/.

Folder where photos taken in c:geo are saved

When taking a photo with c:geo while using the photo attachment function in c:geo cache logging, the photo is saved to <4>/cgeo.

How to store local data in Android

This summarizes the general methods to store and access local data on Android. It applies to APi state 29 and above. It was collected while working on #8457 and is documented here to keep it for the future.

All methods of reading and writing local data to android can be classified with regards on who can access the data:

  • private/internal: private data is only visible for c:geo itself. Such data cannot be read by the user or any other app outside of c:geo. It is typically deleted by Android on uninstalling c:geo.
  • public: public data written by c:geo is visible also outside of c:geo to other apps and the user (e.g. using file manager apps). Also, public data from other apps can be read or modified by c:geo.

Also, many methods differentiate on where the data is actually stored. This might be:

  • internal storage: this is typically placed in build-in memory of the device and can be considered "stable" (it is always there)
  • external storage: typically plaved on an SD card, data placed here might or might not be available since SD cards can be removed from device. NOrmally SD card is emulated on internal storage if not available though.

Files

The classical Java File interface is the traditional and most familiar way to access data. Android provides various methods to get locations of standard folders. Starting with API21 and enforced with API30, Android does no longer allow accessing public data using File API. Private data however can still be accessed. This policy is the reason for most of the deprecations of some very useful methods in the following list.

# Accessed directory API method Public? External/Internal Deprecation status
Ctx.Int Private internal App storage space Context.getFilesDir() internal ✔ ok to use
Ctx.Ext Private internal App storage space Context.getExternalFilesDir() ✔ -API28, ❌ API29+ external ✔ ok to use
Env.Ext Public external Storage Space Environment.getExternalStorageDirectory() ✔ -API28, ❌ API29+ external ❌ Depr API29+
Env.ExtPub Public external media files Environment.getExternalStoragePublicDirectory() external ❌ Deprecated for API29+, but surprisingly still working even in API30

In summary, Android still encourages the use of Files for all app-private data while it is pushing apps to use either SAF or MediaStore API for all public data. As an example here is the documentation of one of the methods above: https://developer.android.com/training/data-storage/shared/media

Storage Access Framework: Scoped storage

The Storage Access Framework is meant for usage of public data shared between applications. Its idea is to let the user select explicitely files or directories she wants to share with the app. This is done using Intents where the most important ones are:

  • Intent#ACTION_OPEN_DOCUMENT: opens a single document/file for read
  • Intent#ACTION_CREATE_DOCUMENT: creates a new document where the application can then write to
  • Intent#ACTION_OPEN_DOCUMENT_TREE: opens a whole directory for read and/or write All file/directory selection is done in the intent, the app just gets an Uri in return which can then be accessed using the SAF API. A most interesting feature of SAF is that permissions granted to the app by the user using the aboive intent can be persisted by the app (and are thus also available after restart). However, it is always the user who was to explicitely grant these permissions at least one time using the mentioned intents.

This also means that when using SAF the app can't control the file/folder structure used by the user any more. Only inside a directory where access was granted via Intent#ACTION_OPEN_DOCUMENT_TREE the app can create structures freely.

More information can be found here: https://developer.android.com/preview/privacy/storage

MediaStore API

The MediaStoreAPI is a way to access the common media collections maintained in an android system (Images, Videos, Music, Documents and so on). Each such collection has an Uri to access it with which can be retrieved using the class MediaStore. For example, the uri representing the "Documents" collection stored on external storage can be retrieved via MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY).

Once we have such an Uri, the collection can be accessed using SQL-like commands (insert, query, update, delete) via a ContentResolver. More information about the API can be found here: https://developer.android.com/training/data-storage/shared/media

Some notes about this API:

  • API is "collection-oriented", not "folder-structure-oriented". Relevant Collections are e.g. "Files" (=Documents or Downloads) or "Images" (=Pictures or DCIM)
  • Can be accessed in a SQL-Database-like fashion (insert, query, update, delete commands)
  • BUT: does not allow the application to structure collection beyond a "system folder" structure (choosing is limited to e.g. selection "Pictures" or "DCIM for images or "Documents" or "Downloads" for Documents, via REL_PATH, starting with SDK29 only)
  • only allows to access files written by cgeo itself (this restriction would be fine of course)
Clone this wiki locally