Подтвердить что ты не робот

Android Share Intent для растрового изображения - возможно ли сохранить его ранее?

Я пытаюсь экспортировать растровое изображение из своего приложения, используя намерение совместного использования, не сохраняя файл для временного местоположения. Все примеры, которые я нашел, являются двухэтапными 1) сохранить на SD-карту и создать Uri для этого файла 2) начать с этого Uri

Можно ли сделать это, не требуя разрешения WRITE_EXTERNAL_STORAGE, сохраняя файл [и удаляя его потом]? Как обращаться к устройствам без ExternalStorage?

4b9b3361

Ответ 1

У меня была такая же проблема. Я не хотел просить разрешения на чтение и запись внешних хранилищ. Кроме того, иногда возникают проблемы, когда телефоны не имеют SD-карт или карты размонтируются.

В следующем методе ContentProvider используется FileProvider. Технически вы до сих пор сохраняете растровое изображение (во внутреннем хранилище) перед совместным использованием, но вам не нужно запрашивать какие-либо разрешения. Кроме того, каждый раз, когда вы делитесь растровым изображением, файл изображения перезаписывается. И поскольку он находится во внутреннем кеше, он будет удален, когда пользователь удалит приложение. Так что, на мой взгляд, это так же хорошо, как не сохранение изображения. Этот метод также более безопасен, чем сохранение его на внешнем хранилище.

Документация неплохая (см. Дополнительное чтение ниже), но некоторые части немного сложны. Вот резюме, которое сработало для меня.

Настройте FileProvider в манифесте

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

Замените com.example.myapp на ваше имя пакета приложений.

Создать файл res/xml/filepaths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="shared_images" path="images/"/>
</paths>

Это сообщает FileProvider, куда следует делить файлы (используя в этом случае каталог кэша).

Сохранить изображение во внутреннем хранилище

// save bitmap to cache directory
try {

    File cachePath = new File(context.getCacheDir(), "images");
    cachePath.mkdirs(); // don't forget to make the directory
    FileOutputStream stream = new FileOutputStream(cachePath + "/image.png"); // overwrites this image every time
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    stream.close();

} catch (IOException e) {
    e.printStackTrace();
}

Поделитесь изображением

File imagePath = new File(context.getCacheDir(), "images");
File newFile = new File(imagePath, "image.png");
Uri contentUri = FileProvider.getUriForFile(context, "com.example.myapp.fileprovider", newFile);

if (contentUri != null) {
    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file
    shareIntent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
    shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
    startActivity(Intent.createChooser(shareIntent, "Choose an app"));
}

Дальнейшее чтение

Ответ 2

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

В теории это возможно. На практике это, вероятно, невозможно.

В теории все, что вам нужно сделать, это Uri, который разрешит растровое изображение. Самый простой подход - это тот файл, который напрямую доступен другому приложению, например, на внешнем хранилище.

Чтобы не записывать его во Flash, вам нужно будет реализовать свой собственный ContentProvider, выяснить, как реализовать openFile(), чтобы вернуть растровое изображение в памяти, а затем передать Uri, представляющий это растровое изображение в ACTION_SEND Intent. Поскольку openFile() должен возвращать ParcelFileDescriptor, я не знаю, как вы это сделаете без представления на диске, но я не потратил много времени на поиск.

Можно ли сделать это, не требуя разрешения WRITE_EXTERNAL_STORAGE, сохраняя файл [и удаляя его потом]?

Если вы просто не хотите его на внешнем хранилище, вы можете перейти по маршруту ContentProvider, используя файл на внутренней памяти. Этот примерный проект демонстрирует ContentProvider, который обслуживает файл PDF через ACTION_VIEW в программу просмотра PDF на устройстве; такой же подход можно использовать для ACTION_SEND.

Ответ 3

Это для совместного использования CardView в качестве изображения, затем сохраните его в подкаталоге кэша внутренней области хранения приложения. надеюсь, что это будет полезно.

        @Override
        public void onClick(View view) {

            CardView.setDrawingCacheEnabled(true);
            CardView.buildDrawingCache();
            Bitmap bitmap = CardView.getDrawingCache();

            try{
                File file = new File(getContext().getCacheDir()+"/Image.png");
                bitmap.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(file));
                Uri uri = FileProvider.getUriForFile(getContext(),"com.mydomain.app", file);

                Intent shareIntent = new Intent();
                shareIntent.setAction(Intent.ACTION_SEND);
                shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
                shareIntent.setType("image/jpeg");
                getContext().startActivity(Intent.createChooser(shareIntent, "Share"));

            }catch (FileNotFoundException e) {e.printStackTrace();}

        }
    });