Сохранить изображение из внутреннего хранилища в галерею через намерение ACTION_VIEW - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть приложение чата. Если пользователь отправляет изображение, я сохраняю это изображение во внутреннем хранилище приложения в

data/data/package_name/....

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

val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, File(it.localUri))
       val intent = Intent(Intent.ACTION_VIEW).apply {
       flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
       setDataAndType(uri, "image/*")
    }
    startActivity(intent)

Проблема в том, что в программе просмотра изображений нет выбора сохранить файл в хранилище телефона c, в данном случае в галерее. Есть ли способ сделать это, не меняя внутреннее хранилище по умолчанию для сохранения изображений в моем приложении?

1 Ответ

0 голосов
/ 14 февраля 2020

Если это то, что вас интересует, вы можете использовать MediaStore для программного сохранения в галерее изображения из вашего внутреннего хранилища.

Код

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

ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "MyPicture.jpg");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
   contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
}

ContentResolver resolver = myContext.getContentResolver();
Bitmap bitmap;
Uri uri;
try {
   // Requires permission WRITE_EXTERNAL_STORAGE
   bitmap = BitmapFactory.decodeFile(currentPhotoPath);
   uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
} catch (Exception e) {
   Log.e(LOG_TAG, "Error inserting picture in MediaStore: " + e.getMessage());
   return;
}

try (OutputStream stream = resolver.openOutputStream(uri)) {
   if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream) {
      throw new IOException("Error compressing the picture.");
   }
} catch (Exception e) {
   if (uri != null) {
      resolver.delete(uri, null, null);
   }
   Log.e(LOG_TAG, "Error adding picture to gallery: " + e.getMessage());       
}

Кредиты этот ответ для преобразования от File до Bitmap и этот ответ для использования MediaStore.

Примечания

  • BitmapFactory.decodeFile() требует разрешения времени выполнения WRITE_EXTERNAL_STORAGE
  • С введением области памяти в Android 10 (которая станет обязательной в Android 11, см. в этой статье ) MediaStore, вероятно, единственный надежный способ сохранять изображения в галерее
  • Следствием использования области хранения является то, что да, вы должны продолжать использовать внутреннее хранилище для кэш-копии вашей фотографии.

Тесты

Я тестировал этот код с помощью targetSdkVersion 29 на следующих комбинациях устройств / ОС

  • Samsung Galaxy S10 / API 29
  • Samsung Galaxy S9 / API 29
  • Huawei Nexus 6P / API 27
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...