Skip to content

[v1.1] Support sharing Non-Text Clipboard Items #15

@patrickd-

Description

@patrickd-

Expected task duration: 3 hours
Reward for accepted PR: US$75

Summary

The App currently assumes that clipboard contents would only ever contain a single plaintext item. But this isn't the case. But there could be multiple clipboard items containing things like HTML, media URIs, and even Intents.

Intents in clipboards should be pretty rare and are likely a case we can ignore. We can handle HTML the same way as we handle plaintext – just transfer it as text. The problem is media URI of various mimetypes.

Problem Description

The App currently assumes that clipboard contents would only ever contain a single plaintext item:

    private fun onShareClipboardClick() {
        val clipboard = getSystemService(ClipboardManager::class.java)
        val clipData: ClipData? = clipboard.primaryClip
        if (clipData != null && clipData.itemCount > 0) {
            val text = clipData.getItemAt(0).text?.toString()
            if (!text.isNullOrEmpty()) {
                handleShareText(text)
            } else {
                showToast(getString(R.string.message_clipboard_empty))
            }
        } else {
            showToast(getString(R.string.message_clipboard_empty))
        }
    }

It should be easy to adjust this code to handle the following:

  • If there are multiple clipboard items, all of them should be shared. The fact that it only copies a single item was based on the incorrect assumption that the other items would be older ones, ie. that there's a history of items that we have access to here. But that's not the case: All items are part of the same current clipboard.
  • Handle non-plaintext items by simply coercing them into text using item.coerceToText(this)?.toString(). This should be the default / fallback case if the clipboard item is not a media URI.

The real challenge here is handling those media URIs because, depending on their item.uri.scheme...

  • They could be content:// (unlikely but possibly even file:// or android.resource://?) going through a ContentProvider and need to use the ContentResolver to be accessed
  • They could be https:// or http:// and would need to be downloaded with an HTTP Client or the DownloadManager (But what if the user actually just wanted to share the URL and not the actual file behind it?)
  • They could be data:image/png;base64,... and contain the media within the URI itself

From what I can find in the "real world", the majority of apps that display multi-media only allow the user to share (via Intents) or directly download the file to the users device. But, aside from the browser and Google Docs, not a single one of them appears to actually use the clipboard to "copy" a media file.

From what I can gather, I highly suspect that those few apps that actually put media into the clipboard, will most likely do so using the content:// scheme.

Implementation Instructions

The onShareClipboardClick() function should be extended to share multiple clipboard items at once.

If the item is of Non-Text mime-type and the URI is using the content:// scheme, the contents should be shared like a file would be shared. If possible the existing handleShareFiles() handler should be used in this case (needs to be tried if that works). If that doesn't work, the file needs to be temporarily copied into the app's private folder. and then shared via handleShareFiles().

If the item is anything else, it should be coerced into text and shared as plaintext clipboard content – same as before, just using the coerceToText() in addition.

It's important to verify whether this successfully handles media that was copied from the Internet Browser or from Google Docs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions