Флаттер намерен поделиться имиджем - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь поделиться изображением с помощью классического Intent. Я добавил следующие предметы:

file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="." />
</paths>

Манифест:

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

И, наконец, MainActivity.java:

private void shareFile(String fileName) {
        Intent share = new Intent(Intent.ACTION_SEND);
        Uri uri = FileProvider.getUriForFile(this, "com.example.android.fileprovider", new File(this.getApplicationInfo().dataDir + "/app_flutter/userphotos", fileName));
        share.setData(uri);
        share.setType("image/png");
        share.putExtra(Intent.EXTRA_STREAM, uri);
        share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(Intent.createChooser(share, "Share"));
    }

Проблема, с которой я сталкиваюсь, заключается в том, что изображение, которым я пытаюсь поделиться, имеет следующий путь:

* * Тысяча двадцать-один / данных / пользователь / 0 / shoedrobe.innovativeproposals.com.shoedrobe / app_flutter / userphotos / receipt20181101094430.jpg

Однако FileProvider пытается получить доступ к нему отсюда:

java.lang.IllegalArgumentException: не удалось найти настроенный root который содержит /data/data/shoedrobe.innovativeproposals.com.shoedrobe/app_flutter/userphotos/receipt20181101094430.jpg

Для сохранения изображений я использую пакет path_provider и сохраняю элементы в getApplicationDocumentsDirectory(), который в Android является каталогом AppData.

Я не уверен, почему FileProvider решил внезапно перейти из папки /data/user/0/ в /data/data/, поэтому любая помощь или советы по этому вопросу будут высоко оценены.

Обновление:
Я обновил код согласно рекомендациям и заменил Uri в MainActivity.java следующей строкой:

Uri uri = FileProvider.getUriForFile(this, "com.example.android.fileprovider", new File(this.getDir("flutter", Context.MODE_PRIVATE).getPath() + "/app_flutter/userphotos", path));

Тем не менее, проблема все еще сохраняется (за исключением того, что файл должен иметь значение /data/data/<package> вместо /data/user/0. Я также попытался добавить дополнительные разрешения в мой AndroidManifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

но это не сработало. Может ли быть проблема с моим file_paths.xml файлом?

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

В итоге ни одно из предложенных решений не сработало; ни используя extenal-path, ни другое решение.

В конце концов мне удалось поделиться файлом, сначала скопировав его во временный (кеш) каталог (во флаттере path_provider это getTemporaryDirectory()) и обновив file_paths.xml до следующего:

<cache-path name="image" path="."/>

и, наконец, под MainActivity.java:

Uri uri = FileProvider.getUriForFile(this, "com.example.android.fileprovider", new File(this.getCacheDir(), path));
0 голосов
/ 09 ноября 2018

Под капотом Флаттер getApplicationDocumentsDirectory() использует getDir() вместо dataDir, что может отличаться.

Из документации Android по getDataDir(), что эквивалентно this.getApplicationInfo().dataDir:

Возвращает абсолютный путь к каталогу в файловой системе, где хранятся все личные файлы, принадлежащие этому приложению. Приложения не должны использовать этот путь напрямую ; вместо этого они должны использовать getFilesDir (), getCacheDir (), getDir (String, int) или другие API хранилища для этого класса.

Возвращенный путь может со временем измениться , если вызывающее приложение перемещено на принятое устройство хранения, поэтому должны сохраняться только относительные пути.

Поэтому, чтобы обеспечить согласованность между каталогом, используемым для сохранения изображений Flutter, и каталогом, используемым для извлечения файлов через FileProvider, строку getUriForFile в MainActivity.java можно изменить следующим образом:

FileProvider.getUriForFile(this, "com.example.android.fileprovider", new File(<your application context>.getDir("flutter", Context.MODE_PRIVATE).getPath() + "/app_flutter/userphotos", fileName));

... заменив <your application context> переменной, хранящей контекст вашего приложения, если есть.

...