In my app, I have an option to share photos using standard Android sharing mechanism. When I choose gmail or yahoo mail, the sharing works, the images are displayed in the body of an email and are sent to the destination. When I choose Facebook, the images are displayed inside the Facebook activity where you can add a message, but when I hit the Done button, the upload process starts, but always fails.
The title of the message box is: "Facebook Upload Failed" and the message itself is: "Your upload could not be completed because we could not access your photo(s)."
Here is the code snippet for sharing:
mShareIntent = new Intent();
mShareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
mShareIntent.setType("image/jpeg");
mShareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ArrayList<Uri> uris = new ArrayList<Uri>();
for(int i = 0; i < mImageUrls.size(); i++) {
uris.add(Uri.parse("file://"+mShareFiles[i].getAbsolutePath()));
}
mShareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(Intent.createChooser(mShareIntent, "Share Images To..."))
The photos are obviously accessible, since they are successfully processed by gmail and yahoo mail. And Facebook, itself, can access them, but not sent them.
As an experiment, I shared photos from the Android Gallery, in the Chooser, I chose Facebook, and the photos were successfully uploaded.
Does anyone have any idea what might be going on?
Thank You,
Gary
If the file is in your app's private directory (or even in its sd card directory in KitKat) then you might run into sharing issues. And FileProvider has its problems too.
The only reliable way I've found to share image files is to copy them to the external storage directory for pictures and sharing from there (you can create a .nomedia subdirectory to avoid them appearing in the Gallery app).
For example:
Bitmap bitmapToShare = ...
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
File pictureStorage = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File noMedia = new File(pictureStorage, ".nomedia");
if (!noMedia.exists())
noMedia.mkdirs();
File file = new File(noMedia, "shared_image.png");
saveBitmapAsFile(bitmapToShare, file);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
shareIntent.setType("image/png");
startActivity(shareIntent);
}
Related
I have implemented the following code to share video:
// Copy video file to Fileprovider directory.
final String destFile = …
// Build FileProvider uri.
final Uri uri = FileProvider.getUriForFile(activity, AUTHORITY, destFile)
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.setType("video/*");
Log.d(TAG, "Sharing " + sendIntent.getType() + " for " + uri);
String title = "Share this content with";
Intent chooser = Intent.createChooser(sendIntent, title);
if (null != sendIntent.resolveActivity(activity.getPackageManager())) {
activity.startActivity(chooser);
}
This code works and shows the chooser. When I select a messaging app like Telegram, I get to pick the destination conversation, but the video is sent as a file attachment, meaning that users only see a document icon and need to download it and open externally. However, the same video, using the OS system gallery, will open Telegram into their video editor where they can cut/edit the media and when sent will be visible inline in the conversation.
What am I missing to get the same behaviour? Looking through Android git repositories I don't see anything different from this to share content, so I don't know what I'm missing. The log I get with this code looks like
Sharing video/* for content://com.app.android.fileprovider/share/video-a.mp4
So not only does it have the mime type but also the file extension could help. When I change the code to use a different mime type for images then I get the same behaviour, where the images get inlined into Telegram's chat.
For some reason the culprit was the FileProvider. Once I removed the FileProvider and passed in directly file:// URIs everything works.
I have an app which lists the video from a location in SD card. I want to share the video on different possible apps(like Whatsapp, gmail, facebook or bluetooth etc.). What intent should I call to acheive this action? I found this: Share image from SD Card but it is for image sharing. I also read: http://developer.android.com/training/sharing/shareaction.html but I didn't get it. I am viewing the videos in a listview and want to display a list of possible apps where I can share the video when I click it in list view.
EDIT: I am using this for now:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM,uri_for_file);
sendIntent.setType("file/*");
startActivity(Intent.createChooser(sendIntent,"Send video via:"));
but showing error when I tried to share on bluetooth:
11-18 17:49:59.275: E/BluetoothLauncherActivity(3249): type is null; or sending file URI is null
I checked using debugger, the uri_for_file variable has the exact uri where the video is stored.
The problem was, uri_for_file was string and I needed to parse it to Uri. Sorry to bother.
New Code:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM,Uri.parse(uri_for_file));
sendIntent.setType("file/*");
startActivity(Intent.createChooser(sendIntent,"Send video via:"));
I am hoping to be able to email the SQLite database I use within my app as a form of backup that the user can perform. My current code is below, the database shows up as an attachment in the email intent and the email will send, but the attachment is not sent.
File file = new File(Environment.getDataDirectory(), "/data/com.app/databases/databaseName");
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{""});
intent.putExtra(Intent.EXTRA_SUBJECT, "Backup");
intent.putExtra(Intent.EXTRA_TEXT, "");
intent.setType("application/octet-stream");
intent.putExtra(Intent.EXTRA_STREAM, file.toURI());
startActivity(Intent.createChooser(intent, "Send Email"));
Export your database to the sd card before trying to email it. You can't add attachments from within the data/data folder of your application. Those files are private to your application.
I remember I had this exact problem some time back. I'm not sure what I did to fix it, but my working code looks something like this...
File root = Environment.getExternalStorageDirectory();
String fileName = "foo.txt";
if (root.canWrite()) {
attachment = new File(root, fileName);
}
email.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(attachment));
startActivity(Intent.createChooser(email, "Send Email"));
I do remember that since I was using the SD card for storage, it would not send my attachment if I was still plugged into my computer via USB (since it kept the SD card mounted and busy). Once I unplugged the USB connection, things worked well.
https://stackoverflow.com/a/18548685/293280
The above SO Answer does a great job at showing you how to copy the DB file, email it as an attachment, and then delete the copied file. Check it out.
watch this link : http://www.openintents.org/en/node/121 you need passed URI
the solution is:
files have to be attached as
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/mysong.mp3"));
You need the extra / in file:/// (missing in the Stack Overflow post) as otherwise GMail drops the attachment just before sending stating the file path is wrong.
SO YOU NEED TH EXTRA / in file and its not droped.... hope this helps
I have a programmatically generated image that I want to send as an attachment via the ACTION_SEND and EXTRA_STREAM method.
But how do i do this?
My first attempt (writing to my context.getCacheDir() based file path) appeared to work in the Gmail preview (no image preview, but attached file name and icon was visible), but the attachment never arrived on the recipient side. I guess this has something to do with permissions on the generated file, but how to avoid this? Do I need to set more permissive settings on these generated files (so that the Gmail activity can access)? Is that even possible for the app's cache folder?
Is there another file location that would be more suitable to write my files to? I considered the downloads folder, but think it would be an awkward location for something that only needs to exist until it has been emailed.
I have even tried encoding my image purely in a data:image/png;base64,ABCD... style URI. This, too, showed up in Gmail preview (attachment icon, but no file name), but did not result in a recipient-side attachment.
Has anyone been able to attach a one-shot generated image to an email intent by any means? What options may I have overlooked?
My problem really consisted of two parts:
context.getCacheDir() is private to your app. You can't put something there and expect another app to be able to access it.
I misunderstood what MIME type I should have been using. Even though I was sending email text, I really needed to specify image/png for the sake of my attachment.
Additionally, research indicated that putting (potentially large) images on the primary memory was not a good idea, even if you were going to immediately clean it up.
Once I did these things and wrote my generated images to a public location on the SD Card, it worked just fine.
So, in overview:
Request SD Card Access in your manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Make sure SD Card is available
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
{
//Bail gracefully
}
Create a directory on the SD Card
File pngDir = new File(
Environment.getExternalStorageDirectory(),
//Loose convention inferred from app examples
"Android/data/com.somedomain.someapp/flotsam");
if (!pngDir.exists())
pngDir.mkdirs();
Write your file to that directory and capture the Uri
File pngFile = new File(pngDir, "jetsam.png");
//Save file encoded as PNG
Uri pngUri = Uri.fromFile(pngFile);
Build an ACTION_SEND intent
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("image/png"); //
intent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "someone#somewhere.com" });
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Portable Network Graphics");
intent.putExtra(android.content.Intent.EXTRA_CC, new String[] { "carbon#somewhere.com" });
intent.putExtra(Intent.EXTRA_TEXT, "Something textual");
intent.putExtra(Intent.EXTRA_STREAM, pngUri);
And then start the activity
context.startActivity(Intent.createChooser(intent, "Something Pithy"));
And then make sure you clean everything up...
Caveat 1
There appears to be more support coming for app-specific SD Card directories, but alas, not in my required SDK version.
Caveat 2
This is an overview of the solution that eventually worked for me. It is not necessarily a "best practice" approach.
Caveat 3
This does mean that the application has to have an SD Card mounted in order to have the image attachments feature available, but this was totally acceptable for my use case. Your mileage may vary. If the SD Card is not available, I append a friendly note to the email explaining why the images could not be attached and how to rectify the situation.
I've just run into exactly the same issue (wanting to attach a text file in my case). If you look in the Android log, the reason for it is:
02-28 21:01:28.434: E/Gmail(19673): file:// attachment paths must point to file:///mnt/sdcard. Ignoring attachment file:///data/data/com.stephendnicholas.gmailattach/cache/Test.txt
As a workaround (as mentioned by HRJ), you can use a ContentProvider to provide access to files in your application's internal cache so that Gmail can attach them. I've just written up a blog post on how to do it.
Hopefully that's of some help :)
tableLayout.buildDrawingCache();
Bitmap test = Bitmap.createBitmap(tableLayout.getDrawingCache());
tableLayout.destroyDrawingCache();
Log.d("Image", test.toString());
String path = Environment.getExternalStorageDirectory().toString();
Log.d("Path", path);
File file = new File(path,"mail_image.png");
Uri pngUri = Uri.fromFile(file);
Log.d("Real Image Path", pngUri.toString());
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("image/png");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "email to");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "From My App");
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, pngUri );
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
I have an Android app that saves a text file directly onto the phone, in the app's install directory. I need to allow the user to create a new email, attaching this saved text file. When I start the intent to send the email, everything shows up in Gmail correctly, but the attachment does not get sent. All of my searches on stack overflow seem to only deal with attaching an image file from the SD card. Below is the code that I used. Please let me know if I have done something incorrectly.
File myFile = new File(getFilesDir() + "/" + "someFile.txt");
FileOutputStream stream = null;
if( file != null )
{
steam = openFileOutput("someFile.txt", Context.MODE_WORLD_READABLE);
stream.write(some_data);
Uri uri = Uri.fromFile(myFile);
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
sendIntent.putExtra(Intent.EXTRA_TEXT, email_text);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
file.close();
startActivity(Intent.createChooser(sendIntent, "Email:"));
}
I've also tried sendIntent.setType("application/octet-stream"); but that didn't make a difference. I'm at a loss for why the file doesn't attach and get sent.
Any ideas?
I've just run into exactly the same issue (wanting to attach a text file to a Gmail message). If you look in the Android log, the reason for it is:
02-28 21:01:28.434: E/Gmail(19673): file:// attachment paths must point to file:///mnt/sdcard. Ignoring attachment file:///data/data/com.stephendnicholas.gmailattach/cache/Test.txt
As a workaround, you can use a ContentProvider to provide access to files in your application's internal cache so that Gmail can attach them. I've just written up a blog post on how to do it.
Hopefully that's of some help :)
I've seen this before and the only way I could solve it was by writing the file to the SD card.
It's worth trying writing to the file to the SD card and attaching it if only to eliminate the files location as the cause of the problem.