A wxPython application for MacOS to copy files from and Android device, using ADB, to local directories
The app scans on a connected Android device, the specified source directories, and recursively the subdirectories, for the files which comply with the specified ignore/include filters.
The application uses ADB commands to interact with the Andriod device, wxPython for the GUI, and Python threading for background processing. Building this code was inspired by the much more comprehensive Android file transfer app by Cj Carito.
The copy operations are configured in the config.yaml YAML file. The copy operations are grouped as tasks. Each task is configurable with its own label, name, source, target, target_subdir, include and ignore parameters.
Logging is implemented to track scan and copy operations. Each run of the app is logged to a separate timestamped log file. The results of the scan/copy operations are logged to the output history_syncdbapp_YYYYMMDD_HHMMSS.log file, where the YYYYMMDD_HHMMSS indicates the date/time when the application has been started.
Make sure to have the ADB utility installed and properly set up on your system. The Android device needs to have '{} Developer options' enabled and 'USB debugging' turned on to allow ADB access. The source directories in the configuration file, source, should be specified in the format used by ADB (e.g., "/sdcard/DCIM/Camera", or "/storage/self/primary/DCIM/Camera/").
This app uses ADB commands to access the files on the Android device (see https://teamandroid.com/adb-commands-list/), so ensure that your device is connected and recognized by ADB before running the app.
The app recreates the subdirectory structure found under the source directory, source, in the target directory, target, for each file to be copied. The file metadata information (creation and modification date) are preserved after copy.
When the target_subdir is specified, this string is used to generate an addtional subdirectory in the target directory. The target_subdir string can include any of the standard format directives for time conversion. The target_subdir can contain any other string in addition to the format directives. The date and time information is extracted from the file modification time (stat.st_mtime).
When no format directive is present in target_subdir, the string is simply used as is as the subdirectory name.
The config.yaml specifies for one task the following:
source: /storage/self/primary/Pictures
target: /Users/Pictures
target_subdir: 'Pictures_%Y_%m_%d'
On the Android device the files and subdirectories, under the souurce directory are:
/storage/self/primary/Pictures/
├── picture1.jpg # with m_time = 2026-03-09 21:00:31
├── notes/
│ ├── note1.jpg # 2026-03-09 11:00:30
│ ├── note2.jpg # 2026-03-09 21:00:30
│ └── note3.jpg # 2026-03-10 11:00:00
Running the app and task configured as above, on the target device the following structure will be generated with files copied from the source:
/Users/Pictures/
├── Pictures_2026_03_09/
│ └── picture1.jpg
├── notes/
│ ├── Pictures_2026_03_09/
│ │ ├── note1.jpg
│ │ └── note2.jpg
│ └──Pictures_2026_03_10/
│ └── note3.jpg
The include and ignore filters can both specify startswith and endswith string patterns. First, for each of the subdirectories and files found in the specified source directory source, the include startswith patterns (if any) are applied. Next, the ignore startswith and endswith patterns are applied to each file name. Last, the include endswith patterns are applied to each file name.
- Clone this repo:
git clone https://github.com/istvanzk/adbftapp
cd adbftapp
-
Configure/edit the sync tasks in
config.yaml -
Run the python app with:
python3 adbftapp.py
-
In the app GUI select with the checkboxes what operations you would like to perform for each task to be run:
a) Scan: It scans recursively the Source directory, and recursively the subdirectories, based on the filters and the file modification date after the last synced date given in the
config.yamlfor the task. The Scan datetime is not recorded in theconfig.yamlfile.b) Copy: Copies recursively the files found during scanning, with addtional filtering applied to the file names, to the Target directory and optional sub-dierectory. Files which are already found in the Target are not overwritten only if the Source constains newer (modified data) versions of the same files. A Copy a operation can be run only after a Scan, and the Copy date/time is recorded in the
config.yamlfile. -
Run the desired task with the corresponding buttons Run <Task label>, or adjust (some of the) configuration parameters for the task with the button Config. The status and progress of each run are displayed inside the corresponding task box.
NOTEs:
- Each task run operation is executed in a separate python thread.
- Not all options are provided to adjust the task configuration under Config. Please use the
config.yamlfile for detailed configurations adjustments.