Receive shares and serve file requests, so other apps can reach this one
The manifest had nothing but a LAUNCHER filter, so no other app could hand Plain Files anything. It now registers for ACTION_SEND and SEND_MULTIPLE (a bar over the browser: navigate to the folder, then Save here) and for GET_CONTENT and OPEN_DOCUMENT, where tapping a file hands it back through the existing FileProvider. Both reuse the browser instead of a second screen, because both are navigate-to-a-folder with a different verb at the end. data/ gains one port, IncomingSource, to keep a ContentResolver out of the ViewModel the way DeleteRequestFactory keeps one out of the delete path. Shared files are named from the sender OpenableColumns, allocated by the same NameAllocator a paste uses, and deleted again if they cannot be read rather than left as zero-byte stubs. While providing, a tap on a file chooses it but a tap on a folder still navigates, or the user could never reach the file. ACTION_VIEW is deliberately not registered: the app already hands files out through the system chooser, and registering as a viewer would offer Plain Files back to itself. No new permissions - the merged release manifest still declares no INTERNET.
This commit is contained in:
@@ -38,6 +38,27 @@ upload needs a **higher `versionCode`** than every previous upload.
|
||||
|
||||
### Added
|
||||
|
||||
- **The app can receive a share, and act as a file picker.** The manifest had nothing but a
|
||||
`LAUNCHER` filter, so no other app could hand Plain Files anything at all. It now registers
|
||||
for `ACTION_SEND`/`SEND_MULTIPLE` — a bar appears over the browser, you navigate to the
|
||||
folder you want, then "Save here" — and for `ACTION_GET_CONTENT`/`OPEN_DOCUMENT`, where
|
||||
tapping a file hands it back through the existing `FileProvider`.
|
||||
|
||||
Both reuse the browser rather than adding a second screen, because both are the same task
|
||||
underneath — navigate to a folder — with a different verb at the end. `data/` gains one
|
||||
port, `IncomingSource`, so a `ContentResolver` stays out of the ViewModel exactly as
|
||||
`DeleteRequestFactory` keeps one out of the delete path. A shared file is named from the
|
||||
sender's `OpenableColumns` where it offers one, goes through the same `NameAllocator` a
|
||||
paste does (so sharing the same file twice cannot overwrite the first copy), and is removed
|
||||
again if it cannot be read rather than left as a zero-byte stub. While another app is
|
||||
waiting for a file, tapping a *file* chooses it and tapping a *folder* still navigates —
|
||||
without that the user could never reach the file they were trying to choose.
|
||||
|
||||
`ACTION_VIEW` is deliberately **not** registered: the app already hands files out through
|
||||
the system chooser, and registering as a viewer as well would offer Plain Files back to
|
||||
itself in that chooser. No new permissions — the merged release manifest still declares no
|
||||
`INTERNET`.
|
||||
|
||||
- **Recursive search.** The query box used to filter the folder you were standing in, which
|
||||
can only ever answer "is it here?" — and the usual question is "where did I put it?". It
|
||||
now walks *down* from the current folder (`domain/FileSearch`) and streams matches as they
|
||||
|
||||
Reference in New Issue
Block a user