尝试将文件从 SD 卡附加到电子邮件
Posted
技术标签:
【中文标题】尝试将文件从 SD 卡附加到电子邮件【英文标题】:Trying to attach a file from SD Card to email 【发布时间】:2010-10-09 22:19:45 【问题描述】:我正在尝试启动 Intent 以发送电子邮件。所有这些都有效,但是当我尝试实际发送电子邮件时,会发生一些“奇怪”的事情。
这里是代码
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:"));
因此,如果我使用 Gmail 菜单上下文启动它会显示附件,让我输入电子邮件的收件人,并编辑正文和主题。没什么大不了。我点击发送,它发送。唯一的问题是附件没有发送。
所以。我想,为什么不尝试使用电子邮件菜单上下文(用于我手机上的备用电子邮件帐户)。它显示附件,但正文或主题中根本没有文本。当我发送它时,附件会正确发送。那会让我相信有些事情是完全错误的。我是否需要在 Manifest 中获得新权限才能发送带有附件的电子邮件?我做错了什么?
【问题讨论】:
感谢 Chrispix!,此代码在我的 moto cliq 中工作。 【参考方案1】:同样的问题
代码:
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("image/jpeg");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]
"me@gmail.com");
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..."));
来自 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/me@gmail.com(null, null)
D/Gmail ( 2507): URI FOUND:file://sdcard/DumbDumpers/DumbDumper.jpg
看起来电子邮件提供商正在附加一个长度为 0 的文件。当我检查文件系统时,文件在那里并且正确。创建图像文件的代码在尝试通过电子邮件发送之前已经完成。
有人在没有魔法重启的情况下解决了这个问题(我已经尝试过了)?
问候, 鳍
更新
我的路径应该是
file:///sdcard/DumbDumpers/DumbDumper.jpg
你需要额外的/
,因为它指向根目录,即:
file://
+ /sdcard/DumbDumpers/DumbDumper.jpg
合并为
file:///sdcard/DumbDumpers/DumbDumper.jpg
在上面的sn-p中你需要:
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+ sPhotoFileName));
我希望这会有所帮助。我花了很长时间来调试。
问候, 芬莱
【讨论】:
我投了赞成票,但如果你重新设计它会更好,这样最终的解决方案就会被纳入代码。解决方案比这里的故事更重要。 我更改了答案以反映它需要 3 个斜线的事实。我也投了赞成票。 赞成,我不会重做这个,因为人们应该知道错误在哪里。感谢您的解决方案。 赞成,但 EXTRA_TEXT 在 facebook 的情况下不起作用,发布后只有图像出现在我的墙上。知道如何解决这个问题。 您不应使用“硬编码”路径,因为它们可能会因设备而异。因此,我建议您对代码稍作更改: File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);然后定义:Uri path = Uri.fromFile(filelocation);并将其放入您的意图中: emailIntent .putExtra(Intent.EXTRA_STREAM, path);【参考方案2】:只是我的一点意见。我在使用 GMail 时遇到了同样的问题,但是当我首先将有问题的文件存储在 SD 卡上并从那里而不是从资产中检索它时,它似乎可以工作。所以我的代码如下:
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"));
这里,
uri = Uri.fromFile(new File(context.getFilesDir(), FILENAME));
不有效,而
uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), FILENAME));
会。
问候, 迈克尔
【讨论】:
我发现了同样的事情。我想知道这是否是 Gmail(或其他邮件程序)读取文件的权限问题?帮助我的一件事是,当我使用内置的“邮件”程序(不是 Gmail)时,它显示附件是 0 字节。很高兴知道问题存在而无需发送和检查我的电子邮件。 :-) 我建议用startActivityForResult()
替换startActivity()
并从onActivityResult()
中的SD 卡的根目录中删除文件。
我认为这不是权限问题。这是 Android 的一个问题,在 2.3 和 4.2 之间的某个地方得到了纠正。在 2.3 上,如果我使内部存储上的文件可读,那么其他应用程序可以打开它,但 gmail 仍然无法附加它。需要在外部存储上。在 4.2 上我没有这个问题。【参考方案3】:
使用“Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"file name"))”代替“Uri.parse”
Environment.getExternalStorageDirectory() - SD 卡或任何其他外部存储的路径
【讨论】:
【参考方案4】:看来这实际上是正确的,不知道发生了什么,但重新启动后它开始工作:/
【讨论】:
OP 的代码有一个错字:路径应该是file:///sdcard
(注意三个斜线,而不是两个)。【参考方案5】:
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]"example@mail.com");
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..."));
【讨论】:
【参考方案6】:我遇到了同样的问题,到处寻找解决方案。最后,我通过找到一个开箱即用的开源应用程序解决了这个问题,并研究了他们是如何做到的。代码比较长,这里就不引用了,发个链接。查看第 449 行的 sendEmail 函数
http://rehearsalassist.svn.sourceforge.net/viewvc/rehearsalassist/android/trunk/src/urbanstew/RehearsalAssistant/SessionPlayback.java?revision=94&view=markup
我将我的代码重构为相似,现在它可以工作了。我希望这会帮助其他处于相同情况的人。
【讨论】:
【参考方案7】:来自RFC 1738 3.10 节:
文件 URL 采用以下形式:
file://<host>/<path>
其中 host 是系统的完全限定域名 路径是可访问的,并且 path 是分层的 directory/directory/.../name 形式的目录路径。
所以它是 file:///path/from/root 就像 http://host/path/from/root 因为在第二个和第三个斜杠之间有一个隐含的“localhost”。但是如上所述,使用 Uri.FromFile() 来构建它。
【讨论】:
关于 3 斜线的部分是我想要的。谢谢。【参考方案8】:我有同样的症状。就我而言,这是因为我最初使用权限MODE_PRIVATE
保存附件。一旦我将其更改为MODE_WORLD_READABLE
,GMail 似乎就能够访问该文件并正确发送附件。
See more
【讨论】:
【参考方案9】:这对我来说非常有用: 在这个解决方案中,Nicolas 在 Cache 文件夹中创建了一个副本,在这里 gmail 意图可以访问! http://stephendnicholas.com/archives/974
【讨论】:
【参考方案10】: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..."));
【讨论】:
【参考方案11】:还可以尝试添加 Intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);这有助于解决我的问题。
【讨论】:
【参考方案12】:我在 4 天后得到了解决方案,请在 Android(Java) 中为 File 类提供路径时注意以下几点:
1) 内部存储使用路径 String path="/storage/sdcard0/myfile.txt";
2) path="/storage/sdcard1/myfile.txt";
3) 在 Manifest 文件中提及权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
4) 首先检查文件长度以确认。
5) 检查 ES File Explorer 中关于 sdcard0 & sdcard1 的路径是否相同......
例如
File file=new File(path);
long=file.length();//in Bytes
【讨论】:
【参考方案13】:发送带有附件的电子邮件:(按文档)
意图 emailIntent = new Intent(Intent.ACTION_SEND); emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] "jon@example.com");
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "电子邮件主题"); emailIntent.putExtra(Intent.EXTRA_TEXT, "电子邮件信息文本"); emailIntent.putExtra(Intent.EXTRA_STREAM, uri.parse("content://path/to/email/attachment"));
// 也可以通过Uris的ArrayList来附加多个项目
【讨论】:
以上是关于尝试将文件从 SD 卡附加到电子邮件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 PHPMailer 从 PC 将文件附加到电子邮件
使用 PDO/MySQL 将自动增量编号附加到电子邮件中发送和发送电子邮件