Ответ 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"));
}