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

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

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

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

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

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

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

 ...  ...    ...   

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

Создание res / xml / filepaths.xml

   

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

 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")); } 

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

  • FileProvider
  • Варианты хранения - Внутреннее хранилище
  • Совместное использование файлов
  • Сохранение файлов

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

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

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

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

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

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

Это для совместного использования 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();} } }); 

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

Чтобы исправить bitmap, не обновляющее проблему, я улучшил ответ Сурагха , используя комментарий Гурупада Мамадапура и добавил собственные изменения.


Вот код на языке Котлин :

 private lateinit var myRootView:View // root view of activity @SuppressLint("SimpleDateFormat") private fun shareScreenshot() { // We need date and time to be added to image name to make it unique every time, otherwise bitmap will not update val sdf = SimpleDateFormat("yyyyMMdd_HHmmss") val currentDateandTime = sdf.format(Date()) val imageName = "/image_$currentDateandTime.jpg" // CREATE myRootView = window.decorView.rootView myRootView.isDrawingCacheEnabled = true myRootView.buildDrawingCache(true) // maybe You dont need this val bitmap = Bitmap.createBitmap(myRootView.drawingCache) myRootView.isDrawingCacheEnabled = false // SAVE try { File(this.cacheDir, "images").deleteRecursively() // delete old images val cachePath = File(this.cacheDir, "images") cachePath.mkdirs() // don't forget to make the directory val stream = FileOutputStream("$cachePath$imageName") bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream) // can be png and any quality level stream.close() } catch (ex: Exception) { Toast.makeText(this, ex.javaClass.canonicalName, Toast.LENGTH_LONG).show() // You can replace this with Log.e(...) } // SHARE val imagePath = File(this.cacheDir, "images") val newFile = File(imagePath, imageName) val contentUri = FileProvider.getUriForFile(this, "com.example.myapp.fileprovider", newFile) if (contentUri != null) { val shareIntent = Intent() shareIntent.action = Intent.ACTION_SEND shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // temp permission for receiving app to read this file shareIntent.type = "image/jpeg" // just assign type. we don't need to set data, otherwise intent will not work properly shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri) startActivity(Intent.createChooser(shareIntent, "Choose app")) } } 

Если кто-то все еще ищет легкое и короткое решение без разрешения на хранение (также поддерживает nougat 7.0). Вот.

Добавьте это в манифест

    

Теперь создайте provider_paths.xml

    

Наконец добавьте этот метод в свою активность / fragment (rootView – это представление, которое вы хотите поделиться)

  private void ShareIt(View rootView){ if (rootView != null && context != null && !context.isFinishing()) { rootView.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap(rootView.getDrawingCache()); if (bitmap != null ) { //Save the image inside the APPLICTION folder File mediaStorageDir = new File(AppContext.getInstance().getExternalCacheDir() + "Image.png"); try { FileOutputStream outputStream = new FileOutputStream(String.valueOf(mediaStorageDir)); bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); outputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (ObjectUtils.isNotNull(mediaStorageDir)) { Uri imageUri = FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".provider", mediaStorageDir); if (ObjectUtils.isNotNull(imageUri)) { Intent waIntent = new Intent(Intent.ACTION_SEND); waIntent.setType("image/*"); waIntent.putExtra(Intent.EXTRA_STREAM, imageUri); startActivity(Intent.createChooser(waIntent, "Share with")); } } } } } 
  • как я могу отправить данные из onPostExecute в AsyncTask?
  • Как получить список установленных приложений для Android и выбрать один для запуска
  • Android - Как перехватить намерение «Установить приложение»
  • Как получить дополнительные данные от намерения на Android?
  • Intent не устанавливает параметры камеры
  • Учет целей
  • Что такое намерение в Android?
  • Не удалось запустить служебный
  • Android: Как открыть конкретную папку через Intent и показать ее содержимое в файловом браузере?
  • Как открыть личные файлы, сохраненные во внутреннем хранилище с помощью Intent.ACTION_VIEW?
  • Android: запуск активности для другого стороннего приложения
  • Interesting Posts

    Когда утверждения должны оставаться в производственном коде?

    Как я могу попасть в контейнер Docker?

    Получить позицию курсора в Android в редакторе текста?

    Цветная копия окна PuTTY

    Почему мой Macbook становится очень жарким при использовании Boot Camp?

    Tensorflow NaN ошибка?

    Вызов камеры из активности, захват изображения и загрузка на сервер

    Советы по созданию «Контекстная свободная грамматика»

    Переопределение переменных экземпляра суперclassа

    Я случайно подключил USB-мышь к своему порту eSata … он работает?

    Почему не может быть -z быть последним вариантом командной строки, который будет использоваться с tar?

    Каковы некоторые настройки аудио / звуковой карты / драйвера, которые все еще позволяют вам «записывать то, что вы слышите»?

    Соглашение об именовании C # для свойства enums и соответствия

    Мониторинг полосы пропускания через несколько систем в домашней сети

    TW700 не загружается с USB или microSD

    Давайте будем гением компьютера.