編輯:關於Android編程
RFC1867協議介紹
RFC1867協議主要是在HTTP協議的基礎上為INPUT標簽增加了file屬性,同時限定了Form的method必須為POST,ENCTYPE必須為multipart/form-data。 其它屬性標簽, 標記可以有一個VALUE屬性來指定默認的文件名 ,可以用“SIZE=寬,高”來指定SIZE屬性 。
multipart/form-data
multipart/form-data的媒體內容遵從RFC 1521所規定的多部分的數據流規則。它主要被用來描述表單填寫後返回的數據。在一個表單中(這裡指的是HTML,當然其他一些應用也可 能使用表單),有一系列字段提供給用戶進行填寫,每個字段都有自己的名字。在一個確定 的表單中,每個名字都是唯一的。
multipart/form-data由多個部分組成,每一部分都有一個content-disposition標題頭,它的 值是form-data,它的屬性指明了其在表單內的字段名。舉例來說,'content-disposition: form-data; name=xxxxx',這裡的xxxxx就是對應於該字段的字段名。如果字段名包含非 ASCII碼字符的話,還應該按照RFC 1522裡面所規定的方法進行編碼。
對所有的多部分MIME類型來說,每一部分有一個可選的Content-Type,默認的值是 text/plain。如果文件的內容是通過表單填寫上傳返回的話,那麼輸入的文件就被定義為 application/octet-stream,或者,如果知道是什麼類型的話,就定義為相應的媒體類型。如 果一個表單返回多個文件,那麼它們就作為multipart/form-data中所結合的multipart/mixed 被返回。
如果所傳送的內容不符合默認的編碼方式的話,該部分都將被編碼,並加上 content-transfer-encoding的標題頭。
Android Post上傳文件的實現
Android POST方式上傳文件,可以基於通過 RFC1867協議來實現。
/** * * @param urlPath * @param params * map 參數 <參數名稱 , 參數值> * @param fileParams * map 文件類型 參數 <參數名稱 , 文件路徑> * */ public String postFile(String urlPath, Mapparams,Map fileParams) throws FileNotFoundException{ String PREFIX = --; //前綴 String LINE_END = ; //換行 String BOUNDARY = UUID.randomUUID().toString(); // 邊界標識 URL url; HttpURLConnection connection; try { url = new URL(urlPath); connection = (HttpURLConnection) url.openConnection(); //設置超時時間 connection.setReadTimeout(readTimeOut); connection.setConnectTimeout(connectTimeOut); // 請求方式 connection.setRequestMethod(POST); connection.setRequestProperty(X-Requested-With, XMLHttpRequest); //開啟輸入流 connection.setDoInput(true); //開啟輸出流 connection.setDoOutput(true); //關閉緩存 connection.setUseCaches(false); // 設置編碼 connection.setRequestProperty(Charset, utf-8); connection.setRequestProperty(connection, keep-alive); connection.setRequestProperty(user-agent, Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)); //設置內容類型及定義BOUNDARY connection.setRequestProperty(Content-Type, multipart/form-data + ;boundary= + BOUNDARY); //獲取輸出流 DataOutputStream dos = new DataOutputStream(connection.getOutputStream()); StringBuffer sb = null; String result = ; String paramStr; //發送非文件參數 if (mParams != null && mParams.size() > 0) { Iterator it = mParams.keySet().iterator(); while (it.hasNext()) { sb = null; sb = new StringBuffer(); String key = it.next(); Object value = mParams.get(key); sb.append(PREFIX).append(BOUNDARY).append(LINE_END); sb.append(Content-Disposition: form-data; name=) .append(key).append().append(LINE_END) .append(LINE_END); sb.append(value).append(LINE_END); paramStr = sb.toString(); dos.write(paramStr.getBytes()); dos.flush(); } } paramStr = null; //發送文件參數,讀取文件流寫入post輸出流 if (mFileParams != null && !mFileParams.isEmpty()) { Iterator > fileIter = mFileParams .entrySet().iterator(); while (fileIter.hasNext()) { sb = null; sb = new StringBuffer(); Entry entry = fileIter.next(); String fileKey = entry.getKey(); String filePath = entry.getValue(); File file = new File(filePath); if (file.exists() == false) { throw new FileNotFoundException(); } //設置邊界標示,設置 Content-Disposition頭傳入文件流 sb.append(PREFIX).append(BOUNDARY).append(LINE_END); sb.append(Content-Disposition:form-data; name= + fileKey + ; filename= + file.getName() + + LINE_END); sb.append(Content-Type: + CONTENT_TYPE + LINE_END); sb.append(LINE_END); dos.write(sb.toString().getBytes()); InputStream is = new FileInputStream(file); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); } is.close(); dos.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END) .getBytes(); dos.write(end_data); dos.flush(); } } dos.close(); int res = getResponseCode(); //返回成功 if (res == 200) { InputStream input = conn.getInputStream(); StringBuffer sb1 = new StringBuffer(); int ss; while ((ss = input.read()) != -1) { sb1.append((char) ss); } result = sb1.toString(); return result; } else { } } catch (MalformedURLException e) { Log.i(TAG, MalformedURLException error); } catch (IOException e) { Log.i(TAG, IOException error); } return null; }
接著上一篇博客,上一篇博客跟大家分享了三種開始頁面的定時跳轉,根據項目需求接下來就說一下向導頁面吧!幾乎每一個APP都有自己的向導頁面,一般都是第一次安裝的時或者第一次進
Android日常開發中,對於下拉與上拉刷新控件的使用非常之頻繁。一般都會采用第三方庫,但是下拉刷新做到簡單優雅並不是太多,甚至有的兼容性都存在問題。這個是不能接受的。最
類似QQ分組的樣子,實現tableView的折疊與展開。其實要做這個效果我先想到的是在tableView中再嵌套多個tableView,這個想法實現起來就有點難了。所以還
先看看效果圖:首先過程中碰到的幾個問題: 1、對 EditText 進行自定義背景 2、運行時自動 EditText 自動獲得焦點 3、在獲