2014-10-22 52 views
0

發送文件別的之前,其實我已經通過關於在Android上發送附件多個線程讀取。這就是說,我沒有找到解決我的問題的辦法。如何從Android應用

我的應用程序比較簡單,用戶類型的數字,它們會保存到「values.csv」使用openFileOutput(文件名,Context.MODE_APPEND);.

現在,這裏我使用的文件附加到電子郵件,然後發送(我是從其他文件的一個線程得到它。)

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中的文件資源管理器模塊,並導航到/data/data/com.example.myapp/files/,我的values.csv所在的位置,並將其複製到我的計算機,以便文件確實存在。必須是我的代碼有問題。

+0

恐怕郵件應用無法讀取你的文件,你有沒有試圖改變在openFileOutput的模式MODE_WORLD_READABLE? – 2014-10-22 02:56:37

+0

好吧,它說,它已被棄用在API 17,但它似乎工作,現在郵件可以閱讀併發送它。但是,通過將其更改爲MODE_WORLD_READABLE,它失去了APPEND質量,這非常重要......有什麼辦法可以保持兩者? – iVikD 2014-10-22 03:01:00

+1

是的,其實這不是一個好的舉措,因爲一個安全漏洞,但它導致我的答案,請等待我會爲你寫一個答案:) – 2014-10-22 03:02:00

回答

3

所以另一種方式來連接電子郵件,但使用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(); 

然後將它傳遞到電子郵件意圖

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是如此你不關心任何連接問題和重試等,最後你有一個鏈接到文件並通過鏈接。

    a。 DropBox API:documentation

    b。 Amazon S3 SDK API:documentation

    c。 Google Drive API:documentation 使用Google雲端硬盤的優勢。

    1. 是在Android上工作的外觀極好
    2. 認證是容易得多。
    3. 「已用空間」位於用戶帳戶上。

問候

+0

很好的解釋。你能否提供一些示例代碼? 「附加音頻文件併發送給我的應用程序的其他用戶」 – LittleGirl 2014-11-03 19:31:29

相關問題