Android email intent not attaching files as attachment - android

For my company i am trying to send email from my android app using email intent.
I'm using emulator to test my app. But the problem is when i'm trying to Add and Attachment (eg. pdf, image) it won't attaching yet.
here is my code:
private String SendEmail(String oid, final String img, final String party_code, final String order_by, final Bitmap attachimg, final String note) {
try {
String filename="DOAttachment.jpeg";
String subject ="Order "+oid+" has been sent successfully";
String body="\nDear Sir, \n"+"Please find the attached file herewith.\nThe D.O for the customer(party) "+party_code+" has been successfully done with the order number: "+oid+"\n\n\n"+"With regards \n \n Employee code/ID: "+order_by+"\n\nN.B:"+note;
File root = Environment.getExternalStorageDirectory();
String pathToMyAttachedFile = "DirName/"+filename;
File file = new File(root, pathToMyAttachedFile);
file.setReadable(true,false);
Log.e("File path"," "+file);
//using outlook
Intent intent = new Intent(Intent.ACTION_VIEW).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP);
intent.setType("image/*");
Uri data = Uri.parse("mailto:?subject=" + subject + "&body=" + body+ "&stream="+Uri.parse("file:///"+Environment.getExternalStorageDirectory().getAbsolutePath())+"/DirName/"+filename);
intent.setData(data);
intent .putExtra(Intent.EXTRA_EMAIL, toemail);
if (!file.exists() || !file.canRead()||!file.canWrite()) {
Log.e(" FILE ERROR ","File Not found");
Toast.makeText(getApplicationContext(),"File Not found",Toast.LENGTH_LONG).show();
}
else {
file.setReadable(true);
Log.e(" FILE OK ","File was found");
Uri uri = Uri.fromFile(file);
intent.putExtra(Intent.EXTRA_STREAM, uri);
}
));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
return "TRUE";
} catch (Exception e) {
Log.e("SendMail", e.getMessage(), e);
return "MAIL NOT SENT";
}
}
The result is email with empty attachment find screenshot : https://1drv.ms/i/s!AruisQQIx8MTgatuhJFmSaoArg_6Xw

Check whether you had provided READ_EXTERNAL_STORAGE permission for your application both in manifest and run-time.
Then Call the below method send mail assuming the full file path is saved in filePath.
File root = Environment.getExternalStorageDirectory();
String pathToMyAttachedFile = "DirName/"+filename;
File filePath = new File(root, pathToMyAttachedFile)
sendEmailAlert(filePath,subject,text);
CALLED METHOD
private void sendEmailAlert(File fileName,String subject,String text) {
final File file=fileName;
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("application/octet-stream"); /* or use intent.setType("message/rfc822); */
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, text);
if (!file.exists() || !file.canRead()) {
Toast.makeText(getContext(), "Attachment Error", Toast.LENGTH_SHORT).show();
return;
}
Uri uri = Uri.fromFile(file);
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent, "Send email..."));
}

Related

Adding attachment using email intent Android

I've added an email intent to an Android app with code to add a local file as an attchment.
But when I click "Email Data" button to open the intent I get a an app crash
and log cat shows the following, http://hastebin.com/idejavunam.avrasm , an error of null pointer exception is output at this line:
case R.id.emailBtn:
so I thought its a problem with the file uri but can't see why as the file exists in the device's file system.
Does anyone know how I can debug this issue?
Possibly I'm passing the file's path to email intent incorrectly?
This is the process I'm following to implement the solution.
code from the method that creates csv file:
String baseDir = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "AnalysisData.csv";
//this filePath is used in email code and converted to Uri.
filePath = baseDir + File.separator + fileName;
File f = new File(filePath);
And this is the code where the email intent is called, with the file path converted to a Uri for attachment prposes:
case R.id.emailBtn: {
Toast.makeText(this, "email clicked", Toast.LENGTH_SHORT).show();
Uri.fromFile(new File(filePath));
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","abc#gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "EXTRA_SUBJECT");
emailIntent.putExtra(Intent.EXTRA_STREAM, filePath);
startActivity(Intent.createChooser(emailIntent, "Send email..."));
break;
I have modified some part check, if it works now.
case R.id.emailBtn: {
Toast.makeText(this, "email clicked", Toast.LENGTH_SHORT).show();
Uri uri = Uri.fromFile(new File(filePath));
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","abc#gmail.com", null));
emailIntent.setType("*/*");
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "EXTRA_SUBJECT");
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(emailIntent, "Send email..."));
break;
UPDATE
Also after looking at the logcat I found that your filepath is null . kindly correct that
EDIT
I have modified your onClick Method simply replace tell me if it works for you
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String baseDir = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "AnalysisData.csv";
filePath = baseDir + File.separator + fileName;
File f = new File(filePath);
switch (v.getId()) {
case R.id.exportBtn: {
Toast.makeText(this, "select clicked", Toast.LENGTH_SHORT).show();
//write sample data to csv file using open csv lib.
date = new Date();
CSVWriter writer = null;
// File exist
if(f.exists() && !f.isDirectory()){
FileWriter mFileWriter = null;
try {
mFileWriter = new FileWriter(filePath , true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
writer = new CSVWriter(mFileWriter);
}
else {
try {
writer = new CSVWriter(new FileWriter(filePath));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String data [] = new String[] {"Record Number","Ship Name","Scientist Name","Scientist Email","Sample Volume","Sample Colour","Sample Material","Latitude","Longitude","Date","\r\n"};
writer.writeNext(data);
/*
//retrieve record cntr from prefs
SharedPreferences settings = getSharedPreferences("RECORD_PREF", 0);
recordCntr = settings.getInt("RECORD_COUNT", 0); //0 is the default value
*/
//increment record count
recordCntr++;
/*
//save record cntr from prefs
settings = getSharedPreferences("RECORD_PREF", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("RECORD_COUNT",recordCntr);
editor.commit();
*/
data = new String[]{Integer.toString(recordCntr),shipName,analystName,analystEmail,sampleVolume,
sampleColour,sampleMaterial,latitudeValue.toString(),longitudeValue.toString(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date),"\r\n"};
writer.writeNext(data);
try {
writer.close();
Toast.makeText(this, "Data exported succesfully!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(this, "Error exporting data!", Toast.LENGTH_SHORT).show();
}
break;
}
case R.id.emailBtn: {
Toast.makeText(this, "email clicked", Toast.LENGTH_SHORT).show();
if (f.exists() && !f.isDirectory()) {
Uri uri = Uri.fromFile(f);
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","abc#gmail.com", null));
emailIntent.setType("*/*");
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "EXTRA_SUBJECT");
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(emailIntent, "Send email..."));
}
break;
}
}
}

Not able to send .csv file with email in android

I am going to attach ".csv" in mail and send it. but facing the problem that the csv file is not available at receiver side.
I have tried too many Mime types
application/octet-stream, text/comma-separated-values, text/csv, application/csv, application/excel, application/vnd.ms-excel, application/vnd.msexcel
but the file is not attached with the mail.
below are the code which i have used to send the mail
public boolean sendEmail() {
boolean success = false;
Intent intentSendMail = new Intent(Intent.ACTION_SEND);
File mydir = getApplicationContext().getDir(Global.FOLDERNAME, Context.MODE_PRIVATE);
File fileWithinMyDir = new File(mydir, Global.FILENAME);
if (!fileWithinMyDir.exists() || !fileWithinMyDir.canRead()) {
Toast.makeText(this, "Attachment Error", Toast.LENGTH_SHORT).show();
success = false;
} else {
intentSendMail.setType("text/csv");
intentSendMail.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(fileWithinMyDir));
intentSendMail.putExtra(Intent.EXTRA_SUBJECT,
"Subject");
intentSendMail.putExtra(Intent.EXTRA_TEXT, "Sent from my phone.");
startActivity(Intent.createChooser(intentSendMail, "E-mail"));
success = true;
}
return success;
}
Thanks in advance..
Try out as below:
String FILE = Environment.getExternalStorageDirectory() + File.separator
+ "Foldername";
Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
sendIntent.setType("application/csv");
sendIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "");
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "");
sendIntent.putExtra(Intent.EXTRA_TEXT, "");
String temp_path = FILE + "/" + "Filename.csv";
File F = new File(temp_path);
Uri U = Uri.fromFile(F);
sendIntent.putExtra(Intent.EXTRA_STREAM, U);
startActivity(Intent.createChooser(sendIntent, "Send Mail"));
Hope this will help you.
I got the solution for this problem.
Below are the solution
public boolean sendEmail() {
String destLocation = "";
String FILE = Environment.getExternalStorageDirectory()+"";
destLocation = FILE + "/" + Global.FILENAME;
boolean success = false;
Intent intentSendMail = new Intent(Intent.ACTION_SEND);
File mydir = getApplicationContext().getDir(Global.FOLDERNAME, Context.MODE_PRIVATE);
File fileWithinMyDir = new File(mydir, Global.FILENAME);
copyFile(Uri.fromFile(fileWithinMyDir).toString(),destLocation);
if (!fileWithinMyDir.exists() || !fileWithinMyDir.canRead()) {
Toast.makeText(this, "Attachment Error", Toast.LENGTH_SHORT).show();
success = false;
} else {
intentSendMail.setType("application/csv");
intentSendMail.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+destLocation));
intentSendMail.putExtra(Intent.EXTRA_SUBJECT,
"Test Play file.");
intentSendMail.putExtra(Intent.EXTRA_TEXT, "");
startActivity(Intent.createChooser(intentSendMail, "E-mail"));
success = true;
}
return success;
}
try this
emailIntent.setType("plain/text");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///mnt/sdcard/sanket test/siteriskassesment.csv"));
OR
see this

Android attaching multiple files from sdcard to email

How to attach multiple files in email in android?
Is there any permission required for multiple files attachment to an intent?
I am trying with putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList uriList) method but still in doubt whether Uri class is <? extends Parcelable> or not. I am not able to attach any file to email.
This is my code ::
Intent sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
sendIntent.setType("plain/text");
sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"soubhabpathak2010#gmail.com"});
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Accident Capture");
sendIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
ArrayList<Uri> uriList = getUriListForImages();
sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList);
Log.d(TAG, "Size of the ArrayList :: " +uriList.size());
FormHolderActivity.this.startActivity(Intent.createChooser(sendIntent, "Email:"));
and getUriListForImages() this method is defined as bellow -----
private ArrayList<Uri> getUriListForImages() {
ArrayList<Uri> uriList = new ArrayList<Uri>();
String imageDirectoryPath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/accident/";
File imageDirectory = new File(imageDirectoryPath);
String[] fileList = imageDirectory.list();
if(fileList.length != 0) {
for(int i=0; i<fileList.length; i++)
{
String file = "file://" + imageDirectoryPath + fileList[i];
Log.d(TAG, "File name for Uri :: " + file);
Uri uriFile = Uri.parse(file);
uriList.add(uriFile);
Log.d(TAG, "Image File for Uri :: " +(file));
}
}
return uriList;
}
To, subject and body of the email is coming and I have images in the accident folder in sdcard (I am using 2.1 API level 7) but nothing is attaching even there is also no exception in logcat.Arraylist is also ok(means length OK and name of the files are ok too). Can anyone help me to solve this problem?
After 1 day work finally I am able to attach multiple image files from \sdcard\accident\ folder to email client. For attaching multiple files I had to add the images to the ContentResolver which is responsible for gallery images provider.
Here is the Complete Code ---
Intent sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
sendIntent.setType("plain/text");
sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"soubhabpathak2010#gmail.com"});
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Accident Capture");
sendIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
ArrayList<Uri> uriList = getUriListForImages();
sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList);
Log.d(TAG, "Size of the ArrayList :: " +uriList.size());
FormHolderActivity.this.startActivity(Intent.createChooser(sendIntent, "Email:"));
So there is no change in the First Section of Code -- But Change is in getUriListForImages() method which is as follows---
private ArrayList<Uri> getUriListForImages() throws Exception {
ArrayList<Uri> myList = new ArrayList<Uri>();
String imageDirectoryPath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/accident/";
File imageDirectory = new File(imageDirectoryPath);
String[] fileList = imageDirectory.list();
if(fileList.length != 0) {
for(int i=0; i<fileList.length; i++)
{
try
{
ContentValues values = new ContentValues(7);
values.put(Images.Media.TITLE, fileList[i]);
values.put(Images.Media.DISPLAY_NAME, fileList[i]);
values.put(Images.Media.DATE_TAKEN, new Date().getTime());
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put(Images.ImageColumns.BUCKET_ID, imageDirectoryPath.hashCode());
values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, fileList[i]);
values.put("_data", imageDirectoryPath + fileList[i]);
ContentResolver contentResolver = getApplicationContext().getContentResolver();
Uri uri = contentResolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values);
myList.add(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return myList;
}
This is working fine and I am able to attach multiple image files to emulator default email client and send them successfully .
EXTRA_STREAM says this:
A content: URI holding a stream of data associated with the Intent, used with
ACTION_SEND to supply the data being sent.
Constant Value: "android.intent.extra.STREAM"
You can not pass a set of file URIs: it will simply ignore the results (as you are observing).
EDIT: scratch that. I was wrong. This is the chunk of code in the standard Android Email client that handles multiple files.
if (Intent.ACTION_SEND_MULTIPLE.equals(mAction)
&& intent.hasExtra(Intent.EXTRA_STREAM)) {
ArrayList<Parcelable> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (list != null) {
for (Parcelable parcelable : list) {
Uri uri = (Uri) parcelable;
if (uri != null) {
Attachment attachment = loadAttachmentInfo(uri);
if (MimeUtility.mimeTypeMatches(attachment.mMimeType,
Email.ACCEPTABLE_ATTACHMENT_SEND_INTENT_TYPES)) {
addAttachment(attachment);
}
}
}
}
}
Try doing this:
private ArrayList<Parcelable> getUriListForImages() {
ArrayList<Parcelable> uriList = new ArrayList<Parcelable>();
String imageDirectoryPath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/accident/";
File imageDirectory = new File(imageDirectoryPath);
String[] fileList = imageDirectory.list();
if(fileList.length != 0) {
for(int i=0; i<fileList.length; i++)
{
String file = "file://" + imageDirectoryPath + fileList[i];
Log.d(TAG, "File name for Uri :: " + file);
Uri uriFile = Uri.parse(file);
uriList.add(uriFile);
Log.d(TAG, "Image File for Uri :: " +(file));
}
}
return uriList;
}

android exporting to csv and sending as email attachment

I have seen multiple threads in this site discussing about sending email with attachments in android. I tried every methods discussed here, here and here.
I am creating a csv file via code and saving this file to android internal storage. Then I want to send this file as attachment in an email. Well, the email is being sent, I am getting it without attachment. This is what I have done.
String columnString = "\"Person\",\"Gender\",\"Street1\",\"PostOfice\",\"Age\"";
String dataString = "\"" + currentUser.userName +"\",\"" + currentUser.gender + "\",\"" + currentUser.street1 + "\",\"" + currentUser.poNumber.toString() + "\",\"" + currentUser.age.toString() + "\"";
String combinedString = columnString + "\n" + dataString;
File file = new File(this.getCacheDir()+ File.separator + "Data.csv");
try {
FileOutputStream out = new FileOutputStream(file);
out.write(combinedString.getBytes());
out.close();
} catch (IOException e) {
Log.e("BROKEN", "Could not write file " + e.getMessage());
}
Uri u1 = Uri.fromFile(file);
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Person Details");
sendIntent.putExtra(Intent.EXTRA_STREAM, u1);
sendIntent.setType("text/richtext");
startActivity(sendIntent);
I tried changing mime settings to "text/html" and "text/richtext" etc. But no luck yet. Can anyone tell me what I am doing wrong?
Thanks for everyone who tried to help..After taking a full day I have send an email from my app with attachment..This is the working code..
String columnString = "\"PersonName\",\"Gender\",\"Street1\",\"postOffice\",\"Age\"";
String dataString = "\"" + currentUser.userName +"\",\"" + currentUser.gender + "\",\"" + currentUser.street1 + "\",\"" + currentUser.postOFfice.toString()+ "\",\"" + currentUser.age.toString() + "\"";
String combinedString = columnString + "\n" + dataString;
File file = null;
File root = Environment.getExternalStorageDirectory();
if (root.canWrite()){
File dir = new File (root.getAbsolutePath() + "/PersonData");
dir.mkdirs();
file = new File(dir, "Data.csv");
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
out.write(combinedString.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Uri u1 = null;
u1 = Uri.fromFile(file);
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Person Details");
sendIntent.putExtra(Intent.EXTRA_STREAM, u1);
sendIntent.setType("text/html");
startActivity(sendIntent);
Also If you have mounted your phone SDCard in the machine , this code wont work. Only one can access SDCard at one time. So in that case unmount your SDCard from computer and try..Thanks to the guy who answered here..Also make sure you have bought permission to write to external Storage in your manifest file...
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Hope it helps someone...Thanks for everyone who tried to help..
This Code will help you out
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonSend = (Button) findViewById(R.id.buttonSend);
textTo = (EditText) findViewById(R.id.editTextTo);
textSubject = (EditText) findViewById(R.id.editTextSubject);
textMessage = (EditText) findViewById(R.id.editTextMessage);
buttonSend.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String to = textTo.getText().toString();
String subject = textSubject.getText().toString();
String message = textMessage.getText().toString();
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("plain/text");
File data = null;
try {
Date dateVal = new Date();
String filename = dateVal.toString();
data = File.createTempFile("Report", ".csv");
FileWriter out = (FileWriter) GenerateCsv.generateCsvFile(
data, "Name,Data1");
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(data));
i.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
i.putExtra(Intent.EXTRA_SUBJECT, subject);
i.putExtra(Intent.EXTRA_TEXT, message);
startActivity(Intent.createChooser(i, "E-mail"));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public class GenerateCsv {
public static FileWriter generateCsvFile(File sFileName,String fileContent) {
FileWriter writer = null;
try {
writer = new FileWriter(sFileName);
writer.append(fileContent);
writer.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return writer;
}
}
Add this line in AndroidManifest.xml file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission
Try
sendIntent.setType("message/rfc822");
For internal storage files, you need to make the file readable:
shareFile.setReadable(true, false);
Here is the code for attachment of csv file in mail (Its working code):
MyCsvFile.csv" should be present in your Internal/External memory of phone.
For More Look into this :https://stackoverflow.com/a/48643905/8448886
Below is the code for attachment of csv file into mail :
String csv = (Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyCsvFile.csv"); // Here csv file name is MyCsvFile.csv
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"email#example.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "subject here");
emailIntent.putExtra(Intent.EXTRA_TEXT, "body text");
File file = new File(csv);
Uri uri = Uri.fromFile(file);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(emailIntent, "Pick an Email provider"));
}
});

Android - not able to attach a file in email

By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user).
I am able to see the file "/data/data/package_name/files/ in file explore in DDMS, but when i attached the above file URI using imageUri in email , then i saw that attached file is of 0kb.
i have used the default email APIs of Android.
Can anyone suggest me ,how to attach a file in email that is private to the application?
although i am successful able to save the file in SD card and attaching the file from SD card , this is working fine.
But if SD card is not available and saving the file to the internal storage , then how can i attach them in email.
String FILENAME = "hello_file.txt";
String string = "hello world!";FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
File imageFile = getFileStreamPath(FILENAME );
Uri imageUri = Uri.fromFile(imageFile);
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("*/*");
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM,imageUri);
this.startActivityForResult(Intent.createChooser(emailIntent, "Send mail..."),SUB_ACTIVITY);
When you try to attach file from internal storage, GMail writes an error to the log:
ERROR/Gmail(...): file:// attachment paths must point to file:///mnt/sdcard.
E-mail application would show you the attached file even if it didn't physically exist.
As for an external storage, documentation says that:
Every Android-compatible device supports a shared "external storage" that you can use to save files. This can be a removable storage media (such as an SD card) or an internal (non-removable) storage.
That means you don't have to worry about device not having an external storage at all. Still, external storage can be unavailable at times. Refer to http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
Android: Attaching files from internal cache to Gmail
package com.stephendnicholas.gmailattach;
import java.io.File;
import java.io.FileNotFoundException;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
public class CachedFileProvider extends ContentProvider {
private static final String CLASS_NAME = "CachedFileProvider";
// The authority is the symbolic name for the provider class
public static final String AUTHORITY = "com.stephendnicholas.gmailattach.provider";
// UriMatcher used to match against incoming requests
private UriMatcher uriMatcher;
#Override
public boolean onCreate() {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Add a URI to the matcher which will match against the form
// 'content://com.stephendnicholas.gmailattach.provider/*'
// and return 1 in the case that the incoming Uri matches this pattern
uriMatcher.addURI(AUTHORITY, "*", 1);
return true;
}
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
String LOG_TAG = CLASS_NAME + " - openFile";
Log.v(LOG_TAG,
"Called with uri: '" + uri + "'." + uri.getLastPathSegment());
// Check incoming Uri against the matcher
switch (uriMatcher.match(uri)) {
// If it returns 1 - then it matches the Uri defined in onCreate
case 1:
// The desired file name is specified by the last segment of the
// path
// E.g.
// 'content://com.stephendnicholas.gmailattach.provider/Test.txt'
// Take this and build the path to the file
String fileLocation = getContext().getCacheDir() + File.separator
+ uri.getLastPathSegment();
// Create & return a ParcelFileDescriptor pointing to the file
// Note: I don't care what mode they ask for - they're only getting
// read only
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(
fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);
return pfd;
// Otherwise unrecognised Uri
default:
Log.v(LOG_TAG, "Unsupported uri: '" + uri + "'.");
throw new FileNotFoundException("Unsupported uri: "
+ uri.toString());
}
}
// //////////////////////////////////////////////////////////////
// Not supported / used / required for this example
// //////////////////////////////////////////////////////////////
#Override
public int update(Uri uri, ContentValues contentvalues, String s,
String[] as) {
return 0;
}
#Override
public int delete(Uri uri, String s, String[] as) {
return 0;
}
#Override
public Uri insert(Uri uri, ContentValues contentvalues) {
return null;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Cursor query(Uri uri, String[] projection, String s, String[] as1,
String s1) {
return null;
}
}
<provider android:name="CachedFileProvider" android:authorities="com.stephendnicholas
public static void createCachedFile(Context context, String fileName,
String content) throws IOException {
File cacheFile = new File(context.getCacheDir() + File.separator
+ fileName);
cacheFile.createNewFile();
FileOutputStream fos = new FileOutputStream(cacheFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
PrintWriter pw = new PrintWriter(osw);
pw.println(content);
pw.flush();
pw.close();
}
public static Intent getSendEmailIntent(Context context, String email,
String subject, String body, String fileName) {
final Intent emailIntent = new Intent(
android.content.Intent.ACTION_SEND);
//Explicitly only use Gmail to send
emailIntent.setClassName("com.google.android.gm","com.google.android.gm.ComposeActivityGmail");
emailIntent.setType("plain/text");
//Add the recipients
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[] { email });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
//Add the attachment by specifying a reference to our custom ContentProvider
//and the specific file of interest
emailIntent.putExtra(
Intent.EXTRA_STREAM,
Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/"
+ fileName));
return emailIntent;
}
enter code here
In order to share a private file you need to use a ContentProvider to provide access to your file by other applications. Here's a great example: Android: Attaching files from internal cache to Gmail.
Also, although the tutorial mentions that you need to declare your provider in the Android manifest file, it does not specify that it should be contained in <application>, so make sure that when you declare it is within <application> </application>.
This Code may help you out to get idea about attachment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonSend = (Button) findViewById(R.id.buttonSend);
textTo = (EditText) findViewById(R.id.editTextTo);
textSubject = (EditText) findViewById(R.id.editTextSubject);
textMessage = (EditText) findViewById(R.id.editTextMessage);
buttonSend.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
String to = textTo.getText().toString();
String subject = textSubject.getText().toString();
String message = textMessage.getText().toString();
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("plain/text");
File data = null;
try {
Date dateVal = new Date();
String filename = dateVal.toString();
data = File.createTempFile("Report", ".csv");
FileWriter out = (FileWriter) GenerateCsv.generateCsvFile(
data, "Name,Data1");
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(data));
i.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
i.putExtra(Intent.EXTRA_SUBJECT, subject);
i.putExtra(Intent.EXTRA_TEXT, message);
startActivity(Intent.createChooser(i, "E-mail"));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public class GenerateCsv
{
public static FileWriter generateCsvFile(File sFileName,String fileContent)
{
FileWriter writer = null;
try {
writer = new FileWriter(sFileName);
writer.append(fileContent);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return writer;
}
}
The above code requires you add the following permission to your manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Try using Context.MODE_WORLD_READABLE instead of Context.MODE_PRIVATE when saving the file. Then other apps will have access to the file.
I have also experienced this problem using internal files and although I have used openFileInput with MODE_WORLD_READABLE on /data/data//files/testFileName.txt and used the URI.parse with the extra "/" (see below), the received test emailed is still lacking the desired attachment. So sorry but there is no answer, except try to use External files on the SD Card - which is my next experiment!
Code :
File tmpFile = new File(context.getFilesDir(), mfileName);
Log.d(TAG, tmpFile.toString());
// This shows: /data/data/org.eddiem.adeveloper.flatfiletest/files/testFile.csv
//File tmpFile2 = new File(context.getFileStreamPath(mfileName), mfileName);
//Log.v(TAG, tmpFile2.toString());
// This also shows: /data/data/org.eddiem.adeveloper.flatfiletest/files/testFile.csv
//Uri uri = Uri.fromFile(new File(context.getFileStreamPath(mfileName), mfileName));
Uri uri = Uri.parse("file://" + tmpFile.toString());
//Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
// mfileName));
Log.d(TAG, "Uri-path is: " + uri.getPath()); // or .toString()
Intent i = new Intent(android.content.Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_EMAIL, new String[]{"eddie.moxey#sky.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "Test Email - with Attachment");
i.putExtra(Intent.EXTRA_TEXT, "This is a test Email with an Attachment.");
i.putExtra(Intent.EXTRA_STREAM, uri);
//startActivity(Intent.createChooser(i, "Select application"));
startActivity(Intent.createChooser(i, "Send mail"));
I was facing the same issue and following worked for me.
First send Broadcast to notify device that file is created / mounted.
For example:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+storagePath)));
Then use code to send mail with attachment.
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, "Receiver Email Address" );
email.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
email.putExtra(Intent.EXTRA_SUBJECT, "Subject");
email.putExtra(Intent.EXTRA_TEXT,"Email Text");
//Mime type of the attachment (or) u can use sendIntent.setType("*/*")
//email.setType("text/plain");
email.setType("application/YourMimeType");
//Full Path to the attachment
email.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+storagePath));
try
{
startActivity(Intent.createChooser(email, "Send Message..."));
}
catch (android.content.ActivityNotFoundException ex)
{
}

Categories

Resources