Search code examples
androiddatabasetransactionsandroid-contentproviderstorage-access-framework

Direct file access (SQlite database) with Android 10+


I have 2 apps A & B. A can download data to a sqlite database owned by B. Until now I asked the user the WRITE_EXTERNAL_STORAGE permission and A could directly write to B's database, and thus use transactions in order to avoid altering the database if the user cancels the process.

With Android 10 direct file access does not seem to be possible anymore as we are forced to use that ****** SAF...

To still get this working I updated my apps to use a ContentProvider. However, I'm no longer able to use transactions to provide the cancel feature: the data being too heavy to fit in memory, I can't use the ContentProvider's batch insert methods (if I'm not mistaken?).

Am I stuck? Or is there a solution to grant a direct file access between two apps I own? Ideally he process would be like this:

  • 1 asks B a file access
  • B grants the access
  • A starts a transaction
  • A download file 1
  • A download file 2
  • [...]
  • A download file n
  • A commits the transaction (or rollbacks if user asked to cancel)
  • A notifies B that the download is done
  • B revokes the access

Is that possible?

EDIT: I need an access with the File object, in order to use the SqliteDatabaseOpenHelper class, thus grantUriPermission won't help me.


Solution

  • is there a solution to grant a direct file access between two apps I own?

    No.

    Am I stuck?

    You could do:

    • A download file 1
    • A download file 2
    • [...]
    • A download file n
    • A tells B "yo, I downloaded these files" by some means (see below), if the user did not cancel the operation
    • B updates its own database

    "By some means" could be:

    • insert() or update() with your ContentProvider
    • a command delivered by startService()
    • bindService() and a call on the AIDL-defined API exposed by B's service
    • a broadcast Intent with an explicit Intent
    • starting an activity in B, if that would be appropriate (probably not, just mentioning for completeness)

    A has a "user transaction" and can stop its downloads based on user interaction. Once the downloads are complete, B can perform the database transaction to update its own database with the details of the downloaded stuff.