2013-04-11 12 views
5

Zuerst werden Sie denken "Warte, diese Frage ist ein Duplikat!". Weiter lesen.Senden von E-Mail mit Anhang mit SENDTO auf einigen Geräten funktioniert nicht

Ich versuche, die Absicht ACTION_SENDTO (mit einer E-Mail-URI als Daten) zu verwenden, um nur E-Mail-Anwendungen zu haben.

(mit ACTION_SEND startet ein Standard "SEND" -Wähler ohne Daten-URI bedeutet, dass keine Mail-Apps wie Google Drive reagieren).

Mein Problem ist, dass der Anhang mit ACTION_SEND auf allen Geräten funktioniert, aber - wenn Sie ACTION_SENDTO verwenden nur einige Geräte korrekt die Dateien anhängen. Nexus 7 funktioniert, aber Samsung Galaxy Tab und Acer Iconia nicht.

Sie können unter den verschiedenen Methoden nebeneinander sehen:

String email = getActivity().getResources().getString(R.string.supportEmail); 
    String subject = getActivity().getResources().getString(R.string.sFeedback); 
    subject   = String.format(subject, 
         getActivity().getResources().getString(R.string.productName)); 
    String content = getActivity().getResources().getString(R.string.whatFeedbackWouldYouLikeToProvide) + "\n\n" + 
         mMessage.getText().toString(); 
    File toSend  = new File(outfile); 

    if(toSend.exists()) { 
     Log.e("Feedback", "File path: " + toSend.getAbsolutePath()); 

     Intent emailIntent = new Intent(android.content.Intent.ACTION_SENDTO); 
     emailIntent.setData(Uri.parse("mailto:" +email)); 
     emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, Uri.fromFile(toSend)); 
     emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);    
     emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,  content); 

    /* Intent emailIntent = new Intent(Intent.ACTION_SEND); 
     emailIntent.setType("message/rfc822"); 
     emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{email}); 
     emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); 
     emailIntent.putExtra(Intent.EXTRA_TEXT , content); 
     emailIntent.putExtra(Intent.EXTRA_STREAM , Uri.fromFile(toSend)); */ 

     try { 
      startActivity(emailIntent); 
     } catch (ActivityNotFoundException anfe) { 
      Toast.makeText(getActivity(), getResources().getString(R.string.pleaseInstallAnEmailClientInOrderToSendUsFeedback), 8000).show(); 
     } 
    } 

Sie können sehen, dass die Dateipfade scheinen nicht das Problem zu sein, habe ich in einigen Protokollierung hinzugefügt, die berichtet:

Samsung Gibt:

04-11 11:40:09.953: E/Feedback(6286): File path: /storage/sdcard0/logs.zip 

Nexus Gibt:

04-11 11:38:59.249: E/Feedback(12702): File path: /storage/emulated/0/logs.zip 

(beide basierend auf getExternalStorageDirectory(), um den anwendungsübergreifenden Zugriff zu gewährleisten).

Weiß jemand, warum der Unterschied?

+0

sollte 'Uri.parse (" mailto: "+ email)' sein, aber Sie vermissen auch eine Klammer auf dieser Linie, so könnte es Frage Tippfehler sein. –

+0

ja, sorry, Tippfehler in Frage. – Graeme

+0

Etwas muss im filePath falsch sein, da der Rest des Codes korrekt ist. Überkreuzen Sie einfach den URI, der sich auf den gültigen Standort bezieht oder nicht. Zweitens darf die anzuhängende Datei nicht im Anwendungsverzeichnis oder Cache-Verzeichnis liegen. –

Antwort

4

Versuchen Sie, die Aktivität über ACTION_SENDTO aufzulösen, aber tatsächlich über ACTION_SEND zu senden.

Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
        "mailto", "", null)); 
      intent.putExtra(Intent.EXTRA_SUBJECT, title); 
      intent.putExtra(Intent.EXTRA_TEXT, text); 
      intent.putExtra(Intent.EXTRA_STREAM, getSnapshotUri(snapshot, context, event)); 

      List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0); 
      if (resolveInfos.size() == 0) { 
       new AlertDialog.Builder(context) 
         .setMessage(R.string.no_mail_app) 
         .setPositiveButton(R.string.ok, null) 
         .show(); 
      } else { 
       String packageName = resolveInfos.get(0).activityInfo.packageName; 
       String name = resolveInfos.get(0).activityInfo.name; 

       intent.setAction(Intent.ACTION_SEND); 
       intent.setComponent(new ComponentName(packageName, name)); 

       context.startActivity(intent); 
      } 
+0

Ich möchte immer noch, dass der Benutzer die Wahl hat, welcher E-Mail-Client, aber dies ist sicherlich ein sehr guter Anfang für dieses Problem und sehr clever - wenn ich jemals zurück zu diesem werde ich versuche, dies zu verbessern. Vielen Dank! – Graeme

+0

Ich habe Folgendes verwendet, um die Aktivität aufzulösen: intent.resolveActivity (getPackageManager()); –

+0

Das Problem mit dieser Antwort: Es verwendet willkürlich die erste Aktivität von QueryIntentActivities zurückgegeben –

0

Sie könnten versuchen, das Thema und den Körper in den Uri zu setzen. This question scheint zu implizieren, dass das Problem möglicherweise behoben werden kann.

