brig
brig

Reputation: 315

how to attach file to the email from /data folder of the device

I am trying to attach the file from the /data folder of the device.

I have successfully created "abc.txt" in /data folder, I can see the file at that place.

I am using below code to send email:

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_EMAIL, new String[]{[email protected]});
    intent.putExtra(Intent.EXTRA_STREAM,
       Uri.parse(Environment.getDataDirectory()+"/abc.txt"));
    intent.putExtra(Intent.EXTRA_TEXT, "hello..");
    startActivity(Intent.createChooser(intent, email_chooser_title));

but I am unable to receive the attachments..

pl. let me know what's the mistake I have done..

thanks.

Upvotes: 6

Views: 4279

Answers (6)

Borzh
Borzh

Reputation: 5215

From Android: Attaching files from internal cache to Gmail (with some modifications that allows you to run this code on Lollipop).

Basically you need to implement your own class that extends ContentProvider (say CachedFileProvider, see below), and add a next field in manifest (inside /application tag):

<provider
        android:name=".CachedFileProvider" 
        android:authorities="com.your.app.provider"
        android:grantUriPermissions="true" />

When opening a mail chooser, use next code:

File f = getLocalFileToSend();
Uri uri = Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/" + f.getName());
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Body");
intent.putExtra(Intent.EXTRA_STREAM, uri);

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Grant permissions to read.
startActivity(Intent.createChooser(intent, "Send Email"));

The code for CachedFileProvider:

package ...;

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 TAG = "CachedFileProvider";

    private static final String CLASS_NAME = "CachedFileProvider";

    // The authority is the symbolic name for the provider class.
    // Should match one in the manifest file.
    public static final String AUTHORITY = "com.your.app.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 {
        Log.v(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.
                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(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;
    }
}

Upvotes: 1

miten joshi
miten joshi

Reputation: 185

Try this code!!!!    


File sdCard = Environment.getExternalStorageDirectory();
PATH=sdCard.toString();
String path =PATH.replace("/mnt","") + "/abc.txt";
Intent intent=new Intent(Intent.ACTION_SEND);
intent.setType("**/**");// or intent.setType("text/plain");
String[] recipients={"[email protected]");
intent.putExtra(Intent.EXTRA_EMAIL, recipients);
intent.putExtra(Intent.EXTRA_SUBJECT,getResources().getString(R.string.app_name));
intent.putExtra(Intent.EXTRA_STREAM,Uri.parse("file://" +path));
intent.putExtra(Intent.EXTRA_TEXT, "hello..");
startActivity(Intent.createChooser(intent,""));

Upvotes: 0

AkashG
AkashG

Reputation: 7888

Try using this code:

File sdCard = Environment.getExternalStorageDirectory();
PATH=sdCard.toString()+"/abc.txt";
Intent intent=new Intent(Intent.ACTION_SEND);
intent.setType("**/**");// or intent.setType("text/plain");
String[] recipients={"[email protected]");
intent.putExtra(Intent.EXTRA_EMAIL, recipients);
intent.putExtra(Intent.EXTRA_SUBJECT,getResources().getString(R.string.app_name));
intent.putExtra(Intent.EXTRA_STREAM,Uri.parse("file://"+PATH));
intent.putExtra(Intent.EXTRA_TEXT, "hello..");
startActivity(Intent.createChooser(intent,""));

Make sure there is abc.txt file in your Device/Emulator's sdcard.

Also include these two permissions in your project's manifest file:

<uses-permission  android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>

Upvotes: 1

Sriram
Sriram

Reputation: 1

Instead of using Environment.getDataDirectory()+"/abc.txt" did you try using Environment.getExternalStorageDirectory()+"/abc.txt" ?

I feel this change should do the trick. Of course, for this to work, you have to have the file on the phone's/emulator's SD card.

Upvotes: 0

Manikandan
Manikandan

Reputation: 1519

Try this instead of the 4th line

intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:/data/abc.txt"));

If it is in sdcard:

intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:/sdcard/data/abc.txt"));

Upvotes: 0

Cristian
Cristian

Reputation: 200140

You must copy the file to the external directory (aka SD Card). It's because the email application cannot access your data directory (in the same way that you can't access other app's data directory)

Upvotes: 3

Related Questions