Android中提供了不少進行Server-Client 連線的方法,其中透過HTTP連線的方式有了相當健全的API可供使用,但基於安全考量,在Android SDK 3.0之後強制要求在Android中使用HTTP時不可以在主UI執行序中執行,必須在子執行序中運作。相關AIP可看官網解說(Developers)
本篇將針對HTTP Get 及HTTP Post 來撰寫,兩種方法將會分別寫在Service中,其中HTTP Post將會透過Handler的將Message丟給MainActivity,讓主UI執行序可以進行一些相對應的動作(例如:訊息顯示等),由於開發環境是在Ubuntu中,所以若還不會在Ubuntu中建置及設定Apache2及php的可以參考這篇『Ubuntu 安裝及設定 Apache 2 & PHP 5』。
首先,在開發Android App前先建立我們Server端的連線頁面。
- HTTP Get
我們直接使用行政院(Open Data)提供的資料來進行Http Get存取所需的Url。
- HTTP Post
先寫一個簡易的php檔來當Server端的接收端,此php檔在接收到"data"訊息後會將傳上來的資料再回傳回去,要注意的是此檔案要放在『 /var/www/html/ 』中,此目錄在安裝Apache2之後會自動產生,或者是看自己設定網頁存取的資料夾為哪個來作位置修改。
簡易的php檔如下,而檔名則隨各自喜愛去命名(name.php)。
<?php
//Setting Utf-8 encoding
header("Content-Type:text/html; charest=utf-8");
$data=$_POST['data'];
echo"data=".$data;
?>
在開始講解HTTP Get 和 Post 的程式碼前有一個很重要的部份,要記得在App中的『AndroidManifest.xml』加入網路存取的授權,否則無法網路功能則無法正常存取。
- Get 使用步驟
1. 建立HTTP Client物件:
HttpClient httpClient = new DefaultHttpClient();
2. 建立HTTP Get物件並給予要連線的Url:
HttpGet get = new HttpGet(Url);
3. 使用client進行get後,Server會回傳HttpResponse:
HttpResponse response = httpClient.execute(get);
4. 取得回傳的資料實體:
HttpEntity resEntity = response.getEntity();
5. 將資料轉為字串使用:
String result = EntityUtils.toString(resEntity);
- Post 使用步驟
1. 建立HTTP Client物件:
HttpClient httpClient = new DefaultHttpClient();
2. 建立HTTP Post物件並給予要連線的UrL:
HttpPost httpRequest = new HttpPost(postUrl);
3. 要透過Post傳到Server的參數(params):
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("data", strTxt));
4. 使用Post來傳送參數給Server(記得設定為UTF8格式):
httpPost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
5. 取得Server回傳的HttpResponse:
HttpResponse httpResponse = new DefaultHttpClient().execute(httpPost);
6. 取得回傳的資料實體(需自行轉UTF8格式):
String strResult = EntityUtils.toString(httpResponse.getEntity(),HTTP.UTF_8);
特別注意的是,若是在Server端回傳的資料不是UTF8格式的話,我們接收資料後要自行轉UTF8格式,否則該資料在顯示時會是亂碼。
(以上資料來自Tony Blog,Post後面部份有小修改,請依個人習慣參考使用)
接下來為Android App專案部份:
- AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="terence.http_post_get" >
<!-- 加入網路使用權限 -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".Http_Get"
android:enabled="true"
android:exported="true" >
</service>
<service
android:name=".Http_Post"
android:enabled="true"
android:exported="true" >
</service>
</application>
</manifest>
註:記得在App中的『AndroidManifest.xml』加入網路存取的授權,否則無法網路功能則無法正常存取。
- MainActivity.java
package terence.http_post_get;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements View.OnClickListener{
//設定HTTP Get & Post要連線的Url
private String postUrl = "http://192.168.2.100/abc.php";
private String getUrl = "http://opendata.epa.gov.tw/ws/Data/AQX/?$format=xml";
private EditText txtMessage;
private Button postBtn;
private Button getBtn;
private String msg = null; //存放要Post的訊息
private String result; //存放Post回傳值
Http_Post HP;
Http_Get HG;
static Handler handler; //宣告成static讓service可以直接使用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HG = new Http_Get();
HP = new Http_Post();
txtMessage = (EditText) findViewById(R.id.txt_message);
postBtn = (Button) findViewById(R.id.http_post_btn);
getBtn = (Button) findViewById(R.id.http_get_btn);
//讓多個Button共用一個Listener,在Listener中再去設定各按鈕要做的事
postBtn.setOnClickListener(this);
getBtn.setOnClickListener(this);
//接收service傳出Post的到的回傳訊息,並透過Toast顯示出來
handler = new Handler(){
public void handleMessage(Message msg){
switch (msg.what){
case 123:
String ss = (String)msg.obj;
Toast.makeText(MainActivity.this, ss,Toast.LENGTH_LONG).show();
break;
}
}
};
}
//依照按下的按鈕去做相對應的任務
public void onClick(View v){
switch (v.getId()){
case R.id.http_get_btn:
HG.Get(getUrl);
break;
case R.id.http_post_btn:
if (txtMessage != null) {
//取得EditText的內容
msg = txtMessage.getEditableText().toString();
HP.Post(msg,postUrl);
}
break;
}
}
}
- HttpGet.java
package terence.http_post_get;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class Http_Get extends Service {
private String getUrl;
public void Get(String url){
this.getUrl = url;
new Thread(new Runnable() {
@Override
public void run() {
//建立HttpClient物件
HttpClient httpClient = new DefaultHttpClient();
//建立Http Get,並給予要連線的Url
HttpGet get = new HttpGet(getUrl);
//透過Get跟Http Server連線並取回傳值,並將傳值透過Log顯示出來
try {
HttpResponse response = httpClient.execute(get);
HttpEntity resEntity = response.getEntity();
Log.d("Response of GET request", EntityUtils.toString(resEntity));
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
- HttpPost.java
package terence.http_post_get;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Message;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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 java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Http_Post extends Service {
String strTxt=null;
String postUrl=null;
String strResult=null;
public void Post(String StrTxt, final String PostUrl){
this.strTxt = StrTxt;
this.postUrl = PostUrl;
new Thread(new Runnable() {
@Override
public void run() {
//建立HttpClient物件
HttpClient httpClient = new DefaultHttpClient();
//建立一個Post物件,並給予要連線的Url
HttpPost httpPost = new HttpPost(postUrl);
//建立一個ArrayList且需是NameValuePair,此ArrayList是用來傳送給Http server端的訊息
List params = new ArrayList();
params.add(new BasicNameValuePair("data", strTxt));
try{
//發送Http Request,內容為params,且為UTF8格式
httpPost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
//接收Http Server的回應
HttpResponse httpResponse = new DefaultHttpClient().execute(httpPost);
//判斷Http Server是否回傳OK(200)
if(httpResponse.getStatusLine().getStatusCode() == 200){
//將Post回傳的值轉為String,將轉回來的值轉為UTF8,否則若是中文會亂碼
strResult = EntityUtils.toString(httpResponse.getEntity(),HTTP.UTF_8);
Message msg = Message.obtain();
//設定Message的內容
msg.what = 123;
msg.obj=strResult;
//使用MainActivity的static handler來丟Message
MainActivity.handler.sendMessage(msg);
}
}catch (IOException e) {
// Log exception
e.printStackTrace();
}
}}).start();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
- main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/help_txt"/>
<EditText
android:id="@+id/txt_message"
android:text="@string/txt_message_hint"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/http_get_btn"
android:text="@string/http_get"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/http_post_btn"
android:text="@string/http_post"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
- strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">HTTP_POST_GET</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="help_txt">請輸入要Post的內容</string>
<string name="txt_message_hint">請輸入文字</string>
<string name="http_get">Http Get</string>
<string name="http_post">Http Post</string>
</resources>
程式執行結果
- Http Get
- Http Post

As said previously, there are also many types of online games that can be played on Android. I really like it, and I look forward to hearing from you next. Thank you for the information about the most popular online games this year. For more detailed information, please visit our website for further informationhttps://clarogaming.gg/
Gacor Slot is an internet-based gambling club that presents many games. Regardless of whether you tend to play exemplary gambling machines or best-in-class video rooms. I really like it, and I look forward to hearing from you next. Thank you for the information about the most popular online game players this year. For more detailed information, please visit our website for further information https://rumahno1.com/
By playing on the official Gacor slot, you will have the opportunity to get a jackpot in every jackpot release. I really like it, and I look forward to hearing from you next. Thank you for the information about the most popular online game players this year. For more detailed information, please visit our website for further information https://mezup88.com/