【问题标题】:How to send file from Android app如何从 Android 应用程序发送文件
【发布时间】:2014-12-17 10:14:06
【问题描述】:

首先,我实际上已经阅读了几个关于在 Android 上发送附件的主题。也就是说,我还没有找到解决问题的方法。

我的应用程序相对简单,用户输入数字,然后使用 openFileOutput(filename, Context.MODE_APPEND); 将它们保存到“values.csv”。

现在,这是我用来将文件附加到电子邮件并发送的代码(我是从其他文件线程之一获得的。)

 private void sendEmail(String email) {

    File file = getFileStreamPath(filename);
    Uri path = Uri.fromFile(file);
    Intent intent = new Intent(android.content.Intent.ACTION_SEND);
    intent.setType("application/octet-stream");
    intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Test");
    String to[] = { email };
    intent.putExtra(Intent.EXTRA_EMAIL, to);
    intent.putExtra(Intent.EXTRA_TEXT, "Testing...");
    intent.putExtra(Intent.EXTRA_STREAM, path);
    startActivityForResult(Intent.createChooser(intent, "Send mail..."),
            1222);
}

这会打开我的电子邮件客户端,除了附加文件外,它一切正常,向我显示“文件不存在”的 toast 通知。

我错过了什么吗?顺便说一句,我已经添加了读写外部存储的权限。

我们将不胜感激。

编辑:我可以使用 DDMS 中的文件资源管理器模块并导航到我的 values.csv 所在的 /data/data/com.example.myapp/files/,然后将其复制到我的计算机,这样文件就可以了存在。一定是我的代码有问题。

【问题讨论】:

  • 我担心邮件应用程序无法读取您的文件,您是否尝试将 openFileOutput 中的模式更改为 MODE_WORLD_READABLE?
  • 它说它在 API 17 中已被弃用,但它似乎可以工作,现在 Mail 可以读取并发送它。但是,通过将其更改为 MODE_WORLD_READABLE,它就失去了 APPEND 质量,这很重要……有什么办法可以同时保持两者?
  • 是的,实际上这不是一个好的举措,因为存在安全漏洞,但它引导我找到答案,请稍候,我会为你写答案:)
  • Append 和 world readable 不应该是独占的,但是一些邮件客户端不会从另一个应用程序的内部存储中获取附件,即使它们是可读的(除非你欺骗他们)。所以最好要么使用外部存储,要么使用带有内容提供者的现代“android方式”。

标签: java android file email


【解决方案1】:

因此,除了使用 MODE_WORLD_READABLE 之外,另一种附加电子邮件的方法是使用 ContentProvider。 here 中有一个很好的教程可以做到这一点

但我也会很快向您解释,然后您可以阅读该教程。

所以首先您需要创建一个ContentProvider,它提供对应用程序内部缓存中文件的访问。

public class CachedFileProvider extends ContentProvider {
public static final String AUTHORITY = "com.yourpackage.gmailattach.provider";
private UriMatcher uriMatcher;
@Override
public boolean onCreate() {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(AUTHORITY, "*", 1);
    return true;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    switch (uriMatcher.match(uri)) {
        case 1:// If it returns 1 - then it matches the Uri defined in onCreate
            String fileLocation = AppCore.context().getCacheDir() + File.separator +     uri.getLastPathSegment();
            ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(fileLocation),     ParcelFileDescriptor.MODE_READ_ONLY);
            return pfd;
        default:// Otherwise unrecognised Uri
            throw new FileNotFoundException("Unsupported uri: " + uri.toString());
    }
}
@Override public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return     0; }
@Override public int delete(Uri uri, String s, String[] as) { return 0; }
@Override public Uri insert(Uri uri, ContentValues contentvalues) { return null; }
@Override public String getType(Uri uri) { return null; }
@Override public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) {     return null; }
}

然后写一个临时文件

File tempDir = getContext().getCacheDir();
File tempFile = File.createTempFile("values", ".csv", tempDir);
fout = new FileOutputStream(tempFile);
fout.write(bytes);
fout.close();

然后将其传递给电子邮件Intent

emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + 
CachedFileProvider.AUTHORITY + "/" + tempFile.getName()));

别忘了将它添加到清单中

<provider android:name="CachedFileProvider" android:grantUriPermissions="true"
android:authorities="yourpackage.provider"></provider>

【讨论】:

    【解决方案2】:

    我看到了答案,当然也看到了问题。 您询问如何从 android 发送文件,但在您的代码示例中,您是在谈论通过电子邮件发送。

    这完全是两个不同的东西......

    对于通过电子邮件发送,您已经有了答案,所以我根本不会输入。 从 android 发送文件是另一回事:

    1. 您可以创建到服务器的套接字连接并发送它。你当然要编写客户端和服务器端。 一个例子可以在这里找到:Sending file over socket...

    2. 您可以使用 ftp 服务器并将其上传到那里。你可以使用任何服务器。 例如:It's using apache ftp client library (open source)

    3. 您可以使用http请求并使其成为帖子(此方法仅适用于小文件) 示例:Sending file with POST over HTTP

    4. 您还可以使用 dropbox api 或 amazon s3 sdk,这样您就不必关心任何连接问题和重试等等,最后您有一个指向该文件的链接并传递该链接。

      一个。 DropBox API:documentation

      b. Amazon S3 SDK API:documentation

      c。谷歌云端硬盘 API:documentation 使用 Google Drive 的优势。

      1. 在 Android 上运行良好
      2. 身份验证要容易得多。
      3. “已用空间”在用户帐户上。

    问候

    【讨论】:

    • 很好的解释。您可以为此提供一些示例代码吗? “附加音频文件并发送给我的应用程序的其他用户”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多