+0

Nein - macht keinen Unterschied (Code sieht hässlicher aus) - Datei wird immer noch nicht enthalten :) Danke für den Versuch! – Graeme

+0

Was ist mit 'emailIntent.putExtra (android.content.Intent.EXTRA_STREAM, Uri.parse (" file: // "+ toSend));' wie von http://stackoverflow.com/a/1279574 vorgeschlagen –

+0

Das ist schon der Das gleiche Ergebnis wie 'Uri.fromFile()' – Graeme

2

ich ähnliches Problem gestoßen und war mein Kopf den ganzen Tag kratzen, bis ich eine mögliche Antwort auf einem chinesischen Blog gefunden: http://flysnow.iteye.com/blog/1128354

Fast am Ende des Artikels, spricht sie über die Absicht Filter, die Android gebaut -in E-Mail-Client hat:

<activity 
    android:name=".activity.MessageCompose" 
    android:label="@string/app_name" 
    android:enabled="false"> 
    <intent-filter> 
     <action android:name="android.intent.action.VIEW" /> 
     <action android:name="android.intent.action.SENDTO" /> 
     <data android:scheme="mailto" /> 
     <category android:name="android.intent.category.DEFAULT" /> 
     <category android:name="android.intent.category.BROWSABLE" /> 
    </intent-filter> 
    <intent-filter android:label="@string/app_name"> 
     <action android:name="android.intent.action.SEND" /> 
     <data android:mimeType="text/plain" /> 
     <data android:mimeType="image/*" /> 
     <data android:mimeType="video/*" /> 
     <category android:name="android.intent.category.DEFAULT" /> 
    </intent-filter> 
</activity> 

Sie können sehen, es zwei Intent-Filter hat, anders zu behandeln SEND und SENDTO Absichten und nur SEND wird mit mime angegeben. Das Code-Snippet war weit zurück zu Android 1.6, aber es hat sich nicht viel geändert. Sie können es in der jüngsten Version finden:

https://android.googlesource.com/platform/packages/apps/Email/+/f44b729bff619d0a9f0b1492726351e41c1e5d5d/AndroidManifest.xml

Ich bin nicht sicher, warum sie nicht angeben mime in SENDTO Absicht, aber das ist so, wie es ist, ich denke, die meisten E-Mail-Client wahrscheinlich das gleiche zu tun Weg (außer Gmail, kann es Datei erfolgreich anfügen, wenn Sie SENDTO Intent verwenden). Könnte das auch dein Fall sein? Um sicher zu sein, sollten Sie Anhänge daher nur mit der SEND-Absicht senden.

8

Die einzige Lösung, die ich kam, ist die folgende. Es ist eine Mischung aus einigen anderen, die ich bei der Suche nach einer vollständigen Antwort gefunden habe.Im Folgenden werden nur E-Mail-Apps angezeigt und Anhänge können hinzugefügt werden. Der wichtigste Teil wurde hier gefunden: https://stackoverflow.com/a/8550043/4927659

ArrayList<Uri> uris = new ArrayList<>(); 
uris.add(Uri.parse("file://" + filepath)); 
//filepath is something like that: /mnt/sdcard/DCIM/DSC0001.JPG 
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
       "mailto", "[email protected]", null)); 
     emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Mail subject"); 
     List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(emailIntent, 0); 
     List<LabeledIntent> intents = new ArrayList<>(); 
     for (ResolveInfo info : resolveInfos) { 
      Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 
      intent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name)); 
      intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"[email protected]"}); 
      intent.putExtra(Intent.EXTRA_SUBJECT, "Mail subject"); 
      intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); //ArrayList<Uri> of attachment Uri's 
      intents.add(new LabeledIntent(intent, info.activityInfo.packageName, info.loadLabel(getPackageManager()), info.icon)); 
     } 
     Intent chooser = Intent.createChooser(intents.remove(intents.size() - 1), "Send email with attachments..."); 
     chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new LabeledIntent[intents.size()])); 
     startActivity(chooser); 
+0

Dies sollte die akzeptierte Antwort sein. – ywwynm

+0

Hallo zusammen, ich habe eine ähnliche Lösung gefunden. So hässlich, dass Anhang nicht über SENDTO gesendet werden kann. –

+0

Sehr schöne Lösung! Ich würde diese Antwort vervollständigen, indem ich nach der 'for'-Schleife einen' if'-Block hinzufüge, um einen Fehler zu vermeiden, wenn kein Mail-Client gefunden wurde: 'if (intents.size()> 0)' – gbaccetta

0

Die Sache ist Intent.ACTION_SEND von anderem E-Mail-Clients behandelt wird richtig, auch wenn Recepient angegeben wird (das ist falsch, aber ..). So ein muss diese Aktion verwenden, wenn andere Kunden als Gmail unterstützt werden sollen. So funktioniert es.

Und Recepient hinzufügen fügen Sie einfach genau die gleiche Zeile, die Sie, wenn Intent.ACTION_SENDTO wurden unter Verwendung hinzufügen würde:

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

In meinem Fall Dateianhang nicht mit Intent.ACTION_SENDTO und die Umstellung auf Intent.ACTION_SEND in anderen Mandanten als Google Mail hinzugefügt wurde gelöst es.