This is what worked for me even on Android 11. It based on this Android documentation: https://developer.android.com/training/data-storage/shared/media. In my usecase, I needed to share an image generated from converting a layout to a bitmap. I had to first save the image to shared media storage but I believe private storage should work as as well.
public void shareImage(Bitmap bitmap) {
Uri contentUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
ContentResolver contentResolver = getApplicationContext().getContentResolver();
ContentValues newImageDetails = new ContentValues();
newImageDetails.put(MediaStore.Images.Media.DISPLAY_NAME, "filename");
Uri imageContentUri = contentResolver.insert(contentUri, newImageDetails);
try (ParcelFileDescriptor fileDescriptor =
contentResolver.openFileDescriptor(imageContentUri, "w", null)) {
FileDescriptor fd = fileDescriptor.getFileDescriptor();
OutputStream outputStream = new FileOutputStream(fd);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bufferedOutputStream);
bufferedOutputStream.flush();
bufferedOutputStream.close();
} catch (IOException e) {
Log.e(TAG, "Error saving bitmap", e);
}
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, imageContentUri);
sendIntent.putExtra(Intent.EXTRA_TEXT, "some text here");
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.setType("image/*");
Intent shareIntent = Intent.createChooser(sendIntent, "Share with");
startActivity(shareIntent);
}