2009-02-25 10 views
67

Sto tentando di avviare un'intenzione per inviare un'email. Tutto ciò funziona, ma quando provo a inviare effettivamente l'email succedono un paio di cose "strane".Tentativo di allegare un file dalla scheda SD all'e-mail

qui è il codice

Intent sendIntent = new Intent(Intent.ACTION_SEND); 
sendIntent.setType("image/jpeg"); 
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Photo"); 
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://sdcard/dcim/Camera/filename.jpg")); 
sendIntent.putExtra(Intent.EXTRA_TEXT, "Enjoy the photo"); 
startActivity(Intent.createChooser(sendIntent, "Email:")); 

Quindi, se io lancio utilizzando il menu contestuale di Gmail Esso mostra l'attaccamento, mi permette di tipo che l'e-mail è quello, e modificare il corpo & soggetto. Nessun grosso problema. Ho colpito invia, e invia. L'unica cosa è che l'allegato NON viene inviato.

Così. Ho pensato, perché non provarlo con il contesto del menu Email (per il mio account email di backup sul mio telefono). Mostra l'allegato, ma nessun testo nel corpo o nel soggetto. Quando lo invio, l'allegato invia correttamente. Ciò mi indurrebbe a credere che qualcosa sia assolutamente sbagliato. Ho bisogno di una nuova autorizzazione nel lancio di Manifest per inviare un'e-mail con allegato? Che cosa sto facendo di sbagliato?

+1

Grazie chrispix !, questo codice ha funzionato nella mia moto cliq. – Jana

risposta

94

ottenendo anche lo stesso problema

Codice:

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 
    emailIntent.setType("image/jpeg"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] 
    {"[email protected]"}); 
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, 
    "Test Subject"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, 
    "go on read the emails"); 
    Log.v(getClass().getSimpleName(), "sPhotoUri=" + Uri.parse("file:/"+ sPhotoFileName)); 
    emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:/"+ sPhotoFileName)); 
    startActivity(Intent.createChooser(emailIntent, "Send mail...")); 

Da adb logcat:

V/DumbDumpersMain(3972): sPhotoUri=file://sdcard/DumbDumpers/DumbDumper.jpg 
I/ActivityManager( 56): Starting activity: Intent { action=android.intent.action.CHOOSER comp={android/com.android.internal.app.ChooserActivity} (has extras) } 
I/ActivityManager( 56): Starting activity: Intent { action=android.intent.action.SEND type=jpeg/image flags=0x3000000 comp={com.google.android.gm/com.google.android.gm.ComposeActivityGmail} (has extras) } 
I/ActivityManager( 56): Starting activity: Intent { action=android.intent.action.SEND type=jpeg/image flags=0x2800000 comp={com.google.android.gm/com.google.android.gm.ComposeActivity} (has extras) } 
D/gmail-ls( 120):  MailProvider.query: content://gmail-ls/labels/[email protected](null, null) 
D/Gmail (2507):  URI FOUND:file://sdcard/DumbDumpers/DumbDumper.jpg 

Sembra che il provider di posta elettronica sia attachi ng un file di lunghezza 0. Quando controllo il filesystem il file è lì e corretto. Il codice che crea il file immagine è ben rifinito prima del tentativo di inviarlo via email.

Chiunque ha risolto questo problema senza riavvii magici (l'ho già provato)?

saluti,
Fin

Aggiornamento

percorso per me avrebbe dovuto essere

file:///sdcard/DumbDumpers/DumbDumper.jpg

è necessario l'extra / come questo punta alla directory principale, vale a dire:

file://+/sdcard/DumbDumpers/DumbDumper.jpg

combinati come

file:///sdcard/DumbDumpers/DumbDumper.jpg

Nel pezzo di codice sopra è necessario:

emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+ sPhotoFileName)); 

Spero che questo aiuta. Mi ci sono voluti anni per eseguire il debug.

saluti,
Finlay

+6

Ho upvoted, ma sarebbe ancora meglio se lo hai rielaborato in modo che la soluzione finale venga elaborata nel codice. La soluzione è più importante della storia qui. –

+3

Ho cambiato la risposta per riflettere sul fatto che sono necessarie 3 barre. Ho anche votato questo. – Chrispix

+0

upvote, non vorrei rielaborare questo perché le persone dovrebbero sapere dove si trova l'errore. grazie per la soluzione – mad

4

Sembra che questo è in realtà corretto, non so cosa stava accadendo, ma dopo un riavvio ha cominciato a lavorare:/

+0

Il codice dell'OP ha un errore di battitura: il percorso dovrebbe essere 'file: /// sdcard' (notare le tre barre, opposte a due). –

7

invece di "Uri.parse" uso "Uri.fromFile (new File (ambiente.getExternalStorageDirectory(), "nome del file"))"

Environment.getExternalStorageDirectory() -. percorso per scheda SD o qualsiasi altro supporto di memorizzazione esterna

21

Solo un po 'un'osservazione da parte mia ho avuto gli stessi problemi con . GMail, ma in qualche modo sembra funzionare quando devo conservare il file in questione sulla scheda SD prima e recuperare da lì, piuttosto che dalle attività Quindi il mio codice è il seguente:

Intent i = new Intent(Intent.ACTION_SEND); 
i.putExtra(Intent.EXTRA_SUBJECT, "Title"); 
i.putExtra(Intent.EXTRA_TEXT, "Content"); 
i.putExtra(Intent.EXTRA_STREAM, uri); 
i.setType("text/plain"); 
startActivity(Intent.createChooser(i, "Send mail")); 

