• 沒有找到結果。

第三章 SaysApp 的設計與實現

3.3. 使用者端

3.3.3. SaysApp 的程式設計

SaysApp 會用到的 Class 和 Interface,在 Java 程式碼的最前面用 import 宣 告如下:

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.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.util.EntityUtils;

import android.graphics.drawable.Drawable;

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;

import com.google.android.maps.GeoPoint;

26

import com.google.android.maps.ItemizedOverlay;

import com.google.android.maps.MapActivity;

import com.google.android.maps.MapController;

import com.google.android.maps.MapView;

import com.google.android.maps.MyLocationOverlay;

import com.google.android.maps.OverlayItem;

宣告 SaysApp 程式繼承 MapActivity 類別,再在程式中宣告發言按鈕、名 稱輸入框、訊息輸入框、地圖、地圖控制器、自己地理位置的圖層、標記資訊 的圖層、字串陣列等物件。

public class SaysApp extends MapActivity { private Button sayButton;

private EditText nameET;

private EditText messageET;

private MapView mView;

private MapController mControl;

private MyLocationOverlay mlOverlay;

private MarkerOverlay saysoverlay;

private String[] stringArray;

27

當 SaysApp 程式開始執行的時候,先要設定程式所使用的 ContentView(介 面),然後用 findViews()方法設定介面中的元件與程式中的物件的對應,最後 用 initMapView()方法起始地圖。

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.main);

findViews();

initMapView();

定義 findViews()方法:設定介面中的 4 個元件與程式中的 4 個物件的對 應。

private void findViews() {

sayButton = (Button) findViewById(R.id.sayButton);

nameET = (EditText) findViewById(R.id.nameET);

messageET = (EditText) findViewById(R.id.messageET);

mView = (MapView) findViewById(R.id.mView);

}

28

定義 initMapView()方法:設定內建縮放控制器,設定初始縮放等級為 19

(最大為 21),以自己的地理位置為地圖的中心,將自己地理位置的圖層 mlOverlay(一個藍點)疊在 Google Maps 之上。

private void initMapView() {

mView.setBuiltInZoomControls(true);

mControl = mView.getController();

mlOverlay = new MyLocationOverlay(this, mView);

mlOverlay.runOnFirstFix(new Runnable() {

public void run() {

Toast.makeText(SaysApp.this, getString(R.string.howto1), Toast.LENGTH_LONG).show();

Toast.makeText(SaysApp.this, getString(R.string.howto2), Toast.LENGTH_LONG).show();

29

設定發言按鈕:當按鈕被按下,首先檢查名稱輸入框及訊息輸入框,是否 未被輸入或含有換行字元,若無錯誤輸入,則開始執行 sync()方法同步資料,

及 mark()方法標記資訊。

sayButton.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

String name = nameET.getText().toString().trim();

String message = messageET.getText().toString().trim();

if (name.contains("\n") || message.contains("\n")

|| name.equals("") || message.equals("")

|| name.equals("You")

|| message.equals("Say something!")) {

Toast.makeText(SaysApp.this, getString(R.string.suggestion), Toast.LENGTH_LONG).show();

30

定義 sync()方法:開啟伺服器上的POST.PHP 以存取資料庫,先將使用者

的名稱 name、訊息 message、經度longitude、緯度latitude插入 contacts 資料表。

再將網頁回應的字串,即 contacts 資料表的查詢結果,用換行字元做為分割依 據,存入字串陣列stringArray。

private void sync() {

HttpClient httpclient = new DefaultHttpClient();

HttpPost httppost = new HttpPost("http://11.22.33.44/POST.PHP");

try {

List<NameValuePair> nameValuePairs = new

ArrayList<NameValuePair>(4);

nameValuePairs.add(new BasicNameValuePair("name",

nameET.getText().toString().trim()));

nameValuePairs.add(new BasicNameValuePair("message",

messageET.getText().toString().trim()));

nameValuePairs.add(new BasicNameValuePair("longitude", String .valueOf(mlOverlay.getMyLocation().getLongitudeE6())));

nameValuePairs.add(new BasicNameValuePair("latitude", String .valueOf(mlOverlay.getMyLocation().getLatitudeE6())));

httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

HttpResponse httpresponse = httpclient.execute(httppost);

String httpresponseString = EntityUtils.toString(httpresponse .getEntity());

stringArray = httpresponseString.split("\n");

31

} catch (ClientProtocolException e) { } catch (IOException e) {

} }

定義 mark()方法:使用 Android 作業系統內建的人形圖示來標示資訊,將 標記資訊的圖層 saysoverlay疊在 Google Maps 之上。

private void mark() {

Drawable marker = getResources().getDrawable(

android.R.drawable.ic_menu_myplaces);

saysoverlay = new MarkerOverlay(marker);

mView.getOverlays().add(saysoverlay);

}

宣 告標記 資訊的 圖層類 別: 宣告標記資訊的圖層 saysoverlay 的 類別 MarkerOverlay 繼承 ItemizedOverlay<OverlayItem>類別,使用迴圈將字串陣列

stringArray 內的資訊一一填入標記資訊的對應欄位,最後設定當使用者觸碰資

訊所在的地理位置時,浮現出該資訊內的名稱及訊息。

private class MarkerOverlay extends ItemizedOverlay<OverlayItem> { private List<OverlayItem> olItems = new ArrayList<OverlayItem>();

public MarkerOverlay(Drawable defaultMarker) { super(boundCenterBottom(defaultMarker));

int saysIndex = 0;

32

do {

GeoPoint geopoint = new GeoPoint(

Integer.valueOf(stringArray[saysIndex + 4]), Integer.valueOf(stringArray[saysIndex + 3]));

olItems.add(new OverlayItem(geopoint,

stringArray[saysIndex+ 1], stringArray[saysIndex + 2]));

saysIndex = saysIndex + 5;

} while (saysIndex < stringArray.length);

populate();

}

@Override

protected OverlayItem createItem(int i) { return olItems.get(i);

}

@Override

public int size() {

return olItems.size();

}

@Override

protected boolean onTap(int index) { Toast.makeText(

SaysApp.this,

olItems.get(index).getTitle() + "\nsays\n"

+ olItems.get(index).getSnippet(), Toast.LENGTH_LONG).show();

33

return true;

} }

在 Java 程式碼的最後面,設定 SaysApp 當暫停及回復時,停用及啟用定位 功能。以及設定位移路徑不顯示。

@Override

protected void onResume() { super.onResume();

mlOverlay.enableMyLocation();

}

@Override

protected void onPause() { super.onPause();

mlOverlay.disableMyLocation();

}

@Override

protected boolean isRouteDisplayed() { return false;

}

34

SaysApp 的 Java 程式碼如以上所述。另外,在 AndroidManifest.XML 權限 清單中,要加入以下權限設定,才能使用 GPS 定位、AP 或基地台定位、模擬 器定位、網路連線、Google Maps。

<uses-permission android:name=

"android.permission.ACCESS_FINE_LOCATION" />

<uses-permission android:name=

"android.permission.ACCESS_COARSE_LOCATION" />

<uses-permission android:name=

"android.permission.ACCESS_MOCK_LOCATION" />

<uses-permission android:name=

"android.permission.INTERNET" />

<uses-library android:name=

"com.google.android.maps" />

35

相關文件