Android wiele załączników do wiadomości e-mail przy użyciu funkcji Intent

98

Pracowałem nad programem na Androida do wysyłania wiadomości e-mail z załącznikiem (plik obrazu, plik audio itp.) Przy użyciu Intent z ACTION_SEND. Program działa, gdy wiadomość e-mail zawiera jeden załącznik. Kiedyś Intent.putExtra(android.content.Intent.EXTRA_STREAM, uri)załączałem wyznaczony plik obrazu do poczty i działa dobrze, poczta może być dostarczona przez Gmaila. Jednak gdy próbowałem dołączyć wiele obrazów do tej samej wiadomości, dzwoniąc Intent.putExtra(android.content.Intent.EXTRA_STREAM, uri)wiele razy, nie udało się. Żaden załącznik nie pojawia się w e-mailu.

Przeszukałem dokumentację SDK i grupę użytkowników programowania na Androida na temat załącznika do wiadomości e-mail, ale nie mogę znaleźć żadnych powiązanych informacji. Jednak odkryłem, że istnieje inna stała intencji ACTION_SEND_MULTIPLE(dostępna od poziomu API 4), która może spełniać moje wymagania. Opierając się na dokumentacji SDK, po prostu stwierdza, że ​​dostarcza wiele danych komuś innemu, działa tak ACTION_SEND, jak tylko, że dane są wielokrotne. Ale nadal nie mogłem znaleźć prawidłowego użycia tego polecenia. Próbowałem zadeklarować zamiar za pomocą ACTION_SEND_MULTIPLE, a następnie dzwoniłem putExtra(EXTRA_STREAM, uri)wiele razy, aby załączyć wiele obrazów, ale otrzymałem ten sam błędny wynik, jak poprzednio, żaden załącznik nie pojawił się w e-mailu.

Czy ktoś próbował ACTION_SEND_MULTIPLEi sprawił, że działał z wieloma załącznikami e-mail?

rrrr1234
źródło
Mam ten sam problem. To nie działa kod. Ten sam problem występuje podczas wysyłania MMS-ów, istnieje możliwość dodania tylko jednego pliku. Czy masz jakieś pomysły na to w inny sposób?

Odpowiedzi:

187

Oto kod potrzebny do utworzenia wiadomości e-mail zawierającej wiele załączników.

public static void email(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[]{emailTo});
    emailIntent.putExtra(android.content.Intent.EXTRA_CC, 
        new String[]{emailCC});
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); 
    emailIntent.putExtra(Intent.EXTRA_TEXT, emailText);
    //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, "Send mail..."));
}
gregm
źródło
2
zapomniałeś wpisać temat i emailText do intencji. w przeciwnym razie dziękuję za kod.
Bahadır Yağan,
5
Prawidłowy typ danych MIME powinna być "text / plain", a nie "plain / text": emailIntent.setType("text/plain");. Jeśli używasz „zwykłego / tekstowego”, Android wymusi używanie Gmaila jako nadawcy, ale jeśli użyjesz „tekst / zwykły”, zapewni okno wyboru aplikacji z Gmailem, Facebookiem, Bluetooth itp. Jeśli chcesz zaproponować tylko programy pocztowe zamiast tego użyj „text / xml”.
Idolon
4
A jeśli zmienisz ostatnią linię na context.startActivity(emailIntent);pole wyboru „Użyj domyślnie dla tej akcji” pojawi się w oknie wyboru aplikacji, dzięki czemu użytkownik będzie mógł wybrać domyślną aplikację do wysyłania wiadomości e-mail z wieloma załącznikami.
Idolon
2
W tym przykładzie pojawia się „AndroidRuntimeException: wywołanie funkcji startActivity () spoza kontekstu działania wymaga flagi FLAG_ACTIVITY_NEW_TASK. Czy naprawdę tego chcesz?” Próbowałem przekazać zarówno aplikację, jak i kontekst podstawowy do tej metody e-mail, ale oba skutkują tym samym błędem.
ravemir
To dla mnie rozwiązało problem, ale nie jestem pewien, czy unikam błędu w dziwny sposób, więc poprzedni komentarz zostawię tutaj każdemu, kto ma o tym jakiś pomysł.
ravemir
29

ACTION_SEND_MULTIPLE powinno być działaniem

i wtedy emailIntent.setType("text/plain");

śledzony przez:

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

To działa dla mnie.

santhana
źródło
19

Chociaż jest to stary wątek, ale ponieważ jest wyświetlany na górze w wyszukiwarkach Google, chcę dodać małą wskazówkę, aby był kompletny, dlatego natknąłem się na niego.

Konieczne jest, aby załączone pliki były czytelne dla aktywności poczty, w przeciwnym razie nie zostaną załączone. Więc musisz gdzieś dzwonić

fileIn.setReadable(true, false)
Tomasz
źródło
Dziękuję panie, poczta nie była w stanie wysłać załączników tylko do wiadomości.
Josejulio
Dziękuje! Nie mogłem zrobić zdjęć do wysłania bez tej linii
konunger
ŁAŁ! ta odpowiedź całkowicie uratowała mi dzień. Jeśli ktoś otrzyma błąd „jeden lub więcej plików nie załączono. Limit 20 MB” w aplikacji Gmail, ta poprawka rozwiązuje wszystko. Najlepsza wskazówka!
belphegor
2

W przypadku wielu załączników użyj, PutParcelableArrayListExtra(Intent.ExtraStream, uris)gdzie zmienna uris to a List<IParcelable>(). Oto przykład:

var email = new Intent(Intent.ActionSendMultiple);
    email.SetType("text/plain");
    email.PutExtra(Intent.ExtraEmail, new string[]{emailTo});
    email.PutExtra(Intent.ExtraCc, new string[]{emailCC});

    var uris = new List<IParcelable>();
    filePaths.ForEach(file=> {
        var fileIn = new File(file);
        var uri = Android.Net.Uri.FromFile(fileIn);
        uris.Add(uri);
    });

    email.PutParcelableArrayListExtra(Intent.ExtraStream, uris);

    context.StartActivity(Intent.CreateChooser(email, "Send mail..."));

Mam nadzieję że to pomoże ;)

Michele Caggiano
źródło