Многие критические изменения происходят в Android Q, когда дело доходит до управления хранилищем, и одна из моих функций в приложении - позволить пользователю сделать снимок в View
подобном CardView
элементе, создать Bitmap
об этом и сохраните это в памяти устройства. Когда сохранение будет завершено, оно вызовет Intent.ACTION_SEND
, чтобы пользователь мог поделиться недавно сохраненным изображением с некоторым описанием в социальных приложениях и создать электронное письмо с GMail.
Этот фрагмент кода работает отлично.
try {
//Get primary storage status
String state = Environment.getExternalStorageState();
File filePath = new File(view.getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + "Shared");
if (Environment.MEDIA_MOUNTED.equals(state)) {
try {
if (filePath.mkdirs())
Log.d("Share Intent", "New folder is created.");
} catch (Exception e) {
e.printStackTrace();
Crashlytics.logException(e);
}
}
//Create a new file
File imageFile = new File(filePath, UUID.randomUUID().toString() + ".png");
//Create bitmap screen capture
Bitmap bitmap = Bitmap.createBitmap(loadBitmapFromView(view));
FileOutputStream outputStream = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.flush();
outputStream.close();
Toast.makeText(view.getContext(), "Successfully save!", Toast.LENGTH_SHORT).show();
shareToInstant(description, imageFile, view);
} catch (IOException e) {
e.printStackTrace();
Crashlytics.logException(e);
}
Но это сохранит файл изображения в /storage/emulated/0/Android/data/YOUR_APP_PACKAGE_NAME/files/Pictures
.
. Я хочу сохранить их, как большинство приложений, в папке «Изображения» по умолчанию в root /storage/emulated/0/Pictures
, чтобы изображение было Gallery .
. Для этого я изменяю приведенный выше фрагмент кода на этот.
//Create bitmap screen capture
Bitmap bitmap = Bitmap.createBitmap(loadBitmapFromView(view));
final String relativeLocation = Environment.DIRECTORY_PICTURES + "/" + view.getContext().getString(R.string.app_name);
final ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, UUID.randomUUID().toString() + ".png");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
final ContentResolver resolver = view.getContext().getContentResolver();
OutputStream stream = null;
Uri uri = null;
try {
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
uri = resolver.insert(contentUri, contentValues);
if (uri == null || uri.getPath() == null) {
throw new IOException("Failed to create new MediaStore record.");
}
stream = resolver.openOutputStream(uri);
if (stream == null) {
throw new IOException("Failed to get output stream.");
}
if (!bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)) {
throw new IOException("Failed to save bitmap.");
}
//If we reach this part we're good to go
Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File imageFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), contentValues.getAsString(MediaStore.MediaColumns.DISPLAY_NAME));
Uri fileContentUri = Uri.fromFile(imageFile);
mediaScannerIntent.setData(fileContentUri);
view.getContext().sendBroadcast(mediaScannerIntent);
shareToInstant(description, imageFile, view);
} catch (IOException e) {
if (uri != null) {
// Don't leave an orphan entry in the MediaStore
resolver.delete(uri, null, null);
}
e.printStackTrace();
Crashlytics.logException(e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
Crashlytics.logException(e);
}
}
}
Также работал, но не смог прикрепить / поделиться изображением с другим приложением, таким как GMail, также считается, что Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
устарел, так что мне интересно, как это сделать сейчас, так как я уже пробовал многочисленные исследования для этого, но не повезло найти подобное Сценарий по этому вопросу.
Это мой FileProvider выглядит так.
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<cache-path
name="cache"
path="." />
<external-cache-path
name="external_cache"
path="." />
<files-path
name="files"
path="." />
</paths>
Это мой фрагмент для намеренного обмена.
private static void shareToInstant(String content, File imageFile, View view) {
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/png");
sharingIntent.setType("text/plain");
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sharingIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
sharingIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(view.getContext(), BuildConfig.APPLICATION_ID + ".provider", imageFile));
sharingIntent.putExtra(Intent.EXTRA_TEXT, content);
try {
view.getContext().startActivity(Intent.createChooser(sharingIntent, "Share it Via"));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(view.getContext(), R.string.unknown_error, Toast.LENGTH_SHORT).show();
}
}