27 December 2011
在Android實作(模擬)一個form,
不管method是用POST或者GET傳遞普通參數(type="text/password/hidden"),都很簡單!

那要傳遞type="fiile"的呢?
也就是說要上傳一個檔案呢?
在Android裡面就稍嫌複雜了一點點點點!

這篇將會結合使用camera,將上傳照相完以後的相片!
至於怎麼取得camera的照完相的照片,可以去看我先前PO的教學! 來這看!
這邊就不多說怎麼取得,就假設已經取得照片了!

我們知道在HTML裡,要上傳含有file的參數,
<form>必須加上enctype="multipart/form-data"

在實作之前,必須說明一下發出這個form的request的格式會怎樣!
--==============
Content-Disposition: form-data; name="image"; filename="image.jpg"
Content-Type: image/jpeg

!@#!FAWE@#$!A=fj2j12r
--==============--





第一行是--==============
是由--加上boundary組成的
boundary很重要! 是用來區隔參數的!!
也就是說,如果裡有很2個參數,
那這2個參數前面都會有這一行!!!
對了,boundary可以自己設定,但是前提是要告訴server你的boundary是甚麼!
等等會說明到! 這裡的boundary假設是===========


第二行Content-Disposition: form-data; name="image"; filename="image.jpg"
這是宣告你的參數名稱,以及他的當案名稱


第三行Content-Type: image/jpeg
是宣告你的file是甚麼型態,因為我們這邊是拿圖片說明,
所以就是jpeg。


第四行是空白行,
在你寫入參數之前,前面一定是一行空白行


第五行!@#!FAWE@#$!A=fj2j12r
這行就是資料行了,開始寫入資料,因為是上傳圖片,
所以這樣看一定是亂碼!
如果今天type不是file,是text,
那麼就會是明文!


第六行--==============--
最後一個參數傳遞完,一定要加上這一行,
告訴server,傳完了!



了解格式後,現在就來實作,
而在Android的實作如下,
	// 先取得圖片
// uriFilePath是當初設定照相完,要存在哪
// 如果忘記可以去看文章上面說的教學文
FileInputStream fileInputStream = new FileInputStream(new File(uriFilePath.getPath()));

final String BOUNDARY = "==================================";
final String HYPHENS = "--";
final String CRLF = "\r\n";
URL url = new URL("http://xxx.xxx.xxx/uploadImage");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST"); // method一定要是POST
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);

// 把Content Type設為multipart/form-data
// 以及設定Boundary,Boundary很重要!
// 當你不只一個參數時,Boundary是用來區隔參數的
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);


// 下面是開始寫參數
String strContentDisposition = "Content-Disposition: form-data; name=\"image\"; filename=\"image\"";
String strContentType = "Content-Type: image/jpeg";
DataOutputStream dataOS = new DataOutputStream(conn.getOutputStream());
dataOS.writeBytes(HYPHENS+BOUNDARY+CRLF); // 寫--==================================
dataOS.writeBytes(strContentDisposition+CRLF); // 寫(Disposition)
dataOS.writeBytes(contentType+CRLF); // 寫(Content Type)
dataOS.writeBytes(CRLF);

int iBytesAvailable = fileInputStream.available();
byte[] byteData = new byte[iBytesAvailable];
int iBytesRead = fileInputStream.read(byteData, 0, iBytesAvailable);
while (iBytesRead > 0) {
dataOS.write(byteData, 0, iBytesAvailable); // 開始寫內容
iBytesAvailable = fileInputStream.available();
iBytesRead = fileInputStream.read(byteData, 0, iBytesAvailable);
}
dataOS.writeBytes(CRLF);
dataOS.writeBytes(HYPHENS+BOUNDARY+HYPHENS); // (結束)寫--==================================--
file.close();
dataOS.flush();
dataOS.close();


這樣完成了!!



blog comments powered by Disqus