Как сохранить растровое изображение и поделиться им из кеша?

У меня есть метод, который делится растровым изображением из приложения со сторонними приложениями для социальных сетей. Я пытающийся, чтобы сохранить растровое изображение в папку кеша и поделиться им оттуда. Это мой метод:

public void shareMeme(Bitmap bitmap) {
    String path = Objects.requireNonNull(getContext()).getCacheDir().getAbsolutePath();
    Uri uri = Uri.parse(path);

    Intent share = new Intent(Intent.ACTION_SEND);
    share.setType("image/*");
    share.putExtra(Intent.EXTRA_STREAM, uri);
    share.putExtra(Intent.EXTRA_TEXT, "This is my Meme");
    getContext().startActivity(Intent.createChooser(share, "Share Your Meme!"));

    Toast.makeText(getContext(), "The Cache drive is: " + path, Toast.LENGTH_LONG).show();
}

Метод получает растровое изображение из другого метода через его параметры. Я хочу знать, как включить параметры shareMeme(Bitmap bitmap) в приведенный выше код.

ОБНОВИТЬ

AndroidManifest.xml:

<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:tools = "http://schemas.android.com/tools"
    package = "com.example.omar.memegenerator">

    ...

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

</manifest>

Новый метод shareMeme(Bitmap bitmap):

    public void shareMeme(Bitmap bitmap) {
    String path = Objects.requireNonNull(getContext()).getCacheDir().getAbsolutePath();
    File file = new File(path + "/Memes/" + timeStamp + counter + ".jpg");
    Uri uri = FileProvider.getUriForFile(getContext(), "com.example.omar.memegenerator.fileprovider", file);
    try {
        OutputStream stream = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        stream.flush();
        stream.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    Intent share = new Intent(Intent.ACTION_SEND);
    share.setType("image/*");
    share.putExtra(Intent.EXTRA_STREAM, uri);
    share.putExtra(Intent.EXTRA_TEXT, "This is my Meme");
    share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    getContext().startActivity(Intent.createChooser(share, "Share Your Meme!"));

    Toast.makeText(getContext(), "The Cache drive is: " + path, Toast.LENGTH_LONG).show();
}

Трассировки стека:

2019-04-09 05:08:51.324 19288-19288/com.example.omar.memegenerator E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.omar.memegenerator, PID: 19288
    java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.example.omar.memegenerator/cache/Memes/201904090.jpg
        at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:739)
        at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:418)
        at com.example.omar.memegenerator.TopImageFragment.shareMeme(TopImageFragment.java:232)
        at com.example.omar.memegenerator.TopImageFragment$6.onReceive(TopImageFragment.java:303)
        at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:313)
        at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:121)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6703)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
317
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Шаг № 1: Используйте compress() на Bitmap, чтобы сохранить его в файл в getCacheDir()

Шаг № 2: Добавьте FileProvider в свой проект, настроенный для обслуживания файлов из getCacheDir()

Шаг № 3: Используйте FileProvider.getUriForFile() вместо существующего кода, чтобы получить Uri для вставки EXTRA_STREAM

Шаг № 4. Добавьте Intent.FLAG_GRANT_READ_URI_PERMISSION к Intent перед вызовом startActivity(), чтобы получатель имел права доступа к вашему контенту.

Шаг 2 уже сделан. Я скорректировал свой манифест и добавил res/xml/filespath.xml. Но не знаю, что вы подразумеваете под «настроенным для обслуживания файлов из getCacheDir()»?

Andros Adrianopolos 07.04.2019 20:18

@AndrosAdrianopolos: «Но не знаю, что вы подразумеваете под «настроенным для обслуживания файлов из getCacheDir()?» — res/xml/filespath.xml нужно есть запись <cache-path>. Кроме того, file должен указывать на файл для вашего сохраненного растрового изображения, и в вашем текущем коде он указывает на getCacheDir() себя.

CommonsWare 07.04.2019 20:49

Вот что у меня в filespath.xml: <cache-path name = "shared_images" path = "images/"/> Как мне указать файл на растровое изображение?

Andros Adrianopolos 07.04.2019 21:04

@AndrosAdrianopolos: выберите имя файла. Создайте объект File, указывающий на это имя файла внутри getCacheDir(). Создайте на нем FileOutputStream и используйте его для compress(). И передайте это FilegetUriForFile().

CommonsWare 07.04.2019 21:05

Привет. Если бы вы могли проверить обновление, я опубликовал обновленный метод и трассировку стека. Я пытался объявить файл с путем, но через ошибку.

Andros Adrianopolos 09.04.2019 11:10

@AndrosAdrianopolos: Согласно предыдущему комментарию, у вас есть <cache-path name = "shared_images" path = "images/"/>. Это обслуживает файлы из подкаталога images/ в getCacheDir(). Это не то место, где находится ваш файл. Он находится в каталоге Memes/ под getCacheDir(). Этим нужно соответствовать.

CommonsWare 09.04.2019 12:56

Я сделал, и это остановило крах. Но теперь, когда я пытаюсь поделиться мемом, ничего не появляется на Facebook, Twitter и т. д.

Andros Adrianopolos 10.04.2019 02:39

Другие вопросы по теме