Android: FileProvider не удалось найти настроенный корень

Я пытаюсь использовать FileProvider для обмена файлом базы данных SQL по электронной почте.

Ошибка:

java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.columbiawestengineering.columbiawest/databases/testresults.db

Мой код:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="test_results" path="databases/"/>
</paths>

Манифест.xml:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.columbiawestengineering.columbiawest"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

Java.код:

    File goob = this.getDatabasePath("testresults.db");
    Log.d("LOG PRINT SHARE DB", "File goob..? getDatabasePath.. here it is: " + goob.toString());

    Uri contentUri = FileProvider.getUriForFile(this, "com.columbiawestengineering.columbiawest", goob);
    Log.d("LOG PRINT SHARE DB", "contentUri got: here is contentUri: " + contentUri.toString());

Кроме того, Logcat для goob показывает правильное местоположение базы данных:

....../com.columbiawestengineering.columbiawest D/LOG PRINT SHARE DB: File goob..? getDatabasePath.. here it is: /data/data/com.columbiawestengineering.columbiawest/databases/testresults.db

Любая помощь?

Из developer.android кажется, что путь к файлам xml... представляет файлы/подкаталог. Но это не то место, где хранится файл. Я в растерянности.


person Dan Lehto    schedule 07.04.2016    source источник


Ответы (2)


Кроме того, Logcat для goob показывает правильное местоположение базы данных:

Да, но <files-path> указывает не на это. Учитывая этот путь к базе данных, эквивалент getFilesDir() будет таким:

/data/data/com.columbiawestengineering.columbiawest/files

Следовательно, ваша база данных не находится в каталоге getFilesDir(), который использует <files-path>, поэтому FileProvider недоволен. FileProvider не поддерживает совместное использование содержимого из каталога базы данных.

person CommonsWare    schedule 07.04.2016
comment
Спасибо CommonsWare, этого я и опасался... Есть ли другой способ получить файл базы данных? Я могу напечатать его в строку и отправить по электронной почте строку, но я пытаюсь отправить по электронной почте фактический файл базы данных. - person Dan Lehto; 07.04.2016
comment
@DanLehto: getDatabasePath() на Context вернет вам объект File, указывающий на вашу базу данных. Вы можете сделать копию файла на getFilesDir() или getCacheDir() для целей FileProvider. Просто убедитесь, что ваша база данных не используется в это время. Или я отправлю обновление на мой StreamProvider в ближайшие несколько дней, где вы должны иметь возможность расширить его для поддержки обслуживания вашей базы данных напрямую. - person CommonsWare; 07.04.2016

Решено (спасибо @CommonsWare). FileProvider не может получить доступ к файлу базы данных SQL, поскольку он находится в каталоге баз данных. Я просто скопировал файл из каталога баз данных в каталог файлов (чтобы FileProvider мог получить к нему доступ), добавил разрешения, прикрепил его к электронной почте, а затем удалил базу данных из каталога файлов при отправке электронной почты с запуском и onActivityForResult() методы.

Моя Java теперь выглядит так:

    //this copies the .db file from dabases dir where FileProvider cannot access it and moves it to files dir
    File booger = copyFileToFilesDir("testresults.db");
    Log.d("LOG PRINT SHARE DB", "we found a booger, Here it is: " + booger.toString());

    Uri contentUri = FileProvider.getUriForFile(this, "com.columbiawestengineering.columbiawest", booger);
    Log.d("LOG PRINT SHARE DB", "contentUri got: here is contentUri: " + contentUri.toString());

и вот что я сделал, чтобы скопировать файл:

private File copyFileToFilesDir(String fileName) {
    File file = null;
    String newPath = getFileStreamPath("").toString();
    Log.d("LOG PRINT SHARE DB", "newPath found, Here is string: " + newPath);
    String oldPath = getDatabasePath("testresults.db").toString();
    Log.d("LOG PRINT SHARE DB", "oldPath found, Her is string: " + oldPath);
    try {
        File f = new File(newPath);
        f.mkdirs();
        FileInputStream fin = new FileInputStream(oldPath);
        FileOutputStream fos = new FileOutputStream(newPath + "/" + fileName);
        byte[] buffer = new byte[1024];
        int len1 = 0;
        while ((len1 = fin.read(buffer)) != -1) {
            fos.write(buffer, 0, len1);
        }
        fin.close();
        fos.close();
        file = new File(newPath + "/" + fileName);
        if (file.exists())
            return file;
    } catch (Exception e) {

    }
    return null;
}
person Dan Lehto    schedule 07.04.2016