**************************
2012.08.13版主回覆:
底下好多留言都詢問,奇怪?怎麼模擬器上都出現文字
然後網頁上沒出現?
不要再相信沒有事實根據的說法了 (大誤
不要再說沒有小弟不才,沒有爬文
請移步至新版:
http://j796160836.pixnet.net/blog/post/30577968
個人還是建議從本篇看起,概念比較清楚
**************************
最近常常被問到這些問題
Android要怎麼接MySQL資料庫呀? MySQL在網路上
Android怎麼接上雲端的資料庫?
Android怎麼傳送表單內容?
這些答案都在這裡
網路上的資料庫,不太容易,也不建議直接與資料庫做溝通
因為涉及到資訊安全的東西
可以用網頁來做中間的介面,讓二者產生關聯
做類似WebServices的東西
(雖然不是真正的WebServices,但其角色是類似的)
--------------------------------------------------------------------
伺服器端
你可以簡單寫個印字串的程式,如果收到POST的封包
就印出其內容
如果是PHP可能這樣寫
<?php
//宣告utf-8的編碼
header("Content-Type:text/html; charset=utf-8");
$data=$_POST['data'];
echo "data=".$data;
?>
把寫好程式,取名httpPostTest.php
把他擺到htdoc底下 (windows)
或是/var/www/ (ubuntu)
或是/var/www/html (Fedora, Cent OS)
用ASP可能這樣寫
<%@ LANGUAGE=VBScript CodePage=950%>
<%
data=request("data")
response.write "data="&data
%>
不管如何,請照你的伺服器語言撰寫
--------------------------------------------------------------------
Android手機端
可以用範例程式碼來解決問題
這些範例仿間找的到
因為過於複雜,所以我又重新整理了其範例給大家看
關鍵程式碼不到5行,但重點是在於你對Android的UI介面認識與否
和動態網頁的語言的熟練度
--------------------------------------------------------------------
照慣例,文字要放在string.xml裡
/res/values/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">httpPostTest</string>
<string name="help_txt">請輸入文字以便使用POST傳送:</string>
<string name="txt_message_hint">請輸入文字</string>
<string name="send">送出</string>
</resources>
--------------------------------------------------------------------
看一下Layout檔
/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/help_txt"
/>
<EditText
android:id="@+id/txt_message"
android:hint="@string/txt_message_hint"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/send_btn"
android:text="@string/send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
這裡沒甚麼特別,就是一個EditText來讓使用者能打入資料
然候一個按鈕讓系統傳送封包到寫死的網址路徑
--------------------------------------------------------------------
程式碼要上了
main.java
package com.J_Test.httpPostTest;
/*
* ====httpPostTest範例====
* 1. 請先確認Apache有沒有正確執行
* 2. 放入以下PHP代碼到htdoc資料夾中(或是/var/www/)等路徑
*
<?php
//宣告utf-8的編碼
header("Content-Type:text/html; charset=utf-8");
$data=$_POST['data'];
echo "data=".$data;
?>
*
* 3. 修改uriAPI的IP和檔案名稱為正確 (請用電腦對外之IP)
* (不可用127.0.0.1因為Android手機上也有本機位址)
*
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
publicclass main extends Activity implements OnClickListener
{
private EditText txtMessage;
private Button sendBtn;
private String uriAPI = "http://192.168.1.3/httpPostTest.php";
@Override
publicvoid onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtMessage = (EditText) findViewById(R.id.txt_message);
sendBtn = (Button) findViewById(R.id.send_btn);
if (sendBtn != null)
{
sendBtn.setOnClickListener(this);
}
}
@Override
publicvoid onClick(View v)
{
if (v == sendBtn)
{
String msg = null;
if (txtMessage != null)
{
msg = txtMessage.getEditableText().toString();
String result = sendPostDataToInternet(msg);
// 印出網路回傳的文字
if (result != null)
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
}
}
private String sendPostDataToInternet(String strTxt)
{
/* 建立HTTP Post連線 */
HttpPost httpRequest = new HttpPost(uriAPI);
/*
* Post運作傳送變數必須用NameValuePair[]陣列儲存
*/
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("data", strTxt));
try
{
/* 發出HTTP request */
httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
/* 取得HTTP response */
HttpResponse httpResponse = new DefaultHttpClient()
.execute(httpRequest);
/* 若狀態碼為200 ok */
if (httpResponse.getStatusLine().getStatusCode() == 200)
{
/* 取出回應字串 */
String strResult = EntityUtils.toString(httpResponse
.getEntity());
// 回傳回應字串
return strResult;
}
} catch (ClientProtocolException e)
{
Toast.makeText(this, e.getMessage().toString(), Toast.LENGTH_SHORT)
.show();
e.printStackTrace();
} catch (IOException e)
{
Toast.makeText(this, e.getMessage().toString(), Toast.LENGTH_SHORT)
.show();
e.printStackTrace();
} catch (Exception e)
{
Toast.makeText(this, e.getMessage().toString(), Toast.LENGTH_SHORT)
.show();
e.printStackTrace();
}
returnnull;
}
}
--------------------------------------------------------------------
最後是AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.J_Test.httpPostTest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- 這裡加入可以存取網路的權限 -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
這裡很重要也很容易疏忽
除了Activity要在這裡註冊外
能對外上網的權限也在這裡註冊
如果遇到
WARN/System.err(503): java.net.SocketException: Permission denied
就該發現權限少了這一項
<uses-permission android:name="android.permission.INTERNET" />
另一個權限也常用,但仿間書常常會遺漏
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
就是能夠存取手機記憶卡的權限
--------------------------------------------------------------------
這樣有看懂嗎?
主要重點在這裡
/* 建立HTTP Post連線 */
HttpPost httpRequest = new HttpPost(uriAPI);
這個HttpPost是主要的Class名,這裡要填入存取的網址
然後
在
/*
* Post運作傳送變數必須用NameValuePair[]陣列儲存
*/
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("data", strTxt));
使用系統指定的資料格式BasicNameValuePair
BasicNameValuePair在new的時候裡面為二個字串,一個是名稱,一個是值
這裡用"data"當名字,值就是剛剛讓使用者打的資料
在
/* 發出HTTP request */
httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
的 HTTP.UTF_8 可以指定編碼格式,不過要跟伺服器端相同(照我範例走的話是不用動)
--------------------------------------------------------------------
其實這個Android其實是跟以下網頁的功能是相同的
有些值你可以對照看看,相關對照的字詞都用顏色標明了
可以將它另存到httpPostTest.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Language" content="zh-tw" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF_8" />
<title>httpPostTest</title>
<head></head>
<body>
請輸入文字以便使用POST傳送:<br />
<form method="POST" action="http://192.168.1.3/httpPostTest.php">
<input type="text" name="data" size="20" value="請輸入文字" /><br />
<input name="Submit1" type="submit" value="送出" /><br />
</form>
</body>
</html>
--------------------------------------------------------------------
延伸
其實網頁大多喜歡把很多功能做在一個檔裡,就是用一個隱藏值來判斷現在進行到那個階段
本例用op當階段的旗標
PHP版:
請輸入文字以便使用POST傳送:<br />
<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="text" name="data" size="20" value="請輸入文字" /><br />
<input type="hidden" name="op" value="showValue" />
<input name="Submit1" type="submit" value="送出" /><br />
</form>
ASP版:
請輸入文字以便使用POST傳送:<br />
<form method="POST" action="<%=Request.ServerVariables("PATH_INFO")%>">
<input type="text" name="data" size="20" value="請輸入文字" /><br />
<input type="hidden" name="op" value="showValue" />
<input name="Submit1" type="submit" value="送出" /><br />
</form>
--------------------------------------------------------------------
不過還是再三的提醒
範例程式碼很簡陋,指是要讓大家看懂其中的語法
真正寫程式使用的時候
要記得在伺服器判斷輸入的型別
更不要直接讓表單直接下SQL指令
怕被資料隱碼攻擊(SQL Injection)
這是很危險低~~~~
參考資料
Google Android SDK開發範例大全 佘志龍等人著
悅知文化
留言列表