Skip to content

Feature: Offline Mode, Auto-Sync & File Manager Visibility#79

Closed
zerox80 wants to merge 2 commits intoopencloud-eu:mainfrom
zerox80:feature/download-sync
Closed

Feature: Offline Mode, Auto-Sync & File Manager Visibility#79
zerox80 wants to merge 2 commits intoopencloud-eu:mainfrom
zerox80:feature/download-sync

Conversation

@zerox80
Copy link
Copy Markdown
Contributor

@zerox80 zerox80 commented Jan 10, 2026

What this PR does

This PR adds three major features for offline file management, along with a MIME-type bugfix.

1. Make All Files Available Offline

Adds a "Download Everything" background worker that downloads all server files to the device for offline access. Previously, users had to tap each file individually to make it available offline.

  • Configurable under Settings → Security → Make all files available offline
  • Runs as a periodic background worker using WorkManager
  • Shows a confirmation dialog before enabling (storage/battery impact)

2. Auto-Sync (Automatic Change Detection)

Introduces a background worker that automatically detects local modifications to offline files and syncs them back to the server.

  • When a file is opened from the OpenCloud app (e.g. in Collabora Office), edited, and saved, the changes are automatically uploaded without manual intervention
  • Configurable conflict resolution: keeps conflicted copies (like the desktop client) or optional "last write wins" strategy
  • Runs periodically via WorkManager

3. File Manager Visibility (Optional)

Adds an "Enable File Manager Access" toggle under Settings → Security. When enabled, offline files are stored in Android/media/eu.opencloud.android/ instead of the app's private internal storage.

What this enables:

  • Files become visible in third-party file managers (e.g. Samsung My Files, Solid Explorer)
  • Users can browse and copy offline files without opening the OpenCloud app
  • Files can be transferred via USB/MTP to a computer

What this does NOT enable:

  • Editing files directly from a file manager (files are read-only for other apps in Android/media/)
  • Desktop-style folder sync (creating new files in the folder won't upload them)

Note: Editing files still works as before — open the file from the OpenCloud app, and it launches in the appropriate editor (e.g. Collabora) with full write permissions via FileProvider. Changes are then synced back automatically by the Auto-Sync worker.

Security considerations:

  • This setting is opt-in (disabled by default)
  • Files in Android/media/ are visible to file managers and USB, but cannot be modified or deleted by other regular apps (Android Scoped Storage restrictions apply)
  • The app's biometric/passcode lock still protects access through the OpenCloud app itself, but does not prevent browsing via an external file manager on an unlocked device
  • All Android 10+ devices have mandatory File-Based Encryption (FBE), so files are encrypted at rest when the device is powered off
  • Does not require the restricted MANAGE_EXTERNAL_STORAGE permission (Play Store compliant)
  • When disabled, files are moved back to private internal storage automatically

4. MIME-Type Bugfix

Fixes MIME-type detection so that tapping offline files correctly suggests the right external apps (e.g. Collabora Office for .docx, Gallery for images).


How the sync flow works

User opens file in OpenCloud app
  → File opens in external editor (Collabora, Gallery, etc.) via FileProvider
  → User edits and saves
  → Changes written back to local file
  → Auto-Sync worker detects modification (timestamp/size change)
  → Automatic upload to server
  → Done

Settings added

Setting Default Location
Make all files available offline Off Security
Auto-sync local changes Off Security
Always prefer local file on conflict Off Security
Enable file manager access Off Security

@zerox80 zerox80 force-pushed the feature/download-sync branch from 187f570 to 0f69672 Compare January 10, 2026 11:13
@samolego
Copy link
Copy Markdown

This is a killer feature!
Question: what happens on file conflicts, e.g. if file is edited on web and on the device? How is synchronization handled?

Also, how does background sync work in regards of battery management in Android?

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Jan 12, 2026

This is a killer feature! Question: what happens on file conflicts, e.g. if file is edited on web and on the device? How is synchronization handled?

Also, how does background sync work in regards of battery management in Android?

When a file changes both locally and remotely, automatically upload
the local version instead of requiring manual conflict resolution.
This provides a seamless auto-sync experience (last write wins).

https://github.com/zerox80/android/releases

@samolego
Copy link
Copy Markdown

When a file changes both locally and remotely, automatically upload
the local version instead of requiring manual conflict resolution.
This provides a seamless auto-sync experience (last write wins).

I don't think that's the best way to handle this. Desktop version pulls the file on conflict and names it _conflicted_copy or sth. similar.

I think we shouldn't be overwriting remote work, at least not without user confirmation.

if (!android.os.Environment.isExternalStorageManager()) {
val builder = AlertDialog.Builder(this)
builder.setTitle(getString(R.string.app_name))
builder.setMessage("To save offline files, the app needs access to all files.")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This strings should probably be translated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, can do micro patch later

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets have focus on implementing the sync stuff perfectly, translation etc can be done later

<string name="db_file" formatted="false">opencloud.db</string>
<string name="db_name" formatted="false">OpenCloud</string>
<string name="data_folder" formatted="false">opencloud</string>
<string name="data_folder" formatted="false">OpenCloud</string>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necesarry?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks better

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Jan 12, 2026

When a file changes both locally and remotely, automatically upload
the local version instead of requiring manual conflict resolution.
This provides a seamless auto-sync experience (last write wins).

I don't think that's the best way to handle this. Desktop version pulls the file on conflict and names it _conflicted_copy or sth. similar.

I think we shouldn't be overwriting remote work, at least not without user confirmation.

But whats issue with last write win strategy? The manual user interaction is really bad UX, the Sync before that sync rework worked, but showed conflict. Its just very very unlikely that it will become an issue. The overwrite happens only if i change the file and save it. I think UX should imo have more priority, cuz thats a ~1% chance that it causes issues

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Jan 12, 2026

When a file changes both locally and remotely, automatically upload
the local version instead of requiring manual conflict resolution.
This provides a seamless auto-sync experience (last write wins).

I don't think that's the best way to handle this. Desktop version pulls the file on conflict and names it _conflicted_copy or sth. similar.
I think we shouldn't be overwriting remote work, at least not without user confirmation.

But whats issue with last write win strategy? The manual user interaction is really bad UX, the Sync before that sync rework worked, but showed conflict. Its just very very unlikely that it will become an issue. The overwrite happens only if i change the file and save it. I think UX should imo have more priority, cuz thats a ~1% chance that it causes issues

So should we just add the conflict stuff again with a easy option "last write win" ? how should it be solved without causing a really really bad UX?

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Jan 12, 2026

This is a killer feature! Question: what happens on file conflicts, e.g. if file is edited on web and on the device? How is synchronization handled?

Also, how does background sync work in regards of battery management in Android?

Have to test it, but i didn't have both open at same time. I only tested editing something, closing on web, editing 2 seconds later on Android. I planned to test that scenario today

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Jan 12, 2026

@samolego
You're right that data safety should be prioritized. I'll implement a conflicted copy approach similar to the desktop version:

When both local and remote have changed, download the remote version AND keep the local file renamed as filename_conflicted_copy_.ext
This ensures no data loss while still avoiding manual intervention
The user can then compare and decide which version to keep

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Jan 12, 2026

Please test it, and give feedback.
Theres option now with always last write wins (default: Off)

edit: Conflict files are in the OpenCloud Folder, not on Server

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Jan 13, 2026

@zerox80 zerox80 force-pushed the feature/download-sync branch 3 times, most recently from c55b72f to 644300d Compare January 20, 2026 07:36
@zerox80 zerox80 force-pushed the feature/download-sync branch 3 times, most recently from 5213458 to 53d61ae Compare March 14, 2026 10:24
@zerox80 zerox80 force-pushed the feature/download-sync branch 3 times, most recently from 848a08e to 06f0356 Compare April 25, 2026 12:10
@zerox80 zerox80 changed the title Feature/download sync feat: download and sync with offline access Apr 25, 2026
@zerox80 zerox80 force-pushed the feature/download-sync branch 9 times, most recently from c139384 to 1cde2aa Compare April 25, 2026 20:23
@zerox80 zerox80 changed the title feat: download and sync with offline access feat: offline access, automatic sync, and conflict resolution Apr 25, 2026
@zerox80 zerox80 force-pushed the feature/download-sync branch from 8642b5c to 9cc8d15 Compare April 26, 2026 09:59
@zerox80 zerox80 changed the title feat: offline access, automatic sync, and conflict resolution Feature: Download Files Locally (Offline Cache) & Sync Fixes Apr 26, 2026
@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Apr 26, 2026

Hi everyone, I wanted to give an update on the current state of the sync functionality and propose a shift in focus for this PR.

In the initial testing phases, we used the MANAGE_EXTERNAL_STORAGE permission, which allowed us to perform true two-way syncing in the public Downloads/OpenCloud directory. However, we had to remove this because the Google Play Store strictly denies this permission for apps that aren't dedicated file managers.

Without MANAGE_EXTERNAL_STORAGE, Android 11+ (Scoped Storage) makes it virtually impossible to reliably track new files or external edits inside a public directory like Downloads. While we could still export the files to Downloads/OpenCloud (as a one-way mirror), any local edits made by the user in that public folder wouldn't sync back to the server, leading to silent data loss when the app downloads new versions from the server and overwrites the local copy.

Furthermore, since OpenCloud is heavily aimed at KRITIS/NIS2 companies, placing synced files in a public Downloads directory completely bypasses our app-level biometric protection and passcode features, rendering them useless.

Proposed Solution:
Instead of trying to force a broken public sync folder, I propose we pivot this PR to focus on "Secure Local Offline Cache".

  1. Files will be securely downloaded to the app's private, internal storage (where biometrics and app locks apply).
  2. Two-way sync works perfectly when users open and edit these files from within the OpenCloud app (the app temporarily provides access to the viewing app via Android's FileProvider).
  3. I have renamed the settings toggle from "Download all files" to "Make all files available offline" to properly set user expectations.

I have just pushed a commit that removes the public mirror export and updates the wording to reflect this secure, offline-cache approach. Let me know what you think!

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Apr 26, 2026

Hey guys, so I was looking into how we handle the local offline sync storage and I noticed we have a pretty big architectural choice to make.

Right now, we're saving everything into the internal Android storage (Android/data/... or /data/user/0/...).
The good thing about this: It's super secure. Since we're targeting KRITIS/NIS2 companies, this is actually perfect because nobody can just open a file manager and bypass our app's biometric lock to steal files.
The downside: Users can't see these files in their normal file explorers at all, they have to use our app.

I did some research on how Nextcloud does it, and they actually use Android/media/com.nextcloud.client/... instead.
The cool thing about Android/media is that Android doesn't hide it. You can literally just open any file manager and browse the synced files normally, and we wouldn't even need the dangerous MANAGE_EXTERNAL_STORAGE permission for 2-way sync to work.
But the huge downside here is obviously security. If we do this, any employee can just plug in a USB stick or open a file manager and copy everything, rendering our biometric app-lock completely useless.

What do you guys think? Should we stick with the current ultra-secure approach (which I kinda prefer for our target audience), or should we migrate to the Nextcloud way (Android/media) so it's easier for users to find their files? Let me know!

@guruz @kulmann

@zerox80 zerox80 closed this Apr 26, 2026
@zerox80 zerox80 reopened this Apr 26, 2026
@zerox80 zerox80 changed the title Feature: Download Files Locally (Offline Cache) & Sync Fixes Feature: Download All Files & File Manager Access Apr 26, 2026
@zerox80 zerox80 changed the title Feature: Download All Files & File Manager Access Feature: Download All Files, Auto-Sync & File Manager Access Apr 26, 2026
@ensapra
Copy link
Copy Markdown

ensapra commented Apr 26, 2026

What do you guys think? Should we stick with the current ultra-secure approach (which I kinda prefer for our target audience), or should we migrate to the Nextcloud way (Android/media) so it's easier for users to find their files? Let me know!

As I understand, the option is A or B. And I know that usually, leaving these choices to the user might not be a good idea. But being this such a requested feature (see #24), I believe it could benefit from allowing the admin to set such flag.

So, instead of this setting being in the Android device, the admin can flag the server as "Allow Two-Way sync on Android/Mobile Devices", which in turn allows the Android device to make this files available to the user in an insecure manner.

For people like me who use OpenCloud only for themselves through tailscale (Not even available online), this would be a massive benefit. By default, OpenCloud would be secure, unless the admin enables this, knowing what it entails.

@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Apr 26, 2026

Hi, i made code changes so it behaves like Nextcloud if u enable the option "Enable file manager access" - which is by default opted out - so we have a balance between security and usability. i removed the bloat from previous codes. Theres no mirroring into a new public folder anymore. I'll look into adding a option to make a real sync like desktop app (so when u create file in the folder in the file manager app, that it gets uploaded). But i am afraid if this is gonna be too complicated - we will see

@zerox80 zerox80 force-pushed the feature/download-sync branch from 82ab5ab to f60a081 Compare April 26, 2026 13:04
@zerox80 zerox80 changed the title Feature: Download All Files, Auto-Sync & File Manager Access Feature: Offline Mode, Auto-Sync & File Manager Visibility Apr 26, 2026
@zerox80
Copy link
Copy Markdown
Contributor Author

zerox80 commented Apr 26, 2026

I think i'll close this PR as it is pointless. Android restrictions... the amount of code changes without a significant UX improvement due to Android Restrictions is never getting merged, but it was a nice experiment, thanks to all :)

@zerox80 zerox80 closed this Apr 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants