Android attaching multiple files from sdcard to email - android

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;
}

Related

Action_Send_Multiple intent, but not sure how to build the array

So in my current form of my app, I am able to send an email with a single image using the following:
private void dispatchSubmitBonusIntent() {
Intent sendEmailIntent = new Intent(Intent.ACTION_SEND);
sendEmailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendEmailIntent.setType("text/plain");
sendEmailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{submissionEmailAddress});
sendEmailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "2019_" + riderNumToH + "_" + bonusCategory.getText() +"_" + bonusState.getText() + "_" + bonusCity.getText() + "_" + bonusCode.getText());
sendEmailIntent.putExtra(Intent.EXTRA_TEXT, "Sent from aTOH App");
if (mainPhotoPath != null) {
sendEmailIntent.putExtra(android.content.Intent.EXTRA_STREAM, FileProvider.getUriForFile(captureBonus.this, "net.tommyc.android.tourofhonor", mainPhotoUri));
Log.v("MainImageFound", mainPhotoPath + "|" + mainPhotoUri);
if (secondaryPhotoPath != null) {
sendEmailIntent.putExtra(android.content.Intent.EXTRA_STREAM, FileProvider.getUriForFile(captureBonus.this, "net.tommyc.android.tourofhonor", secondaryPhotoUri));
Log.v("SecondaryImageFound", secondaryPhotoPath + "|" + secondaryPhotoUri);
} else {
Log.e("NoImageFound", "Image Not Found");
}
}
this.startActivity(Intent.createChooser(sendEmailIntent, "Sending email..."));
}
I am needing it to send up to two attachments, so I'm converting it over to an ACTION_SEND_MULTIPLE. I have the following code, but I'm not sure what to put inside the for loop for it to work.
public void sendEmail(Context context, String emailTo, String emailCC,
String subject, String emailText, List<String> filePaths)
{
//need to "send multiple" to get more than one attachment
final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[]{submissionEmailAddress});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "2019_" + riderNumToH + "_" + bonusCategory.getText() +"_" + bonusState.getText() + "_" + bonusCity.getText() + "_" + bonusCode.getText());
emailIntent.putExtra(Intent.EXTRA_TEXT, "Sent from aTOH App");
//has to be an ArrayList
ArrayList<Uri> uris = new ArrayList<Uri>();
//convert from paths to Android friendly Parcelable Uri's
for (String file : filePaths)
{
File fileIn = new File(file);
Uri u = Uri.fromFile(fileIn);
uris.add(u);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
context.startActivity(Intent.createChooser(emailIntent, "Sending email ..."));
}
What do I put in the for section so the it will grab the one or two images that need to be attached?
EDIT 1: I made some changes based on the answer I was given, but it still isn't working. I get an error that says android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/Tour%20of%20Honor/2019_541_AK6_1.jpg exposed beyond app through ClipData.Item.getUri() (That file path is correct though).
public void dispatchSubmitBonusIntent() {
Log.e(TAG, "entering dispatchSubmitBonusIntent");
//need to "send multiple" to use more than one attachment
final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
// Set up the email parameters
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[]{submissionEmailAddress});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "2019_" + riderNumToH + "_" + bonusCategory.getText() +"_" + bonusState.getText() + "_" + bonusCity.getText() + "_" + bonusCode.getText());
emailIntent.putExtra(Intent.EXTRA_TEXT, "Sent via TOH App for Android");
// Get the attachments
Uri mainPhotoURI = FileProvider.getUriForFile(captureBonus.this, "net.tommyc.android.tourofhonor", mainPhotoUri);
Uri optPhotoURI = FileProvider.getUriForFile(captureBonus.this, "net.tommyc.android.tourofhonor", secondaryPhotoUri);
//has to be an ArrayList
ArrayList<Uri> uris = new ArrayList<Uri>();
String[] filePaths = new String[] {mainPhotoURI.toString(), optPhotoURI.toString()};
for (String file : filePaths)
{
File fileIn = new File(file);
Uri u = Uri.fromFile(fileIn);
uris.add(u);
}
// Add the attachments to the email and trigger the email intent
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
this.startActivity(Intent.createChooser(emailIntent, "Sending email ..."));
}
Create one method for sending multiple attachments using an array
public boolean sendEmailIntentWithMultipleAttachments(Context context,
String[] emailTo, String[] emailCC, String[] emailBCC,
String subject, String emailBody, List filePaths) throws ActivityNotFoundException {
final Intent emailIntent =
new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType("message/rfc822");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, emailTo);
emailIntent.putExtra(android.content.Intent.EXTRA_CC, emailCC);
emailIntent.putExtra(android.content.Intent.EXTRA_BCC, emailBCC);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
ArrayList<String> extra_text = new ArrayList<String>();
extra_text.add("Hello This is multiple Email Text");
ei.putStringArrayListExtra(Intent.EXTRA_TEXT, extra_text);
if (filePaths != null) {
// has to be an ArrayList
ArrayList uris = new ArrayList();
// convert from paths to Android friendly Parcelable Uri's
for (String file : filePaths) {
File fileIn = new File(file);
if (fileIn.exists()) {
Uri u = Uri.fromFile(fileIn);
uris.add(u);
}
}
emailIntent.putParcelableArrayListExtra
(Intent.EXTRA_STREAM, uris);
}
context.startActivity(Intent.createChooser(emailIntent, "Sent mail"));
return true;
}
Create an imageArray like this and set to intent putParcelableArrayListExtra
ArrayList<Uri> uris = new ArrayList<Uri>();
String[] filePaths = new String[] {"sdcard/sample.png", "sdcard/sample.png"};
for (String file : filePaths)
{
File fileIn = new File(file);
Uri u = Uri.fromFile(fileIn);
uris.add(u);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(emailIntent);
Its working fine in my app

Android email intent not attaching files as attachment

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..."));
}

Share image on xamarin android dont work for facebook

I am using this code for sharing text + message in android. This method works fine for g+ or email, but dont work for Facebook. It says cant load file.
public void Share(string title, string content)
{
if (ActivityContext.Current == null || Application.Context == null)
return;
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(content))
return;
Bitmap bitmapToShare = BitmapFactory.DecodeResource(Application.Context.Resources, Resource.Drawable.icon_120);
File pictureStorage = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures);
File noMedia = new File(pictureStorage, ".nomedia");
if (!noMedia.Exists())
noMedia.Mkdirs();
string imageName = "shared_image" + DateTime.Now.ToBinary() + ".png";
File file = new File(noMedia, imageName);
Stream output = Application.Context.OpenFileOutput(imageName,FileCreationMode.WorldReadable);
bitmapToShare.Compress(Bitmap.CompressFormat.Png, 100, output);
output.Flush();
output.Close();
// var name = Application.Context.Resources.GetResourceName(Resource.Drawable.icon_120).Replace(':', '/');
// var imageUri = Uri.Parse("android.resource://" + name);
var sharingIntent = new Intent();
sharingIntent.SetAction(Intent.ActionSend);
sharingIntent.SetType("text/plain");
sharingIntent.SetType("image/png");
sharingIntent.PutExtra(Intent.ExtraTitle, title);
sharingIntent.PutExtra(Intent.ExtraText, content);
// sharingIntent.PutExtra(Intent.ExtraStream, imageUri);
sharingIntent.PutExtra(Intent.ExtraStream, Uri.FromFile(file));
sharingIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
ActivityContext.Current.StartActivity(Intent.CreateChooser(sharingIntent, title));
AnalyticsService.Instance.LogEvent("Share button clicked.");
}
Tried this post.
Am i doing something wrong?

How to store .vcf file in separate folder in internal SDCard

I am using following code to store vcf file that i am generating from code
I am able to generate vcf file
but it appears under root directory in SDcard
I want to store it under seperate folder
How do i meet to requirements? Plz help
Thanks you.
private void getVcardString() throws IOException {
final String vfile = "BackupCont" + currDate + ".vcf";
vCard = new ArrayList<String>();
cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
Cursor c = dbhandle.getContactsByIsChecked();
ArrayList<String> arrchk=new ArrayList<String>();
for(int cc=0;cc<c.getCount();cc++)
{
arrchk.add(c.getString(c.getColumnIndex("con_name")));
}
if (cursor != null && cursor.getCount() > 0) {
int i;
String new_path= Environment.getExternalStorageDirectory().getAbsolutePath()+"/Folder_name";
// String path = "c:/";
File dir = new File(new_path);
if (!dir.exists())
dir.mkdirs();
String storage_path = Environment.getExternalStorageDirectory()+"/Folder_name"+vfile;
Toast.makeText(getApplicationContext(), storage_path,Toast.LENGTH_LONG).show();
FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false);
cursor.moveToFirst();
for (i = 0; i < cursor.getCount(); i++)
{
if(arrchk.contains(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))))
{
get(cursor);
cursor.moveToNext();
mFileOutputStream.write(vCard.get(i).toString().getBytes());
}
}
mFileOutputStream.close();
cursor.close();
Toast.makeText(getApplicationContext(), "Created...",Toast.LENGTH_LONG).show();
Uri uri=Uri.fromFile(new File(storage_path,""+vfile));
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("application/x-vcard");
sharingIntent.putExtra(android.content.Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(sharingIntent, "Share using"));
}
else
{
Log.d("TAG", "No Contacts in Your Phone");
}
}
String outputDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "subFolderName";
outputDirectory.mkdirs();
File outputFile = new File(outputDirectory, filename);
FileOutputStream fos = new FileOutputStream(outputFile);
You should also check Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) to ensure that the external storage is in fact available.

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