0

I want to backup Room database of my app. I'm trying to get uri of database using FileProvider, but it throws IAE at this line:

 Uri contentUri = FileProvider.getUriForFile(this,
                "com.trulden.friends.FileProvider", getDatabasePath(DATABASE_NAME));

In AndroidManifest.xml I have this provider tag:

<application .. >
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true"
            >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"
                />
        </provider>
...
</application>

provider_paths.xml looks like this:

<paths>
    <files-path name="database" path="databases/"/>
</paths>

The error:

08-29 13:28:27.430 8146-8146/com.trulden.friends E/MessageQueue-JNI: java.lang.IllegalArgumentException: 
Failed to find configured root that contains 
/data/data/com.trulden.friends/databases/friends_database
        at androidx.core.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:739)

Result of getDatabasePath(DATABASE_NAME).getAbsolutePath() looks like this:

/data/data/com.trulden.friends/databases/friends_database
Kirill Smirnov
  • 131
  • 2
  • 12
  • possible duplication https://stackoverflow.com/questions/42407486/java-lang-illegalargumentexception-failed-to-find-configured-root-that-contains – Zafer Celaloglu Aug 29 '19 at 10:58
  • isn't doc pretty straight ? *`` - Represents files in the `files/` subdirectory of your app's internal storage area.* – Selvin Aug 29 '19 at 11:05
  • @Selvin yeah, you are right. Because of `databases/` in the error log I thought, that the FileProvider actually tries to read file from there, not from `files/` subdirectory. Thanks for your help! – Kirill Smirnov Aug 30 '19 at 06:42

2 Answers2

0

FileProvider does not support serving content from that location. If you wish to serve directly from that location, you would need to implement your own ContentProvider.

Also, note that a database may be multiple files, particularly if WAL is enabled. getDatabasePath() is from API Level 1, back when WAL did not exist and a SQLite database was always just one file.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
0

FileProvider can access files only in files/ subdirectory, so I copied them there.

Still can't understand, why the error looks like Failed to find, when it should be something like Failed to access.

Also, Room database actually have three files. I got their paths like that:

String dbPath = getDatabasePath(DATABASE_NAME).getAbsolutePath();
String[] dbFiles = {dbPath, dbPath + "-wal", dbPath + "-shm"};
Kirill Smirnov
  • 131
  • 2
  • 12