I'm developing and android app, and at certain point i want to allow the user to send a .csv file by email.
I've seen a lot of tutorials in the web, and all of them have the same code, the same code i've tryed many times. The thing is, the send email activity starts, the attachment appears in the email, but when it is sent, the file or goes empty to the destination, or doesn't appear in the destination at all.
Here is some piece of code:
File file = null;
File dir = ProjectViewerResume.this.getCacheDir();
if (dir.canWrite()){
file = new File(dir, ProjectViewerResume.this.mProject.getName()+".csv");
FileOutputStream out = new FileOutputStream(file);
out.write(csv.toString().getBytes());
out.close();
}
Uri u1 = null;
u1 = Uri.fromFile(file);
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Project Resume: "+
ProjectViewerResume.this.mProject.getName());
sendIntent.putExtra(Intent.EXTRA_STREAM, u1);
sendIntent.setType("text/csv");
startActivity(sendIntent);
The csv variable has file content in csv format.
I've omited the try..catch so the code seems cleaner..
Thks in advance
You can try this....
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject of Email");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("/mnt/sdcard/file.csv"));
sendIntent.putExtra(Intent.EXTRA_TEXT, "Enjoy the mail");
startActivity(Intent.createChooser(sendIntent, "Email:"));
If some problem occur in attaching file try following path.
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/file.csv"));
I have the exact same problem. So not to duplicate the same post I want to show you my code, which is slightly different from yours, but still sends an email with a 0KB attachment.
I print 2 messages to the Log:
The path is printed (I edited the package name)
The size of the file is not 0KB !!!
05-11 11:32:58.133: W/Log Viewer(432): Path is /data/data/<package>/files/LogCat.log.gzip
05-11 11:32:58.192: W/Log Viewer(432): The file is 504 bytes
I stopped inside the code with the Eclipse debugger and inspected the uriLog: it is not null and contains the right path.
The code is:
public void run() {
Uri uriLog = null;
try {
FileOutputStream out = openFileOutput("LogCat.log.gzip", Context.MODE_PRIVATE);
out.write(gzip(dump().getBytes()));
out.close();
File gzipFile = new File(getFilesDir(), "LogCat.log.gzip");
//uriLog = Uri.parse("file://" + getFilesDir() + "/LogCat.log.gzip");
uriLog = Uri.fromFile(gzipFile);
Log.w(TAG,"Path is " + uriLog.getPath());
Log.w(TAG,"The file is " + gzipFile.length() + " bytes");
}
catch (IOException e) {
e.printStackTrace();
}
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Android Log");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, dump());
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, uriLog);
try {
String str = getResources().getString(R.string.send_prompt);
Intent chooser = Intent.createChooser(emailIntent, str);
startActivity(chooser);
}
catch (Exception e) {
e.printStackTrace();
}
}
}).start();
Things I tried:
I created the uri by parse (see the commented line
I also put the data inside the email body to check it exists --> it arrives in the email
I also tried to put the gziped data in the email body to check it exists --> it arrived in the email
EDIT:
Tried to send a pre-existing file in the emulator, from /mnt/system/app/CustomLocale.apk 23745 bytes
The path from uriLog.getPath() was printed /apk/CustomLocale.apk and the mail still arrived with an attachment named CustomLocale.apk and 0KB size
The only thing it occurs to me that is failing, is that putextra(intent.EXTRA_STREAM,uri) is based on
public Intent putExtra (String name, Parcelable value)
and uris implement the parcelable interface. But for some reason, which I will investigate, maybe the call to writeToParcel(Parcel out, int flags) is not writing the file data out; that's why it is 0KB in the attachment.
This code works now for me.
Using createTempFile instead of openFileOutput. I still don't know what was wrong with the former approach.
It attaches a file named LogCat.log.gzip which is not empty this time and it has the data I put insde.
public void run() {
Uri uriLog = null;
try {
File gzipFile = File.createTempFile("LogCat.log", ".gzip");
FileOutputStream out = new FileOutputStream(gzipFile);
out.write(gzip(dump().getBytes()));
out.close();
uriLog = Uri.fromFile(gzipFile);
}
catch (IOException e) {
e.printStackTrace();
}
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Android Log");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, dump());
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, uriLog);
try {
String str = getResources().getString(R.string.send_prompt);
Intent chooser = Intent.createChooser(emailIntent, str);
startActivity(chooser);
}
catch (Exception e) {
e.printStackTrace();
}
}
}).start();
And don't forget to add this line to your manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Related
I want to share a file made and written using Service via email. I know I can't share a private file with email but how to use the content provider to do that. I read online that content Provider can help but I can't make it work. (I merged file creation code together with intent creation for simplicity)
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[]{ "someone#gmail.com"});
email.putExtra(Intent.EXTRA_SUBJECT, "Nothing");
email.putExtra(Intent.EXTRA_TEXT, "Nothing");
email.setType("message/rfc822");
Uri uri = null;
try {
File file = new File(this.getExternalFilesDir(null), "samplefile.txt");
uri = FileProvider.getUriForFile(this, "lcukerd.com.android.fileprovider", file);
FileOutputStream osw = new FileOutputStream(file);
osw.write("Say something".getBytes("UTF-8"));
osw.close();
Log.i("File Reading stuff", "success");
} catch (Exception e)
{
Log.e(tag,"File creation error",e);
}
//Uri uri = FileProvider.getUriForFile(this, "lcukerd.com.android.fileprovider", );
//Uri uri = Uri.fromFile(getFileStreamPath("samplefile.txt"));
Log.d(tag,uri.toString());
email.putExtra(Intent.EXTRA_STREAM,uri);
startActivityForResult(Intent.createChooser(email, "Choose an Email client :"),1);
I get option to choose app but then nothing happens. Gmail app does not open.
Gmail opens if I use Uri uri = Uri.fromFile(getFileStreamPath("samplefile.txt")); but then I get "permission denied for attachment".
Actually, I want to write file from service then send that file via email. Pls help me achieve that.
Use the following code,
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("*/*");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {"me#gmail.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
"Test Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
"go on read the emails");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromfile(new File(yourtextfilepath));
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
Make sure that your text file path should be from external memory card. Action send wont accept the files from internal memory.
Also try this also,
Link 1
I've got an intent that uses FileProvider to read from internal file storage for my app to send a file via email (or similar apps). The code works great everywhere apparently except for Gmail, which strangely adds a version of the provider path itself to the list of addressees of the email.
This is the code generating the intent:
public static Intent getSendIntent(Uri uri) {
final Intent i = new Intent(Intent.ACTION_SEND);
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
i.setDataAndType(uri, "message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL, new String[] { "my#email.com" });
i.putExtra(Intent.EXTRA_SUBJECT, "Export");
i.putExtra(Intent.EXTRA_TEXT, "See the attached...");
i.putExtra(Intent.EXTRA_STREAM, uri);
return i;
}
This is the code to start the activity:
File file = new File(getFilesDir(), filename);
Uri uri = FileProvider.getUriForFile(MainActivity.this, "com.example.myapplication.provider", file);
Intent i = Utils.getSendIntent(uri);
try {
startActivity(Intent.createChooser(i, "Send file..."));
} catch (Exception e) {
Log.d(TAG, "failed to start send activity: " + e.getMessage());
Toast.makeText(MainActivity.this, "No suitable activity found for export.", Toast.LENGTH_SHORT).show();
}
Works well in Slack, Evernote, etc. but in Gmail in addition to the email address I've provided, another addressee in this kind of format is added:
//com.example.myapplication.provider/my_files/filefile.csv
which prevents the email from sending until it's manually removed from the message. Everything else about the message is as expected.
Any clue how to prevent this?
The following Captain Obvious solution resolved the problem.
Replace:
i.setDataAndType(uri, "message/rfc822");
with:
i.setType("message/rfc822");
since, as #CommonsWare's question inferred, the file content isn't itself in rfc822 format.
I'm testing out creating a .txt file, and then sending it as an email attachment, via an intent.
Creating the .txt File
try {
String fileName = "testFileName.txt";
File root = new File(Environment.getExternalStorageDirectory(), "testDir");
if (!root.exists()) {
root.mkdirs();
}
File gpxfile = new File(root, fileName);
FileWriter writer = new FileWriter(gpxfile);
writer.append("Testing email txt attachment.");
writer.flush();
writer.close();
sendEmail(gpxfile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
Sending the email
protected void sendEmail(String fileName){
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_SUBJECT, "Test subject");
i.putExtra(Intent.EXTRA_TEXT, "This is the body of the email");
i.putExtra(Intent.EXTRA_STREAM, Uri.parse(fileName));
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
}
And this all seems to work fine. It opens up the email client, with the subject, body and attachment all visible
And sends just fine, indicating there is an attachment
But when I open gmail, there is no attachment shown
Same story when I view the email
And viewing the email on the phone, from within the "Sent" folder, also shows no attachment
The code is a copy and paste from multiple different posts on SO, and seemingly they are not having any issues. Where is the file going? Is it being stopped by gmail? Or not sending at all? Does the file not exist?
Note: I do have <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> set in the manifest.
Thanks in advance.
The problem was with the file path. Made the following changes:
sendEmail(gpxfile); // This is the file itself, not the file path
Then actually sending the email:
protected void sendEmail(File file){
Uri path = Uri.fromFile(file); // This guy gets the job done!
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_SUBJECT, "Test subject");
i.putExtra(Intent.EXTRA_TEXT, "This is the body of the email");
i.putExtra(Intent.EXTRA_STREAM, path); // Include the path
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
}
I am trying to send an email with logs using send-me-logs to myself. I don't want to use an email client, but just send the email "silently". I have also set android.permission.INTERNET in my app. I am using this code:
Uri emailUri = Uri.parse("mailto:" + email);
StringBuilder sb = new StringBuilder(preface).append(LINE_SEPARATOR);
String phoneInfo = collectPhoneInfo();
sb.append(LINE_SEPARATOR).append(phoneInfo);
for (String line : lines)
sb.append(LINE_SEPARATOR).append(line);
String content = sb.toString();
Intent intent = new Intent(Intent.ACTION_SENDTO, emailUri);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, content);
mContext.startActivity(intent);
startActivity doesn't throw an exception, but my LogCat says:
08-21 16:30:22.418: ERROR/JavaBinder(9269): !!! FAILED BINDER TRANSACTION !!!
I am on a real device (Samsung Galaxy S2). Any ideas?
Try putting the subject and text inside the emailUri as params:
Uri emailUri = Uri.parse("mailto:" + email + "?subject" = subject + "&body=" + content);
And remove the 2 intent.putExtra lines
Then open the chooser:
intent.setData(uri);
startActivity(Intent.createChooser(intent, "Email logs"));
The problem is with
intent.putExtra(Intent.EXTRA_TEXT, content);
content is too large to successfully bind into the bundle. (bundle has a size limit i've heard people say 500kb or 1024kb but not really sure)
If you really want to send all your log information which could be a lot of information. I would write out to file, and attach the file to the email as an .txt attachment
Sample code that could help achieve this...
public static final String filename = "log.txt";
// Opening a file for output
logFile = new File(Environment.getExternalStorageDirectory(), filename);
FileWriter fileWriter = new FileWriter(logFile, true);
//open for appending
bufferedWriter = new BufferedWriter(fileWriter);
for (String line : logInfoToWrite) {
bufferedWriter.write(line);
}
AND...
// adding a file as an attachment
File logFile = new File(Environment.getExternalStorageDirectory(), filename);
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(logFile));
notice: sample code is not complete and has some exception handling left out, and writer flushes, but should give enough of a gist as too how to accomplish writing log entries to a file, and then attaching that file to an email intent as a txt file.
Hope this helps others out there. I noticed this is a fairly old post
consider the code below:
String outFileName = "/data/data/com.packagename/attachment.ics";
emailintent.putExtra(Intent.EXTRA_STREAM, Uri.parse(outFileName));
emailintent.setType("plain/text");
startActivity(Intent.createChooser(emailintent, "Send mail..."));
The above code is starting the email client with the attachment shown when it starts. But when i send the email, the attachment is not received. The body is being received.
what is going wrong here?
thank you in advance.
EDIT:
Is there a specific mime type that i need to put for ics files? i even tried sending a txt file, but that too is not being sent. The attachment does show up when i am trying to send the email, but it does not appear when i receive the email
i found the problem that was occurring. I was putting the file that i want to attach to the email into a private folder inside my application. The email client was not able to access..
All i had to do was put it in a public directory on the sdcard and voila.. the email client got access and i started receiving in the mails i sent from my application.
PS: Even for ics files the MIME type is plain/text.
thanks for all your help.
There are a lot of threads related to this topic.
Did you try adding this
i.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + attachmentFilePath));?
How to send an attachment with the Email in android?
Android: How do I attach a temporary, generated image to an email?
problem sending an email with an attachment programmatically
I am facing the same problem in sending email with attach SQLite database. I am Searching for the solution for this problem but i found nothing.
there is no way to send attached file via email from internal storage.
For sending file via email first save that file to external storage and then attach and send.
I am using this code for saving file to sdcard
public void copyFileToSdCard()
{
File f = new File(Environment.getExternalStorageDirectory() + "/File name");
if(f.exists())
{
}
else
{
try
{
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite())
{
String currentPath = "file path";
String backupFilePath = "file name ";
File currentFile = new File(data, currentPath);
File backupFile = new File(sd, backupFilePath);
if (currentFile.exists()) {
FileChannel src = new FileInputStream(currentFile).getChannel();
FileChannel dst = new FileOutputStream(backupFile).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
}
catch (Exception e) {
Log.w("Backup", e);
}
}
}
and this for attach and send
Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] {emailAddress});
i.putExtra(Intent.EXTRA_SUBJECT, "Subject text");
i.putExtra(Intent.EXTRA_TEXT, "Body text");
Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "file name"));
i.putExtra(Intent.EXTRA_STREAM, uri);
i.setType("text/plain");
startActivity(Intent.createChooser(i, "Send mail"));
try this
emailintent.setType("text/calendar");
public class SendingMail {
public static void SendingMail(Context context) {
final Intent emailIntent = new Intent(
android.content.Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"abc#wxy.com"});
emailIntent.setType("text/html");
// Image file saved in sdcard
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+File.separator+"sdcard"
+ File.separator + "MyImage.png"));
emailIntent.putExtra(Intent.EXTRA_TEXT, "My image");
context.startActivity(Intent.createChooser(emailIntent, "Send mail..."));
}
}
This will work...