首先,你会想到“等等,这个问题是重复的!”。请继续阅读。
我正在尝试使用Intent ACTION_SENDTO
(使用电子邮件URI作为数据),以便让 电子邮件应用响应。
(使用ACTION_SEND
启动标准“SEND”选择器,没有数据URI,这意味着非电子邮件应用(例如Google云端硬盘驱动器)也会响应。)
我的问题是附件适用于所有设备上的ACTION_SEND
,但是当使用ACTION_SENDTO
时,只有部分设备正确附加文件。 Nexus 7可以使用,但三星Galaxy Tab和Acer Iconia 不。
您可以在下面看到不同的方法:
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();
}
}
你可以看到文件路径似乎不是问题,我在一些报告中添加了报告:
三星给予:
04-11 11:40:09.953: E/Feedback(6286): File path: /storage/sdcard0/logs.zip
Nexus给予:
04-11 11:38:59.249: E/Feedback(12702): File path: /storage/emulated/0/logs.zip
(两者均基于getExternalStorageDirectory()
以确保跨应用程序访问)。
有人知道为什么会有差异吗?
答案 0 :(得分:4)
尝试通过ACTION_SENDTO解析活动,但实际通过ACTION_SEND发送。
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);
}
答案 1 :(得分:2)
我遇到了类似的问题,整天都在摸不着头脑,直到我在中文博客上找到了可能的答案:http://flysnow.iteye.com/blog/1128354
几乎到文章的最后,它讨论了Android内置电子邮件客户端的目标过滤器:
<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>
您可以看到它有两个意图过滤器来不同地处理SEND和SENDTO意图,并且只使用mimeType指定SEND。代码片段又回到了Android 1.6,但它没有被改变太多。您可以在最新版本中找到它:
我不确定为什么他们没有在SENDTO意图中指定mimeType,但就是这样,我认为大多数电子邮件客户端可能采用相同的方式(Gmail除外,它使用SENDTO intent时可以成功附加文件)。那可能也是你的情况吗?因此,为了安全起见,您应该只使用SEND意图发送附件。
答案 2 :(得分:0)
你可以尝试将主题和身体放在Uri中。 This question似乎暗示可以解决问题。
答案 3 :(得分:0)
事情是Intent.ACTION_SEND
由不同的电子邮件客户端正确处理,即使指定了recepient(这是不正确的,但是......)。因此,如果想要支持除Gmail以外的其他客户端,则必须使用此操作。这就是它的工作原理。
要添加接收者,只需添加完全相同的行,如果使用Intent.ACTION_SENDTO
则添加:
Intent emailIntent = new Intent(Intent.ACTION_SEND);
String mailto = "abc@def.com";
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{mailTo});
...
在我的情况下,文件附件未添加到Gmail以外的客户端Intent.ACTION_SENDTO
,并切换到Intent.ACTION_SEND
解决了它。
答案 4 :(得分:0)
经过多次尝试和组合,这是我用于仅在电子邮件应用程序中发送多个附件的版本:
public static void sendMailWithAttachedFiles(Context activityContext, ArrayList<String> filePaths, String MAIL, String SUBJECT, String TEXT) {
ArrayList<Uri> uris = new ArrayList<>();
for (String filePath : filePaths) {
File file = new File(filePath);
Uri csvUri = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
csvUri = FileProvider.getUriForFile(activityContext, activityContext.getPackageName() + ".provider", file);
} else {
//doesn't work in API 24+
csvUri = Uri.fromFile(file);
}
uris.add(csvUri);
}
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", MAIL, null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, SUBJECT);
emailIntent.putExtra(Intent.EXTRA_TEXT, TEXT);
List<ResolveInfo> resolveInfos = activityContext.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[]{MAIL});
intent.putExtra(Intent.EXTRA_SUBJECT, SUBJECT);
intent.putExtra(Intent.EXTRA_TEXT, TEXT);
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
intents.add(new LabeledIntent(intent, info.activityInfo.packageName, info.loadLabel(activityContext.getPackageManager()), info.icon));
}
Intent chooser = Intent.createChooser(intents.remove(intents.size() - 1), "Send email using");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new LabeledIntent[intents.size()]));
activityContext.startActivity(chooser);
}
在清单中:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
在 res 文件夹中创建 xml 文件夹并添加这个文件 provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>