查詢網域ip
有了DNS/DDNS,為何還要想要由網域查詢 ip呢! 原因是像華碩路由器所提供的動態轉址功能,時好時壞的。所以如果能第一次先查詢到 ip,後續直接由 ip 來進線的話,就不用怕 DDNS時好時壞的問題了。
首先由 InetAddress傳入網域名稱,再取得 hostName即可取得 ip的字串。
請注意這段程式碼一定要在新 Thread中執行,若使用 UI Thread執行,InetAddress.getByName會取得 null 物件。
fun getIp(){ Thread { try { G.ip = InetAddress.getByName(G.hostName).hostName handler.sendEmptyMessage(G.HostSuccess) } catch (e: Exception) { handler.sendEmptyMessage(G.HostError) } }.start() }
todo
傳送GET資料
Android 大都會使用 Http 協議來訪問網絡, Android 主要提供了兩種方式,分別為 HttpURLConnection及 HttpClient。在Android6.0版本中 HttpClient 已經被移除。而且HttpURLConnection是由 Google所開發,效能高, Bug 少,所以當然是要使用 HttpURLConnection。
先產生 URL物件,再由 url.openConnection產生 HttpURLConnection物件。連線後的結果,可由conn.inputStream進行讀取。
conn.readTimeout=5000 可防止網路臨時中斷而進入孤立連線,單位為ms。也就是說5秒後,沒有取得回應,就會發生 Exception。
當由 conn.inputStream 取得 InputStream 物件時,系統會先自動觸發 conn.connect()函數開始執行連線。然後就可以由 inputStream讀取回應了。
Thread{
try {
val cmd =
"http://${G.ip}/dispatch/delete_case.php?id=%s".format(roadcase["id"])
val url = URL(cmd)
val conn = url.openConnection() as HttpURLConnection
conn.requestMethod = "GET"
conn.readTimeout = 5000
conn.doInput=true
val inputStream = conn.inputStream
val br = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
var lines=StringBuffer()
do{
val line=br.readLine()
if(line==null)break
lines.append(line)
}while(true)
if (lines.contains("success")) {
handler.sendEmptyMessage(What_success)
} else {
handler.sendEmptyMessage(What_delete_error)
}
}
catch(e:Exception){
handler.sendEmptyMessage(What_Internet_error)
}
}.start()
todo
傳送POST資料
POST 則是多了 DataOutputStream 連線,將要傳遞的資料,傳入 dos中。
大部份的網站都說,要傳送純文字資料,必需將 Content-Type 設定為 “application/x-www-form-urlencoded”。但本人測試的結果,要嘛就是不要設定,不然就要設定為 null。
//conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
conn.setRequestProperty("Content-Type", null)
底下為完整代碼
Thread{ try{ val url=URL("http://${G.ip}/dispatch/test.php") val conn=url.openConnection() as HttpURLConnection conn.readTimeout=5000 conn.connectTimeout=5000 conn.doInput=true conn.doOutput=true conn.useCaches=false conn.requestMethod="POST" conn.setRequestProperty("Connection", "Keep-Alive") conn.setRequestProperty("Charset", "utf-8") conn.setRequestProperty("Content-Type", null) val dos= DataOutputStream(conn.outputStream) var sb=StringBuffer() sb.append("userAccount=") sb.append(URLEncoder.encode("張無忌", "UTF-8")) dos.writeBytes(sb.toString()) val inputStream=conn.inputStream val br = BufferedReader(InputStreamReader(inputStream, "UTF-8")) var lines=StringBuffer() do{ var line = br.readLine() if (line==null)break lines.append(line) }while(true) Log.d("Thomas", lines.toString()) dos.flush() dos.close() if (lines.contains("success"))handler.sendEmptyMessage(G.Pothole_upload_success) else handler.sendEmptyMessage(G.Pothole_upload_error) } catch(e:Exception){ handler.sendEmptyMessage(G.Pothole_upload_timeout) } }.start()
傳送POST圖片
下面的例子,是將圖片讀入,然後寫入到 dos中。至於文字資料,則採用 GET的方式由網址傳入。
val url=URL("http://${G.ip}/dispatch/upload_pothole.php?id=${id}")
Thread{
try{
val lineEnd="\r\n"
val prefix="--"
val boundary= UUID.randomUUID().toString()
val maxBufferSize=1*1024*1024
val file=File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "%s/%s".format(G.photoDir,fileName))
val fis=FileInputStream(file)
val conn=url.openConnection() as HttpURLConnection
conn.readTimeout=5000
conn.connectTimeout=5000
conn.doInput=true
conn.doOutput=true
conn.useCaches=false
conn.requestMethod="POST"
conn.setRequestProperty("Connection", "Keep-Alive")
conn.setRequestProperty("Charset", "utf-8")
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary)
val dos= DataOutputStream(conn.outputStream)
dos.writeBytes(prefix + boundary + lineEnd)
dos.writeBytes(String.format("Content-Disposition: form-data; name=\"file\";filename=\"%s\"%s", fileName, lineEnd))
dos.writeBytes(lineEnd)
var bytesAvailable=fis.available()
var bufferSize=Math.min(bytesAvailable, maxBufferSize)
val buffer=ByteArray(bufferSize)
var bytesRead=fis.read(buffer, 0, bufferSize)
while(bytesRead>0){
dos.write(buffer, 0, bufferSize)
bytesAvailable=fis.available()
bufferSize=Math.min(bytesAvailable, maxBufferSize)
bytesRead=fis.read(buffer, 0, bufferSize)
}
dos.writeBytes(lineEnd)
dos.writeBytes(prefix + boundary + prefix + lineEnd)
val inputStream=conn.inputStream
val br = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
var lines=StringBuffer()
do{
var line = br.readLine()
if (line==null)break
lines.append(line)
}while(true)
fis.close()
dos.flush()
dos.close()
if (webResponse.contains("success"))handler.sendEmptyMessage(G.Pothole_upload_success)
else handler.sendEmptyMessage(G.Pothole_upload_error)
}
catch(e:Exception){
handler.sendEmptyMessage(G.Pothole_upload_timeout)
}
}.start()
todo