I am making a drawing app. Now i want to share my Drawing with share option menu. But drawing canvas image is not attaching while sharing.
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/menu_item_share"
android:showAsAction="ifRoom"
android:title="Share"
android:actionProviderClass=
"android.widget.ShareActionProvider"/>
Following is a code of java file
public boolean onCreateOptionsMenu(Menu menu) {
/** Inflating the current activity's menu with res/menu/items.xml */
getMenuInflater().inflate(R.menu.share_menu, menu);
/** Getting the actionprovider associated with the menu item whose id is share */
mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_item_share).getActionProvider();
/** Setting a share intent */
mShareActionProvider.setShareIntent(getDefaultShareIntent());
return super.onCreateOptionsMenu(menu);
}
private Intent getDefaultShareIntent(){
Bitmap bitmap = drawView.getDrawingCache();
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + UUID.randomUUID().toString()+".png";
File file = new File(path+"/image.png");
System.out.println("path="+path);
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = Uri.parse(path);
//Uri screenshotUri = Uri.fromFile(file);
sharingIntent.setType("image/png");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
startActivity(Intent.createChooser(sharingIntent, "Share image using"));
return sharingIntent;
}
Please provide me the way to share canvas image with different apps. Thank you
I know it's a late reply. But this may help someone. Here is the code that worked for me.
private Intent getDefaultShareIntent(){
// Save image to external storage before sending. With out saving, I to got a blank screen as attachment.
String imagePath=saveToExternalSorage(mBitmap);
File f=new File(imagePath);
Uri screenshotUri = Uri.fromFile(f);
//Create an intent to send any type of image
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/*");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
startActivity(Intent.createChooser(sharingIntent, "Share image using"));
return sharingIntent;
}
where
public String saveToExternalSorage(Bitmap b){
// Get path to External Storage
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/"+IMAGE_PATH);
myDir.mkdirs();
// Generating a random number to save as image name
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String timeStamp = new SimpleDateFormat("yyyyMMdd").format(new Date());
String fname = "Image_"+timeStamp+"_"+ n + ".jpg";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
// Tell your media scanner to refresh/scan for new images
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
System.out.println(path);
}
});
return file.getAbsolutePath();
}
I wonder, saving the image before is the only way to share properly.
Related
I am trying to get a image of a view (constraint-layout) and share it via an android send-intent.
I tried a lot of methods, but until now none have worked.
This is what I have so far:
public void shareStatsImage(){
constraintLayout.setDrawingCacheEnabled(true);
Bitmap bitmap = constraintLayout.getDrawingCache();
File path = null;
try {
path = saveImageToExternal(generateImageTitle(), bitmap);
} catch (IOException e) {
e.printStackTrace();
}
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/png");
final File photoFile = new File(Objects.requireNonNull(getActivity()).getFilesDir(), Objects.requireNonNull(path).getAbsolutePath());
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(photoFile));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "Share image using"));
}
public static String generateImageTitle(){
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss");
return sdf.format(new Date());
}
public File saveImageToExternal(String imgName, Bitmap bm) throws IOException {
//Create Path to save Image
String appFolder = "test";
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + File.separator + appFolder); //Creates app specific folder
path.mkdirs();
File imageFile = new File(path, imgName+".png"); // Imagename.png
FileOutputStream out = new FileOutputStream(imageFile);
try{
bm.compress(Bitmap.CompressFormat.PNG, 100, out); // Compress Image
out.flush();
out.close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(getContext(),new String[] { imageFile.getAbsolutePath() }, null,new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
} catch(Exception e) {
throw new IOException();
}
return imageFile;
}
There are multiple problems with this solution, for example I am getting an error message ("Permission denied for the attachment") when sharing the image to gmail. When uploading the image to google drive I only get an "upload unsuccessful message".
One good thing is that the images seem to appear in the phone's gallery, just not when sharing them via the intent :(
Thanks for your help!
Convert Bitmap to Uri
private Uri getImageUri(Context context, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Image Title", null);
return Uri.parse(path);
}
You can send Image using Uri.
Uri imageUri = set your image Uri;
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
shareIntent.setType("image/jpeg");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "send"));
I am trying to convert entire CardView into an Image and then I want to share it using different apps.
PROBLEM
cardView.setDrawingCacheEnabled(true);
cardView.measure(View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED));
cardView.layout(0,0, cardView.getMeasuredWidth(), cardView.getMeasuredHeight());
cardView.buildDrawingCache(true);
bitmap = Bitmap.createBitmap(cardView.getDrawingCache());
cardView.setDrawingCacheEnabled(false);
String path = MediaStore.Images.Media.insertImage(DetailedActivity.this.getContentResolver(),bitmap,"quote",null);
uri = Uri.parse(path);
Thing is I am getting cardview converted into bitmap but while getting uri from bitmap it is returning null path. so while converting Uri it is giving NULL POINTER EXCEPTION.
Below is the list of permissions I provided.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"
tools:ignore="ProtectedPermissions" />
CardView XML
If I give the CardView a defined hardcoded values for Height and Width of a CardView it is working but when I use
android:layout_width="match_parent"
android:layout_height="match_parent"
With the code shown above it is giving NULL_POINTER_EXCEPTION.
QUERIES
1. How can I make it work?
2. Is there any other way to do this?
So if I get it right, the URI path is stored in uri variable. The null error happens because you didn't initialise that uri string. You can do this:
String uri = new String() // -> if there is still an error here, replace String() with String(this) or String(activity_your_name.this)
Intent intent = new Intent(this, activity_output.class); // -> here you add the activity where you send the URI to
intent.putExtra("URI", uri);
and on the other activities you extract the URI through:
//Getting the URI from previous activity:
path = getIntent().getExtra("URI");
//Initialising the File form your URI
File StringToBitmap = new File;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
StringToBitmap = new File(path, String.valueOf(options));
//Your bitmap will be stored in mBitmaps
mBitmaps = BitmapFactory.decodeFile(path);
//The next part is extra, if you want to display your bitmap into an ImageView
ImageView iv = new ImageView();
iv = findViewById(R.id.your_id);
iv.setImageBitmap(mBitmaps);
This code worked to me for something very similar. And about that NULL EXCEPTION, every time you get it, try to see if you initialised all your objects correctly. Hope this helps.
Try This:
public Bitmap getScreenShot(View view) {
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return bitmap;
}
public void onShareImage(Bitmap bitmap) {
#SuppressLint("SimpleDateFormat") String fileName = "IMG_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".PNG";
storeScreenShot(bitmap, fileName);
Uri imgUri = Uri.fromFile(new File(VarName.SCREENSHOT_DIRECTORY + "/" + fileName));
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, imgUri);
shareIntent.putExtra(Intent.EXTRA_TEXT, VarName.DRESS_ME_SHARE_MASSAGE_HEADER + "\n" + VarName.DRESS_ME_SHARE_APP_LINK);
startActivity(Intent.createChooser(shareIntent, "Share Image"));
}
public void storeScreenShot(Bitmap bm, String fileName) {
File dir = new File(VarName.SCREENSHOT_DIRECTORY);
if (!dir.exists()) {
dir.mkdirs();
File file = new File(dir.getAbsolutePath(), ".nomedia");
try {
file.createNewFile();
final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
final Uri contentUri = Uri.fromFile(file);
scanIntent.setData(contentUri);
sendBroadcast(scanIntent);
} catch (IOException e) {
e.printStackTrace();
}
}
File file = new File(VarName.SCREENSHOT_DIRECTORY, fileName);
try {
FileOutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.createNewFile();
final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
final Uri contentUri = Uri.fromFile(file);
scanIntent.setData(contentUri);
sendBroadcast(scanIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
Now you Just need to call function.
Bitmap bitmap = getScreenShot(cardView);
onShareImage(bitmap);
i want working on sharing .gif with available apps like whatsapp, but unable to get valid Uri of gif present in my drawable resource.
Uri path = Uri.parse("android.resource://my_package_name/" + R.drawable.gif_1);
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/gif");
shareIntent.putExtra(Intent.EXTRA_STREAM, path);
there is lot of solution on sharing images but no solution on gif sharing, Please help
I found my answer, I just created a file with a .gif extension and it worked for me. See the code below:
private void shareGif(String resourceName){
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "sharingGif.gif";
File sharingGifFile = new File(baseDir, fileName);
try {
byte[] readData = new byte[1024*500];
InputStream fis = getResources().openRawResource(getResources().getIdentifier(resourceName, "drawable", getPackageName()));
FileOutputStream fos = new FileOutputStream(sharingGifFile);
int i = fis.read(readData);
while (i != -1) {
fos.write(readData, 0, i);
i = fis.read(readData);
}
fos.close();
} catch (IOException io) {
}
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/gif");
Uri uri = Uri.fromFile(sharingGifFile);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(shareIntent, "Share Emoji"));
}
if you want to take image from internal storage.
//this is method having internal storage path.
private String getFilePath2() {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/Gifs temp/");
if (!myDir.exists())
myDir.mkdirs();
String fname = "temp_gif";
SimpleDateFormat timeStampFormat = new SimpleDateFormat(
"yyyyMMdd_HHmmss");
Date myDate = new Date();
String filename = timeStampFormat.format(myDate);
File file = new File(myDir, fname + "_" + filename + ".gif");
if (file.exists()) {
file.delete();
}
String str = file.getAbsolutePath();
return str;
}
// Then take image from internal storage into the string.
String st = getFilePath2();
//And share this by this intent
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/gif");
Uri uri = Uri.fromFile(sharingGifFile);
shareIntent.putExtra(Intent.EXTRA_STREAM,
uri);
startActivity(Intent.createChooser(shareIntent, "Share Emoji"));
I am trying to share an image to other apps.
From the doc, I understand I have to create a ContentProvider to ensure access to my resource from outside the app. It works with most apps but Facebook Messenger and Messages (com.android.mms). I have the following errors:
FB Messenger: "Sorry, messenger was unable to process the file"
com.android.mms: "Unable to attach. File not supported"
The code I call in the activity to share:
Uri path = Uri.parse("content://com.myauthority/test.png");
Intent shareIntent = new Intent(Intent.ACTION_SEND).putExtra(Intent.EXTRA_STREAM, path).setType("image/png");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.share)));
The in my content provider I only override openFile:
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
String fileName = uri.getLastPathSegment();
String resName = fileName.replaceAll(".png","");
int resId = getContext().getResources().getIdentifier(resName,"drawable",getContext().getPackageName());
File file = new File(getContext().getCacheDir(), fileName);
Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), resId);
FileOutputStream fileoutputstream = new FileOutputStream(file);
boolean flag = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileoutputstream);
try {
ParcelFileDescriptor parcelfiledescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY | ParcelFileDescriptor.MODE_WORLD_READABLE);
return parcelfiledescriptor;
} catch (IOException e) {
e.printStackTrace();
return null;
}
Has anyone an idea or experience to share regarding this issue?
Here am Including my code which i used to share data from my app to facebook app or messenger app.
imageView.setDrawingCacheEnabled(true);
Bitmap bitmap = imageView.getDrawingCache();
File root = Environment.getExternalStorageDirectory();
final File cachePath = new File(root.getAbsolutePath()
+ "/DCIM/Camera/Avi.jpg");
try {
cachePath.createNewFile();
FileOutputStream ostream = new FileOutputStream(
cachePath);
bitmap.compress(CompressFormat.JPEG, 100, ostream);
ostream.flush();
ostream.close();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(
Intent.EXTRA_STREAM,
Uri.fromFile(new File(cachePath
.getAbsolutePath())));
Log.e("Path for sending ",
""+Uri.fromFile(new File(cachePath
.getAbsolutePath())));
mContext.startActivity(intent);
}
}, 3000);
just provide your image uri and use this code.
I´ve been struggling with this for a few days now and other answers posted in similar questions here on stackoverflow haven´t helped me.
What I want to do is set a custom ArrayAdapter to my ListView and inside this adapter I want to set an onClickListener to a button that appears in every item. Then I want the user to pick whether he wants to take a picture with the camera or choose a picture from the gallery. Then I want the picture to save in the app´s own folder inside Gallery. However, although the custom folder is created and visible in Gallery, the picture itself is stored in the Camera folder and I can see a broken file in the custom folder.
I´ve read photobasics on the devsite http://developer.android.com/training/camera/photobasics.html, but it did not help much.
I implemented the onActivityResult inside my Fragment but the Uri path is different fro the one created in the adapter.
Here is the code:
In ArrayAdapter:
photoPicker.setOnClickListener(new View.OnClickListener()
{
#Override public void onClick(View v)
{
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = mContext.getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam)
{
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Vyber zdroj");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
if (chooserIntent.resolveActivity(mContext.getPackageManager()) != null)
{
// Create the File where the photo should go
File photoFile = null;
try
{
photoFile = createImageFile();
}
catch (IOException ex)
{
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null)
{
chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
Log.i(TAG,"uri from file:"+Uri.fromFile(photoFile).toString());
chooserIntent.putExtra("path",mCurrentPhotoPath);
fragment.startActivityForResult(chooserIntent, FlowListUtils.getIdFromDate(experience.getDate()));
}
}
}
});
private File createImageFile() throws IOException
{
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
String storagePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getPath()+"/MyApp";
File storageDir = new File(storagePath);
storageDir.mkdirs();
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
Log.i(TAG,"mCurrent Photo Path in adapter:"+mCurrentPhotoPath);
return image;
}
This code is in my Fragment
#Override public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
ExperienceAdapter.dateForPicture = requestCode;
ExperienceAdapter.uriForPicture = data.getData();
galleryAddPic(path);
}
private void galleryAddPic(String path)
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(ExperienceAdapter.mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
getActivity().sendBroadcast(mediaScanIntent);
}
The path I add to the intent is file:/storage/emulated/0/Pictures/MyApp/JPEG_20140626_133228_1332202116.jpg
but suddenly changes to content://media/external/images/media/6273 in the Intent return by onActivityResult.
Where am I going wrong?
Here is the function to save the Image,
public static String saveImageInExternalCacheDir(Context context, Bitmap bitmap, String myfileName) {
String fileName = myfileName.replace(' ', '_') + getCurrentDate().toString().replace(' ', '_').replace(":", "_");
String filePath = (context.getExternalCacheDir()).toString() + "/" + fileName + ".jpg";
try {
FileOutputStream fos = new FileOutputStream(new File(filePath));
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
You have a really good example here -> Taking Photos Simply.
When you go save with createImageFile function you can choose your directory url:
private File createImageFile() throws IOException {
// Create an image file name
timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);]
File image = File.createTempFile(
imageFileName,
".jpg",
storageDir
);
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
I think this is what you need!