e qui,

uri = Uri.fromFile(new File(context.getFilesDir(), FILENAME)); 

fa non lavoro, mentre

uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), FILENAME)); 

fa.

saluti, Michael

+0

Ho trovato la stessa cosa. Mi chiedo se si tratta di un problema di autorizzazioni con Gmail (o altri programmi di posta) che legge il file? Una cosa che mi ha aiutato è che quando ho usato il programma "Mail" incorporato (non Gmail), ha mostrato che l'allegato era 0 byte. È stato bello sapere che il problema esisteva senza dover inviare e controllare la mia email. :-) –

+1

Suggerirei di sostituire 'startActivity()' con 'startActivityForResult()' e rimuovere il file dalla root della scheda SD in 'onActivityResult()'. –

+0

Penso che non sia un problema di autorizzazione. È un problema con Android, che è stato corretto da qualche parte tra 2.3 e 4.2. Alla 2.3, se faccio in modo che un file su memoria interna sia leggibile, altre app possono aprirlo, ma Gmail non può ancora collegarlo. Deve essere in memoria esterna. Alla 4.2 non ho questo problema. – Tom

3

Ho avuto lo stesso problema e guardato dappertutto per trovare una soluzione. Alla fine l'ho risolto trovando un'app open source che funzionasse fuori dagli schemi e guardò come l'hanno fatto. Il codice è piuttosto lungo, quindi non lo citerò qui, ma pubblicherò un link. Guardate la funzione sendEmail in linea 449

http://rehearsalassist.svn.sourceforge.net/viewvc/rehearsalassist/android/trunk/src/urbanstew/RehearsalAssistant/SessionPlayback.java?revision=94&view=markup

ho refactoring mio codice per essere simile, e ora funziona. Spero che questo aiuti gli altri nella stessa situazione.

3

Da RFC 1738 sezione 3.10:

un URL di file prende la forma:

file://<host>/<path> 

dove ospite è il nome di dominio completo del sistema su cui il percorso è accessibile, e percorso è un percorso di directory gerarchico del modulo directory/directory /.../ nome.

Quindi è file: /// percorso/da/root come http://host/path/from/root perché esiste un "localhost" implicito tra la seconda e la terza barra. Ma come detto sopra, usa Uri.FromFile() per costruirlo.

+0

La parte relativa a 3 barre è ciò che voglio. Grazie. –

0

Ho avuto gli stessi sintomi. Nel mio caso è stato perché inizialmente stavo salvando l'allegato con le autorizzazioni MODE_PRIVATE. Non appena l'ho modificato su MODE_WORLD_READABLE sembra che GMail sia stato in grado di accedere al file e inviare correttamente l'allegato.

See more

4
Intent i = new Intent(Intent.ACTION_SEND); 
    i.setType("message/rfc822"); 
    i.putExtra(Intent.EXTRA_EMAIL , new String[]{"[email protected]"}); 
    i.putExtra(Intent.EXTRA_SUBJECT, "Data from app"); 
    i.putExtra(Intent.EXTRA_TEXT , "experience number x"); 
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

    Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "filename.txt")); 
    i.putExtra(Intent.EXTRA_STREAM, uri); 
    startActivity(Intent.createChooser(i, "Send email...")); 
0
public void sendMail(String path) { 
     Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 
     emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, 
     new String[] {AppConstant.server_mail}); 
     emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, 
     "IBPS ERROR Mail"); 
     emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, 
     "This is an autogenerated mail from IBPS app"); 
     emailIntent.setType("image/png"); 
     Uri myUri = Uri.parse("file://" + path); 
     emailIntent.putExtra(Intent.EXTRA_STREAM, myUri); 
     startActivity(Intent.createChooser(emailIntent, "Send mail...")); 
     } 
0

anche provare ad aggiungere Intent.addFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION); Questo ha aiutato con il mio problema.

0

Io ho la soluzione su questo dopo 4 giorni, Si prega di notare i seguenti punti mentre dando percorso file di classe in Android (Java):

1) Utilizzare il percorso per il percorso String storage interno = "/ stoccaggio/sdcard0/miofile.txt ";

2) path = "/ storage/sdcard1/myfile.txt";

3) menzionare le autorizzazioni nel file Manifest.

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

4) Controllare prima la lunghezza del file per conferma.

5) Controllare i percorsi in ES File Explorer per quanto riguarda sdcard0 & sdcard1 è lo stesso, altrimenti ......

esempio

File file=new File(path); 
long=file.length();//in Bytes 
0

Invia una e-mail con un allegato: (By docs)

Intent emailIntent = new Intent (Intent.ACTION_SEND); emailIntent.setType (HTTP.PLAIN_TEXT_TYPE);

emailIntent.putExtra (Intent.EXTRA_EMAIL, new String [] {"[email protected]"});

emailIntent.putExtra (Intent.EXTRA_SUBJECT, "Oggetto di posta elettronica"); emailIntent.putExtra (Intent.EXTRA_TEXT, "Testo messaggio email"); emailIntent.putExtra (Intent.EXTRA_STREAM, Uri.parse ("contenuto: // percorso/a/email/allegato"));

// È inoltre possibile collegare più elementi passando un ArrayList di Uris