【教學】Android 與 Web 的互動

各位 Android 開發員是否曾想抓取某網頁的資料或是與自己寫的 Web 作互動,甚至是將資料存到你自己的 MySQL 或是其他資料庫呢?小編聽見了大家的心聲,今天依舊利用幾個簡單的步驟就讓大家學會如何與網頁作互動哦!

首先在開始 Coding 之前,如果你是要跟自己開發的網頁作互動的話,那你必須要先安裝好 Apache,如果單純要抓其他網頁資料的話,這個步驟可已省略掉,小編在這個範例教學中利用 JSP 寫一個樣本,因此我先安裝 Tomcat 作為我的 HTTP Server,記得安裝好要把 Tomcat 啟動哦!


現在我們先來編寫網頁端的程式碼吧!
File Name:receiver01.jsp
<%@ page contentType="text/html;charset=UTF-8" %>

<%
    // 設定編碼
    request.setCharacterEncoding("utf-8");

    // 取得 name 欄位的資料
    String name = request.getParameter("name");

    // 將訊息列印出來
    out.println("Web 端收到的訊息為 :\n"+name);
%>


存檔的時候有三個重點,第一點是將檔案名稱後方加副檔名,這裡為「.jsp」,第二點是要將存檔類型設為「所有檔案」,第三點是要設定編碼型態,這裡設定為「UTF-8」。而存檔路徑的選擇就是在你們安裝目錄下的「...\webapps」裡頭,當然也可以設定子目錄,此為「...\webapps\MrRayBox\receiver01.jsp」。


接著讓我們來測試看看這個檔案是否執行成功,請大家在瀏覽器的網址列上打入你們的「IP:Port/File Name」,如果不知道 IP 的話,請進入您可愛的 Dos 介面輸入 ipconfig 的指令,如果您是使用 Linux 的話,則要進入終端機模式,改為輸入 ifconfig 的指令,而 Port 的部分,如果在安裝時,是使用預設的話,一般為 8080 ,因此小編在網址列輸入
http://192.168.1.139:8080/MrRayBox/receiver01.jsp?name=web%20file%20is%20ok」,便跑出了這樣的結果!


經過我們一系列 Web 的測試之後,我們終於要開始進行 Android 的部份啦!廢話不多說,首先大家先把 xml 給佈置好,以下是今天的範本。
Path:res/layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10">

            <requestFocus />
        </EditText>

        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Send" />
    </LinearLayout>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize="20dp" />
</LinearLayout>


最後呢!是關於程式的部分,在這個部份我們將會對物件進行實體化,並且進行操作設定。
File Name:WebJspGet
@SuppressLint("HandlerLeak")
public class WebJspGet extends Activity implements OnClickListener {

    /**
     * 注意 !! 讀資料要去設定
     * Path : AndroidManifest.xml > Permissions > Add... > User
     * Permission > Name > android.permission.INTERNET
     **/

    EditText edt_name;
    Button btn_submit;
    TextView tv_result;
    String result = "";
    String data = "";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        edt_name = (EditText) this.findViewById(R.id.name);
        btn_submit = (Button) this.findViewById(R.id.btn);
        tv_result = (TextView) this.findViewById(R.id.text);

        btn_submit.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        data = processData(edt_name.getText().toString());

        // 執行緒, 2.3以上的版本需要執行緒輔助才可以去讀取網頁資料
        new Thread(){
            @Override
            public void run() {

                // 網頁的 URL
                String url = "http://192.168.1.139:8080/MrRayBox/receiver01.jsp?name="+data;

                // 開始進入網路的部分 
                result = getContent(url);

                // 所有執行緒皆不能直接將資料傳送給 UI, 所以需要 Handler 幫忙轉送出去
                handler.sendEmptyMessage(0);
            }
        }.start();
    }

    public String processData(String data){
        /** 處理空白字元的問題 **/

        char[] temp = data.toCharArray();
        data = "";
        for(int i=0;i<temp.length;i++){
            if(temp[i] == ' ')
                data += "%20";
            else
                data += temp[i];
        }
        return data;
    }

    public String getContent(String url){
        // 客戶端處理http協定的物件, 簡單來說就是傳送資料的方法
        HttpClient client = new DefaultHttpClient();

        // 設定 url 及指定傳送方法, 有 get 或 post 兩種
        HttpGet httpGet = new HttpGet(url);

        try{
            // 丟 request 過去並得到 response
            HttpResponse response = client.execute(httpGet);

            // 取得封包
            HttpEntity entity = response.getEntity();

            // 變成可以讀的輸入串流, 簡單來說就是接收資料的管道
            InputStream is = entity.getContent();

            // 緩衝區, 整理字串資料  
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));

            String s = "";
            String line = null;
            while((line = reader.readLine()) != null){
                s+= line+"\n";
            }
            return s;

        }catch(Exception e){
            e.printStackTrace();
        }

        return null;
    }

    // 處理執行緒丟過來的資料
    Handler handler = new Handler() {

        // 當有不同類型的資料需要區分時, 可以用 Tag 去加以判斷
        public void handleMessage(Message mag) {
            tv_result.setText(result);
        }

    };
}


大家將程式給打完之後,先不要著急的把這個程式給 run 下去哦!還有幾個地方沒設定完。首先是這支程式的編碼方式,麻煩大家點選您的程式,接著在 Eclipse 上方功能列的部分點選「edit > set Encoding... > Other:UTF-8」,點選「OK」。再繼續設定網路權限的設定,請大家點選專案裡的「AndroidManifest.xml > Permissions > Add... > User Permission > Name > android.permission.INTERNET」,接著儲存起來就可以 run 囉!

以下是這支程式執行的過程,上圖為執行前,下圖為執行後的結果。

執行前,程式尚未執行

執行後,Web 收到訊息之後,回傳值給手機


6 則留言:

  1. 不好意思
    我照您說的一步一步做
    但是按下 Send 鈕後卻什麼也沒出現
    是為什麼呢???

    回覆刪除
    回覆
    1. 可能在 receiver01.jsp 的部分沒弄好
      你在網址列敲
      http:// 你的IP : 你的port號 /MrRayBox/receiver01.jsp?name=web%20file%20is%20ok
      網頁有出現回應嗎?

      刪除
  2. 請問要從手機android傳的資料
    不能傳中文嗎?

    回覆刪除
    回覆
    1. 可以呀
      編碼方式統一就可以了

      刪除
    2. 感謝,中文編碼的部分已經OK了
      那再請問一下,如果我要傳送2個以上的資料
      要怎麼修改呢

      刪除
    3. 我的做法是用 JSON 傳送至手機
      可是傳至 Server 是利用迴圈將要傳的資料寫好, 然後再傳送
      像是這樣
      http:// 你的IP : 你的port號 /MrRayBox/receiver01.jsp?name1=data1&name2=data2...
      依此類推

      刪除