Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No support for takePersistableUriPermission? #8336

Closed
zell-mbc opened this issue May 1, 2021 · 8 comments
Closed

No support for takePersistableUriPermission? #8336

zell-mbc opened this issue May 1, 2021 · 8 comments
Labels
bug needs info Waiting for info from user(s). Issues with this label will auto-stale.

Comments

@zell-mbc
Copy link

zell-mbc commented May 1, 2021

Thanks to your help here #8028 I managed to sucessfully implement backups to NextCloud. However, there is one thing where I don't know if it is by design or a bug.
When creating a backup I capture the URI and request persistent permissions so I can backup user data automatically when the app is started again:

app.contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

This works fine as long as the destination is local. If I pick Nextcloud as a target I can reuse the uri for backups as long as the app is running. The moment the app is restarted the uri is invalid. So to me this looks like the takePersistableUriPermission call isn't working or maybe simply not supported for Nextcloud?

Steps to reproduce

  1. request persistent permissions for a NC folder via takePersistableUriPermission
  2. store the uri in e.g. sharedPreferences
  3. close the app
  4. start the app again and try to reuse uri

or

  1. Load this app: https://gitlab.com/toz12/medilog
  2. Set automatic backups on
  3. run a manual backup to a NC folder
  4. stop the app
  5. start the app
  6. kick off a backup using the stored uri via selecting about/last backup

Expected behaviour

  • Folder remains accessible without the need to re-authenticate

Actual behaviour

  • Access to uri is denied

Environment data

Android version: 10

Device model: Several

Stock or customized system: Stock

Nextcloud app version: 3.15.1

@zell-mbc zell-mbc added the bug label May 1, 2021
@tobiasKaminsky tobiasKaminsky added the needs info Waiting for info from user(s). Issues with this label will auto-stale. label May 4, 2021
@tobiasKaminsky
Copy link
Member

Currently I fail to understand what is needed where.

Where how do you request what on NC files app?
Can you give me an example? Do you use our DocumentsStorageProvider?

@zell-mbc
Copy link
Author

zell-mbc commented May 4, 2021

Happy to add more detail. One of the features my app offers is regular/automated backups. The workflow is like below:

  1. User selects backup option
  2. I start an intent "Intent(ACTION_OPEN_DOCUMENT_TREE)" which allows the user to select the destination for the backup file via the standard Android UI, Viable destinations are the local file system and Nextcloud (if NC client is installed). Nextcloud is a superior destination for backups because whatever is stored local to the phone isn't a proper backup.
  3. My app saves the backup file in the folder represented by the uri I get back from the intent above.

This is working reliably for Nextcloud and local storage.

To simplify the backup process I also allow users to define the destination folder once and then store the uri in sharedPrefs so when the app starts next time, or after a set number of days I can reuse the uri and automatically save another backup in the same folder.

To make a uri persistent/survive a restart, I use

        app.contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

This is working, but only if the destination folder is on the local file system. In case the user selected a folder on Nextcloud I can reuse the stored uri for as long as the app is running, the moment the app is restarted the stored uri is invalid, like if the takePersistentUriPermissions call didn't happen.

So what I need to find out is, if persistent uri's via contentResolver.takePersistableUriPermission (or any means) are supported by the Nextcloud DocumentsStorageProvider, and if yes, I would like to find out where things go wrong for me.

Here's some code to further illustrate:

  1. Select destination via Android file/folder picker
                // Pick backup folder
                val intent = Intent(ACTION_OPEN_DOCUMENT_TREE)
                intent.addCategory(CATEGORY_DEFAULT)
                intent.addFlags(FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
                intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION)
                intent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION)
                startActivityForResult(createChooser(intent, this.getString(string.selectDirectory)), rcBACKUP)

I do not explicitly use the NC DocumentsStorageProvider but think that when the user selects Nextcloud as destination through the Android file picker UI via the intent, I implicitly interact with it?

  1. Next, the intent gives back control to me with the uri of the folder the user selected:
       override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        data ?: return
        // Backup section
        if (requestCode == rcBACKUP && resultCode == Activity.RESULT_OK) {
            var backupFolderUri: Uri? = null

            // Check Uri is sound
            try {
                backupFolderUri = data.data
  1. I create the backup file
  2. Make the uri persistent
    app.contentResolver.takePersistableUriPermission(backupFolderUri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
  3. Create a DocumentFile object from the uri and save the backup file inside this folder.
…
dFolder = DocumentFile.fromTreeUri(app, backupFolderUri)
…
dFile = dFolder.createFile("application/zip", zipFile)
…

Like I said, all of this works for local storage and Nextcloud, it's the persistence which I can't seem to get when the uri points to Nextcloud.

Hope this makes more sense now?

@github-actions

This comment was marked as outdated.

@github-actions github-actions bot added the stale label Jun 1, 2021
@AndyScherzinger AndyScherzinger added approved and removed needs info Waiting for info from user(s). Issues with this label will auto-stale. stale labels Jun 1, 2021
@AndyScherzinger
Copy link
Member

Also looping in @grote, being a user/expert on SAF/document-provider and utilizing the Nextcloud files app for interactions

@grote
Copy link
Member

grote commented Jun 1, 2021

Seedvault is using takePersistableUriPermission successfully against NextCloud, maybe check its code.

@AndyScherzinger
Copy link
Member

@AndyScherzinger AndyScherzinger added needs info Waiting for info from user(s). Issues with this label will auto-stale. and removed approved labels Jun 1, 2021
@zell-mbc
Copy link
Author

zell-mbc commented Jun 3, 2021

Great! Thanks for confirming that takePersistableUriPermission is supported. I will check out seedvault.

@zell-mbc
Copy link
Author

Well, after checking the seedvault source it turns out that my code to grab persistent permission is identical.
But mine was inside a try / catch block and for whatever reason that made the difference. So try/catch is gone and takePersistableUriPermission is working.

Thanks everyone for helping me along to get to this successful conclusion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug needs info Waiting for info from user(s). Issues with this label will auto-stale.
Projects
None yet
Development

No branches or pull requests

4 participants