tauri-apps / tauri-apps/plugins-workspace
[bug] Android save dialog renames duplicate files as "file.pdf(1)" instead of "file(1).pdf"
- Dominant language
- Rust
- Stars
- 1.8k
- Forks
- 602
- Avg merge
- 4d 14h
- Merged PRs (30d)
- 9
Description
### Describe the bug
### Describe the bug
On Android, when saving a file via `@tauri-apps/plugin-dialog`'s `save()`
to a location where a file with the same name already exists, the SAF
(Storage Access Framework) document provider appends the disambiguation
suffix AFTER the full filename instead of before the extension.
Example:
- Expected: `10mb.pdf` → `10mb(1).pdf`
- Actual: `10mb.pdf` → `10mb.pdf(1)`
### Root cause
**File:** `plugins/dialog/android/src/main/java/DialogPlugin.kt`
**Function:** `saveFileDialog()`
**Line:** 207
```kotlin
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.putExtra(Intent.EXTRA_TITLE, args.fileName ?: "")
intent.type = "*/*" // ← hardcoded regardless of filters
if (parsedTypes.isNotEmpty()) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, parsedTypes)
}
```
### Reproduction
Call save({ defaultPath: "10mb.pdf", filters: [{ name: "PDF", extensions: ["pdf"] }] }).
Save to a folder that already contains 10mb.pdf.
Observe the resulting file is named 10mb.pdf(1) instead of 10mb(1).pdf.
### Expected behavior
_No response_
### Full `tauri info` output
```text
Use the first parsed filter's MIME type when available, falling back to
the wildcard only when no filters are given:
intent.type = parsedTypes.firstOrNull() ?: "*/*"
I've tested this fix locally (forked build) and confirmed it produces the
correct name(1).ext format on a real device (Pixel 7, Android 14).
```
### Stack trace
```text
```
### Additional context
Use the first parsed filter's MIME type when available, falling back to
the wildcard only when no filters are given:
intent.type = parsedTypes.firstOrNull() ?: "*/*"
I've tested this fix locally (forked build) and confirmed it produces the
correct name(1).ext format on a real device (Pixel 7, Android 14).
Contributor guide
Research direction
Start in plugins/dialog/android/src/main/java/DialogPlugin.kt at saveFileDialog(), around line 207, and inspect how parsedTypes and the Android document intent are used. Reproduce the save operation with a duplicate .pdf and a PDF filter on Android, then verify that duplicate naming places the suffix before the extension while unfiltered saves retain current behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100