简体   繁体   中英

Accessing files created in public folders after uninstall and reinstall of app?

I'm using SqliteImportExporter library to import and export my database file to public folder "Documents". I don't think the file has a MIME type, it's just created from a stream of bytes and has a .db file extension.

After targeting Android API 30, if I uninstall and reinstall my app, it cannot access the file it created earlier, to either import it or overwrite it.

The Android documentation talks about using ACTION_OPEN_DOCUMENT_TREE intents to give access to the entire directory and it's contents. After selecting the directory to give permission, it still have no access. Is there something magic about the URI returned by this process, or can I still use the library after getting permission? I am providing the library with an absolute path to the file - which works until I target API 30 and run the app on an API 30 AVD.

Can someone point me in the right direction on how to proceed please?

EDIT: My question simply now boils down to, How can one simply copy a file to/from the shared folders (eg documents folder) when targeting API 30, and still maintain support for API 21 onwards.

Reputation below 50 so adding my comment as answer.

Please refer to this question . As explained here, Once uninstalled your app don't have ownership of its own created files and you will have to work with permission of that folder.

I'm using SqliteImportExporter library

Note that this library does not appear to be being maintained.

Is there something magic about the URI returned by this process

Yes. For example, you could wrap it in a DocumentFile using DocumentFile.fromTreeUri() , then use that DocumentFile to get DocumentFile objects representing the documents directly in the root of that tree, etc.

Personally, I used ACTION_CREATE_DOCUMENT / ActivityResultContracts.CreateDocument() and ACTION_OPEN_DOCUMENT / ActivityResultContracts.OpenDocument() in this sample project demonstrating importing and exporting databases (covered in this book , FWIW).

How can one simply copy a file to/from the shared folders (eg documents folder)

You already have code for this. Your issue is with an uninstall/reinstall cycle and losing permissions to that file. You have a few choices for dealing with that.

First, you could ask the user to remove that file created by your old app installation, so you can write your hard-coded(?) filename to your hard-coded destination again. The user could do this with a pre-installed file manager, for example, if the user has one.

Second, you could let the user choose a filename. If they choose one that you cannot use due to this permissions issue, tell the user and ask the user to give you another filename. Or, you could automatically adjust the filename, the way that Web browsers do when downloading files (eg, add (1) to the name).

Third, you could stop writing to Documents/ and instead write to getExternalFilesDir() (method on Context ). The two main downsides is that this directory is not as convenient and that its contents get removed when your app is uninstalled.

Fourth, you could do what I do in that sample: use ACTION_CREATE_DOCUMENT / ActivityResultContracts.CreateDocument() to let the user choose where to create the exported database and what to call it. You can then use ContentResolver and openOutputStream() to get an OutputStream for the Uri that you get back, and you can copy the bytes of the database to that OutputStream . For a later import, use ACTION_OPEN_DOCUMENT / ActivityResultContracts.OpenDocument() to let the user choose an exported database for you to use, and use ContentResolver and openInputStream() to reverse the process. This gives the user maximum flexibility, as you are not locking them into a particular location and a particular filename. It does mean that the user will need to choose a location and confirm your suggestion of a filename.

There are other possibilities, such as fussing with ACTION_OPEN_DOCUMENT_TREE , but that one in particular is cumbersome IMHO.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM