Attach a file from internal storage to email

Similar topics here do not have answers that helped ... I want to create an email message with an attached file, the file is located in the internal storage. Here is the code:

Intent i = new Intent(Intent.ACTION_SEND); i.setType("text/plain"); i.putExtra(Intent.EXTRA_EMAIL , new String[]{email}); i.putExtra(Intent.EXTRA_SUBJECT, "Smart Weight Tracker"); i.putExtra(Intent.EXTRA_TEXT , "CSV file is in attachment"); Uri uri; if(useExternal){ uri = Uri.fromFile(new File(this.getExternalFilesDir(null),fname)); } else{ File f = new File(this.getFilesDir(),fname); f.setReadable(true, false); f.setWritable(true, false); uri = Uri.fromFile(f); } i.putExtra(Intent.EXTRA_STREAM, uri); try { startActivity(Intent.createChooser(i, "Send mail...")); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(MainActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show(); } 

It works great with external storage, but when using internal storage I don't attach it. I checked - the file opens, (this is the length in my application, showing Toast - OK,> 0).

I write it like this:

  OutputStreamWriter out = new OutputStreamWriter(con.openFileOutput(fname, Context.MODE_WORLD_READABLE)); 

In logcat I see

 I/Gmail (28480): >>>>> Attachment uri: file:///data/data/Android.MyApp/files /31.10.2011.csv I/Gmail (28480): >>>>> type: text/plain I/Gmail (28480): >>>>> name: 31.10.2011.csv I/Gmail (28480): >>>>> size: 0 Size == 0! 

Any ideas?

+6
source share
3 answers

Hi, Try using content providers.

 emailIntent.putExtra(Intent.EXTRA_STREAM,Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/"+ fileName)); 

........ Android: link files from the 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 // Eg // '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.gmailattach.provider">

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

http://stephendnicholas.com/archives/974#comment-342

+5
source
 Uri fileUri = Uri.fromFile(new File(context.getCacheDir()+ "/"+ fileName)); Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); emailIntent.setType("text/plain"); 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, fileUri); startActivity(emailIntent); 

Please try this code. Hope this helps.

+1
source

I followed the stephendnicholas code for hours, thinking that I had to write my files to internal storage because my device did not have an SD card.

Creating my β€œinternal” file similar to this worked fine for me:

 File file = new File(getExternalFilesDir(null), filename); // :) 

He avoided the limitations of Gmail during attachments.

Before that, I created my file object as follows:

 File file = new File(this.getFilesDir(), filename); //will not attach 

But if your file is located literally from the internal storage, then stephendnicholas content providers, etc. work if you have crazy Android skills.

0
source

Source: https://habr.com/ru/post/900412/


All Articles