As a matter of fact sometimes we want to share images without saving it. Images from internet or locally generated images.For example whatsapp profile pictures. You can share it, but it’s only visible in gallery when we saved it. However we are using bitmap generated from linear-layout to share.
In fact sharing an image without saving it is by using cache memory. Consequently we can share it like an uri. On the other hand we can simply store the image in cache and use the uri for sharing.
Furthermore we are saving bitmap to cache and use it for sharing. In fact a previous post explain how to convert view to bitmap.Binary data is shared using the ACTION_SEND action combined with setting the appropriate MIME type and placing the URI to the data in an extra named EXTRA_STREAM. This is commonly used to share an image but can be used to share any type of binary content.
You can use a MIME type of "*/*"
, but this will only match activities that are able to handle generic data streams.
In conclusion the receiving application needs permission to access the data the Uri points to.
Similarly we don’t need any special permission to store data in cache memory.
Adding Permission
Add these permissions in the manifest file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
OnClickShare
However below is the onclick method for share button. Create a method with view as argument then specify it in the xml file.
public void OnClickShare(View view){ Bitmap bitmap =getBitmapFromView(idForSaveView); try { File file = new File(this.getExternalCacheDir(),"logicchip.png"); FileOutputStream fOut = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut); fOut.flush(); fOut.close(); file.setReadable(true, false); final Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); intent.setType("image/png"); startActivity(Intent.createChooser(intent, "Share image via")); } catch (Exception e) { e.printStackTrace(); } }
Creating bitmap from view
For instance method creates bitmap from view or any layout extending view.If the background is empty it set’s white color as background.
private Bitmap getBitmapFromView(View view) { Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(returnedBitmap); Drawable bgDrawable =view.getBackground(); if (bgDrawable!=null) { //has background drawable, then draw it on the canvas bgDrawable.draw(canvas); } else{ //does not have background drawable, then draw white background on the canvas canvas.drawColor(Color.WHITE); } view.draw(canvas); return returnedBitmap; }
MainActivity.java
This class file contain both methods, we don’t use onclick listener or implement onclick listener in order to reduce code. Because the click is coded directly to the xml file using onclick.
public class MainActivity extends AppCompatActivity { LinearLayout idForSaveView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); idForSaveView=(LinearLayout)findViewById(R.id.idForSaveView); } public void OnClickShare(View view){ Bitmap bitmap =getBitmapFromView(idForSaveView); try { File file = new File(this.getExternalCacheDir(),"logicchip.png"); FileOutputStream fOut = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut); fOut.flush(); fOut.close(); file.setReadable(true, false); final Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); intent.setType("image/png"); startActivity(Intent.createChooser(intent, "Share image via")); } catch (Exception e) { e.printStackTrace(); } } private Bitmap getBitmapFromView(View view) { Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(returnedBitmap); Drawable bgDrawable =view.getBackground(); if (bgDrawable!=null) { //has background drawable, then draw it on the canvas bgDrawable.draw(canvas); } else{ //does not have background drawable, then draw white background on the canvas canvas.drawColor(Color.WHITE); } view.draw(canvas); return returnedBitmap; } }
activity_main.xml
Still the project require an user interface. Even though below xml file is just for showing how this work.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.logicchip.blog_13_shareimage.MainActivity"> <LinearLayout android:id="@+id/idForSaveView" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher"/> <TextView android:layout_gravity="center" android:textColor="@color/colorAccent" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="logicchip.com"/> </LinearLayout> <Button android:onClick="OnClickShare" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Share"/> </LinearLayout>
this code works fine thank you….. but there is some problem with gmail its showing permission denied
Change getCacheDir() to getExternalCacheDir() also add READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions.
download link is updated.
code is not working for higher vesrions from oreo to android10 please tell me solution for this
New android require permission for accessing that may be the problem. what kind of problem are you facing
how to Share An gif Without Saving it in Android plzz
even i need this
just awesome man keep doing good work i searched for the code to work for 15 days and its working now wow man
what if the images inside layout pass into new activity ?*cuz later i want to fill the attributes likes name, etc and finally upload to firebase* how to pass it ? I need it for my project ~
Convert the image to string using Base64.encodeToString
Working fine for me…how to use it for multiple images on a single or same Activity page…Please help.
I tried to add more IDs but it didn’t work…please help
File file = new File(this.getExternalCacheDir(),”logicchip.png”); this line is for single image,change the name “logicchip.png” for each image.
thanks…this is the code i’m using…I’m certain that there is some fundamental flaw with this…I’m not really an expert…please suggest……………..
package com.fsa.fonline;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import java.io.File;
import java.io.FileOutputStream;
public class ShareImages extends AppCompatActivity {
LinearLayout idForSaveView;
LinearLayout idForSaveView1;
static int CODE_FOR_RESULT=981;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_images);
idForSaveView=(LinearLayout)findViewById(R.id.idForSaveView);
idForSaveView1=(LinearLayout)findViewById(R.id.idForSaveView1);
}
public void OnClickShare(View view){
Bitmap bitmap =getBitmapFromView(idForSaveView);
try {
//File file = new File(this.getExternalCacheDir(),File.separator+ “logicchip.png”);
File file = new File(this.getExternalCacheDir(),”logicchip.png”);
// File file = new File(this.getCacheDir(),File.separator+ “logicchip.png”);
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType(“image/png”);
//startActivity(Intent.createChooser(intent, “Share image via”));
startActivityForResult(Intent.createChooser(intent, “Share image via”),CODE_FOR_RESULT);
} catch (Exception e) {
e.printStackTrace();
}
Bitmap bitmap1 =getBitmapFromView(idForSaveView1);
try {
//File file = new File(this.getExternalCacheDir(),File.separator+ “logicchip.png”);
File file = new File(this.getExternalCacheDir(),”logicchip1.png”);
// File file = new File(this.getCacheDir(),File.separator+ “logicchip.png”);
FileOutputStream fOut = new FileOutputStream(file);
bitmap1.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType(“image/png”);
//startActivity(Intent.createChooser(intent, “Share image via”));
startActivityForResult(Intent.createChooser(intent, “Share image via”),CODE_FOR_RESULT);
} catch (Exception e) {
e.printStackTrace();
}
}
//create bitmap from view and returns it
private Bitmap getBitmapFromView(View view) {
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
//Get the view’s background
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null) {
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
} else{
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
}
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}
}
Wait….its working fine for me now…tried with two images…however, I still feel what I’m doing is not the right way and this is just a hack…please suggest…. Code Below….
package com.fsa.fonline;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import java.io.File;
import java.io.FileOutputStream;
public class ShareImages extends AppCompatActivity {
LinearLayout idForSaveView;
LinearLayout idForSaveView1;
static int CODE_FOR_RESULT=981;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_images);
idForSaveView=(LinearLayout)findViewById(R.id.idForSaveView);
idForSaveView1=(LinearLayout)findViewById(R.id.idForSaveView1);
}
public void OnClickShare(View view) {
Bitmap bitmap = getBitmapFromView(idForSaveView);
try {
//File file = new File(this.getExternalCacheDir(),File.separator+ “logicchip.png”);
File file = new File(this.getExternalCacheDir(), “logicchip.png”);
// File file = new File(this.getCacheDir(),File.separator+ “logicchip.png”);
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType(“image/png”);
//startActivity(Intent.createChooser(intent, “Share image via”));
startActivityForResult(Intent.createChooser(intent, “Share image via”), CODE_FOR_RESULT);
} catch (Exception e) {
e.printStackTrace();
}
}
public void OnClickShare1(View view) {
Bitmap bitmap1 =getBitmapFromView(idForSaveView1);
try {
//File file = new File(this.getExternalCacheDir(),File.separator+ “logicchip.png”);
File file = new File(this.getExternalCacheDir(),”logicchip1.png”);
// File file = new File(this.getCacheDir(),File.separator+ “logicchip.png”);
FileOutputStream fOut = new FileOutputStream(file);
bitmap1.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType(“image/png”);
//startActivity(Intent.createChooser(intent, “Share image via”));
startActivityForResult(Intent.createChooser(intent, “Share image via”),CODE_FOR_RESULT);
} catch (Exception e) {
e.printStackTrace();
}
}
//create bitmap from view and returns it
private Bitmap getBitmapFromView(View view) {
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
//Get the view’s background
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null) {
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
} else{
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
}
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}
}
you can allocate image name “logichip.png in this case” dynamically. Its just a name, may be use your id as image name.
Forgot to mention..THANK YOU!
happy to help
I am loading image in ImageView using Picasso. I want to share that image without saving in android. When I used above code, Picasso might be not loading image and the layout is showing white. What is the solution for that Akhil?
Check permissions, make sure the required permissions are granted. Can you share the screenshots of code, or anything that i can work with ?
I am using Picasso for loading image in ImageView. I want to share that images without saving it. I tried the above code but then Picasso might be not loading image in ImageView. What is the Problem Akhil?
You can use caching for images loaded using Picasso.First try to load the image in to imageview.
LinearLayout idForSaveView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_wallpaper);
idForSaveView=(LinearLayout)findViewById(R.id.idForSaveView);
imageView=(ImageView)findViewById(R.id.imageThumb);
Picasso.with(getBaseContext())
.load(Common.select_background.getImageLink())
.networkPolicy(NetworkPolicy.OFFLINE)
.placeholder( R.drawable.circular_progress_view )
.into(imageView, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError() {
Picasso.with(getBaseContext())
.load(Common.select_background.getImageLink())
.error(R.drawable.ic_image_black_24dp)
.into(imageView, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError() {
Log.e(“ERROR_STATUS”,”Couldn’t load image”);
}
});
}
});
}
public void instaOnClick(View view) {
loadingcardholder.setVisibility(View.VISIBLE);
Bitmap bitmap = getBitmapFromView(idForSaveView);
try {
File file = new File(this.getExternalCacheDir(), “logicchip.png”);
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType(“image/*”);
intent.setPackage(“com.instagram.android”);
try {
startActivity(intent);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), “Instagram App not installed!”, Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
private Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null) {
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
} else{
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return returnedBitmap;
}
//xml
//xml
these are some of important part of the code, please check it.
I have solved it.
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Added this in onCreate() and pass the ImageView in which I am loading the image to the Bitmap getBitmapFromView(View view). And it works!
Thank you so much Akhil ! I was stuck there from last 1 week. Thank you again!
how to send external load image ????
i means that i want send bitmap image / so what changes reqired
simple just load your external image to an imageview,here we are generating bitmap from view.A view can be ImageView,LinearLayout or any other.
Hello:
If I create a qrcode , how can I send qrcode without saving it ?
BarcodeEncoder encoder = new BarcodeEncoder();
try
{
Bitmap bitmap = encoder.encodeBitmap(etContent.getText().toString(), BarcodeFormat.QR_CODE, 1500, 1500);
try
{
File file = new File(this.getExternalCacheDir(),”temp.png”);
is not working..?
maybe by first create qr code load it to an imageview,turn the imageview to
Bitmap bitmap =getBitmapFromView(idForSaveView);
try {
File file = new File(this.getExternalCacheDir(),”logicchip.png”);
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType(“image/png”);
startActivity(Intent.createChooser(intent, “Share image via”));
} catch (Exception e) {
e.printStackTrace();
}
Thanks
getExternalDir(); is not recognized its color is red
this.getExternalCacheDir() is not working its color is red also
try getActivity().getExternalCacheDir()
Not working. I am new to programming. Kindly help.
What seems to be the problem ?
not work in android pi
not working form me
What seems to be the error ?
in that code is some problem that it can not work with android oreo and upper upgraded version
Here you go updated code https://drive.google.com/open?id=1w3ENuWhffN-bKq5cqpFJZprB3CIJTE97
please share the code because its not download
It works for me, but the output image is only from the size of the screen, but my layout is scrollable, and the image is croped. How to take the screenshot of the entire layout?
This code is not working on some android version 7,8 so help to share updated code
Here you go updated code : – https://drive.google.com/file/d/1w3ENuWhffN-bKq5cqpFJZprB3CIJTE97/view?usp=sharing