14 google
This presentation is the property of its rightful owner.
Sponsored Links
1 / 94

第 14 章 Google 地圖與定位服務 PowerPoint PPT Presentation


  • 40 Views
  • Uploaded on
  • Presentation posted in: General

第 14 章 Google 地圖與定位服務. 14-1 定位服務 - 我在哪裡 14-2 地圖解碼服務 - 找出景點座標 14-3 本地服務與定位應用 -GPS 景點防撞雷達 14-4 使用 Google Maps API-My 地圖 14-5 標記 Google 地圖 - 追蹤個人行蹤. 14-1 定位服務-我在哪裡. 14-1-1 Android 的定位服務與座標 14-1-2 使用定位服務 - 我在哪裡. 14-1-1 Android 的定位服務與座標 - 說明.

Download Presentation

第 14 章 Google 地圖與定位服務

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


14 google

第14章 Google地圖與定位服務

  • 14-1 定位服務-我在哪裡

  • 14-2 地圖解碼服務-找出景點座標

  • 14-3 本地服務與定位應用-GPS景點防撞雷達

  • 14-4 使用Google Maps API-My地圖

  • 14-5 標記Google地圖-追蹤個人行蹤


14 google

14-1 定位服務-我在哪裡

  • 14-1-1 Android的定位服務與座標

  • 14-1-2 使用定位服務-我在哪裡


14 1 1 android

14-1-1 Android的定位服務與座標-說明

  • Android行動裝置結合定位功能和Google地圖建立的「位置感知服務」(Location-based Service,LBS),這是一項十分實用的功能,LBS應用程式可以追蹤你的位置和提供一些額外服務,例如:找出附近的咖啡廳、停車場、自動櫃員機或加油站等。

  • Android作業系統提供LocationManager類別的定位服務來幫助我們存取行動裝置目前的定位資料,包含:緯度(Latitude)、經度(Longitude)和高度(Altitude)等。


14 1 1 android1

14-1-1 Android的定位服務與座標-種類

  • GPS定位提供者:提供者名稱字串為"gps",它是使用GPS(Global Positioning System)的衛星訊號來定位,可以提供精確的位置資訊,但是無法收到衛星訊號的室內並無法使用。

  • 網路定位提供者;提供者名稱字串為"network",它是直接使用電信公司基地台來執行三角定位,其提供的位置資訊較不精確,但是可以在室內使用。


14 1 1 android2

14-1-1 Android的定位服務與座標-座標

  • 定位服務最主要的目的是找出行動裝置目前位置的經緯度座標,經緯度是經度與緯度合稱的座標系統,也稱為地理座標系統,它是使用三度空間的球面來定義地球表面各點的座標系統,能夠標示地球表面上的任何一個位置。經度與緯度的說明,如下所示:

    • 緯度:地球表面某一點距離地球赤道以南或以北的度數,其值為0至90度,赤道以北的緯度叫北緯(符號為N);赤道以南的緯度稱南緯(符號為S)。

    • 經度:地球表面上某一點距離本初子午線(一條南北方向經過倫敦格林威治天文台舊址的子午線)以東或以西的度數,簡單的說,本初子午線的經度是0度,其他地點的經度是向東從0到180度,即東經(符號為W)或向西從0到180度,即西經(符號為E)。


14 1 2

14-1-2 使用定位服務-我在哪裡(說明)

  • 我在哪裡是定位服務的最簡單應用,可以顯示目前行動裝置的經緯度座標。


14 1 2 android

14-1-2 使用定位服務-我在哪裡步驟一:開啟和執行Android專案

  • 請啟動Eclipse IDE開啟Android專案Ch14_1_2,內含1個Java類別檔和版面配置檔main.xml,執行可以看到程式顯示目前的位置座標,按【顯示Google地圖】鈕,可以啟動Google地圖顯示此座標附近的地圖,即台北火車站,如下圖所示:


14 1 21

14-1-2 使用定位服務-我在哪裡步驟二:建立我在哪裡使用介面的版面配置

  • 我在哪裡使用介面的版面配置是定義在main.xml檔,使用LinearLayout垂直編排1個TextView和Button元件,如下所示:

    <TextView android:id="@+id/output"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"/>

    <Button android:id="@+id/button1"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="顯示Google地圖"

    android:onClick="button1_Click"/>


14 1 2 activity 1

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-1

  • 在Ch14_1_2Activity活動類別的開頭宣告成員的LocationManager和Location物件變數,如下所示:

    public class Ch14_1_2Activity extends Activity {

    private LocationManager manager;

    private Location currentLocation;

    private String best;

    }


14 1 2 activity 2

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-2

onCreate()方法

  • 在覆寫的onCreate()方法載入版面配置後,可以取得系統服務的LocationManager物件,if條件檢查是否有啟用GPS,如下所示:

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    manager = (LocationManager)getSystemService(

    LOCATION_SERVICE);

    if (!manager.isProviderEnabled(

    LocationManager.GPS_PROVIDER)) {

    AlertDialog.Builder builder = new AlertDialog.Builder(this);

    builder.setTitle("定位管理")

    .setMessage("GPS目前狀態是尚未啟用.\n"


14 1 2 activity 3

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-3

+"請問你是否現在就設定啟用GPS?")

.setPositiveButton("啟用", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

Intent i = new Intent(Settings.

ACTION_LOCATION_SOURCE_SETTINGS);

startActivity(i);

}

})

.setNegativeButton("不啟用", null).create().show();

}

}


14 1 2 activity 4

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-4

onResume()方法

  • 在覆寫onResume()方法建立Criteria物件設定如何選擇提供者,以便取得最佳或符合你需求的定位提供者,然後就可以呼叫getrBestProvider()方法取得最佳提供者字串,參數是Criteria物件,如下所示:

    @Override

    protected void onResume() {

    super.onResume();

    Criteria criteria = new Criteria();

    best = manager.getBestProvider(criteria, true);

    int minTime = 5000; // 毫秒

    float minDistance = 5; // 公尺

    if (best != null) {

    currentLocation = manager.getLastKnownLocation(best);


14 1 2 activity 5

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-5

manager.requestLocationUpdates(best, minTime,

minDistance, listener);

}

else {

currentLocation = manager.getLastKnownLocation(

LocationManager.GPS_PROVIDER);

manager.requestLocationUpdates(

LocationManager.GPS_PROVIDER,

minTime, minDistance, listener);

}

updatePosition();

}


14 1 2 activity 6

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-6

onPause()方法

  • 在覆寫onPause()方法呼叫removeUpdates()方法取消周期更新位置,如下所示:

    @Override

    protected void onPause() {

    super.onPause();

    manager.removeUpdates(listener);

    }


14 1 2 activity 7

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-7

updatePosition()方法

  • 在自訂updatePosition()方法更新TextView元件顯示的位置資訊,如下所示:

    private void updatePosition() {

    TextView output;

    output = (TextView) findViewById(R.id.output);

    if (currentLocation == null) {

    output.setText("取得定位資訊中...");

    } else {

    output.setText(getLocationInfo(currentLocation));

    }

    }


14 1 2 activity 8

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-8

LocationListener傾聽者物件

  • 使用匿名內層類別實作LocationListener介面來建立此物件,需要實作4個方法,如下所示:

    private LocationListener listener = new LocationListener() {

    @Override

    public void onLocationChanged(Location location) {

    currentLocation = location;

    updatePosition();

    }

    @Override

    public void onProviderDisabled(String provider) { }

    @Override

    public void onProviderEnabled(String provider) { }

    @Override

    public void onStatusChanged(String provider,

    int status, Bundle extras) { }

    };


14 1 2 activity 9

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-9

getLocationInfo()方法

  • 在自訂的getLocationInfo()方法可以從參數Loaction物件取得定位資訊,如下所示:

    public String getLocationInfo(Location location) {

    StringBuffer str = new StringBuffer();

    str.append("定位提供者(Provider): "+

    location.getProvider());

    str.append("\n緯度(Latitude): " +

    Double.toString(location.getLatitude()));

    str.append("\n經度(Longitude): " +

    Double.toString(location.getLongitude()));

    str.append("\n高度(Altitude): " +

    Double.toString(location.getAltitude()));

    return str.toString();

    }


14 1 2 activity 10

14-1-2 使用定位服務-我在哪裡步驟三:建立Activity活動類別使用定位服務-10

button1_Click()事件處理方法

  • button1_Click()事件處理方法可以依據目前的位置座標來啟動Google地圖,它是使用Intent物件啟動Google地圖程式,首先取得經緯度座標longitude和latitude,如下所示:

    public void button1_Click(View view) {

    float latitude = (float) currentLocation.getLatitude();

    float longitude = (float) currentLocation.getLongitude();

    String uri = String.format("geo:%f,%f?z=18", latitude, longitude);

    Intent geoMap = new Intent(

    Intent.ACTION_VIEW,Uri.parse(uri));

    startActivity(geoMap);

    }


14 1 2 androidmanifest xml

14-1-2 使用定位服務-我在哪裡步驟四:在AndroidManifest.xml新增權限

  • 因為需要使用定位服務,所以在AndroidManifest.xml檔新增2個權限,ACCESS_COURSE_LOCATION是網路定位服務,ACCESS_FINE_LOCATION是GPS定位服務,如下所示:

    <uses-permission android:name=

    "android.permission.ACCESS_COARSE_LOCATION"/>

    <uses-permission android:name=

    "android.permission.ACCESS_FINE_LOCATION"/>


14 google

14-2 地圖解碼服務-找出景點座標(說明)

  • 地圖解碼服務(Geocoding Services)可以從位置名稱、郵遞區號等資訊來找出經緯度座標,或反過來,從經緯度座標找出位置名稱或地址。

  • Android是使用Geocoder類別來處理座標轉換,相關方法的說明,如下表所示:


14 2 android

14-2 地圖解碼服務-找出景點座標步驟一:開啟和執行Android專案

  • 請啟動Eclipse IDE開啟Android專案Ch14_2,內含1個Java類別檔和版面配置檔main.xml,因為Android模擬器不支援地圖解碼服務,筆者是使用2.3版的實機來測試,其執行結果如下圖所示:


14 2 1

14-2 地圖解碼服務-找出景點座標步驟二:建立找出景點座標使用介面的版面配置-1

  • 找出景點座標使用介面的版面配置是定義在main.xml檔,使用LinearLayout垂直編排數個水平的LinearLayout,內含TextView和EditText元件輸入座標和景點名稱,如下所示:

    <LinearLayout

    android:orientation="horizontal"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content">

    <TextView

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="緯度(Latitude):"/>


14 2 2

14-2 地圖解碼服務-找出景點座標步驟二:建立找出景點座標使用介面的版面配置-2

<EditText android:id="@+id/txtLat"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="25.047924"

android:inputType="numberDecimal"/>

</LinearLayout>

  • EditText元件輸入緯度,另有2個是輸入經度和景點名稱,查詢結果的地址是顯示在Spinner元件,如下所示:

    <Spinner android:id="@+id/addresslist"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"/>

  • 至於查詢的經緯度是顯示在TextView元件,Button元件button1~3的事件處理方法為button1~3_Click()。


14 2 activity 1

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-1

  • 在Ch14_2Activity活動類別的開頭宣告成員的ArrayAdapter和Geocoder等物件變數,如下所示:

    public class Ch14_2Activity extends Activity {

    private final int maxResult = 3;

    private String addressList[] = new String[maxResult];

    private ArrayAdapter<String> adapter;

    private TextView output;

    private Geocoder geocoder;

    private EditText lat, lon;

    }


14 2 activity 2

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-2

onCreate()方法

  • 在覆寫的onCreate()方法載入版面配置後,可以取得EditText物件來取得輸入座標,如下所示:

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    lat = (EditText) findViewById(R.id.txtLat);

    lon = (EditText) findViewById(R.id.txtLong);

    output = (TextView)findViewById(R.id.output);

    geocoder = new Geocoder(this, Locale.TAIWAN);

    }


14 2 activity 3

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-3

button1_Click()事件處理方法

  • 在button1_Click()事件處理方法將經緯度座標轉換成地址,首先將經緯度的輸入字串轉換成float浮點數,如下所示:

    public void button1_Click(View view) {

    float latitude = Float.parseFloat(lat.getText().toString());

    float longitude = Float.parseFloat(lon.getText().toString());

    try {

    List<Address> listAddress = geocoder.getFromLocation(

    latitude, longitude, maxResult);

  • 程式碼呼叫Geocoder物件的getFromLocation()方法取得地址清單的List物件,參數依序是緯度、經度和最多傳回的地址數。


14 2 activity 4

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-4

  • 如果有傳回地址,就在下方if條件的程式區塊建立ArrayAdapter結合器物件,然後顯示在Spinner元件,如下所示:

    if (listAddress != null) {

    Spinner spinner = (Spinner)findViewById(R.id.addresslist);

    for (int j = 0; j < maxResult; j++) addressList[j] = "N/A";

    int index = 0;

    for (int j = 0; j < maxResult; j++) {

    Address findAddress = listAddress.get(j);

    StringBuilder strAddress = new StringBuilder();

    for (int i = 0; i <

    findAddress.getMaxAddressLineIndex(); i++) {

    String str = findAddress.getAddressLine(i);

    strAddress.append(str).append("\n");

    }

    if (strAddress.length() > 0) {

    addressList[index++] = strAddress.toString();

    }

    }


14 2 activity 5

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-5

  • 在建立addressList[]陣列後,可以將此陣列建立成ArrayAdapter結合器物件,如下所示:

    adapter = new ArrayAdapter<String>(this,

    android.R.layout.simple_spinner_item, addressList);

    adapter.setDropDownViewResource(android.R.layout.

    simple_spinner_dropdown_item);

    spinner.setAdapter(adapter);

    }

    else {

    output.setText("注意: 沒有傳回地址資料!");

    }

    } catch (Exception ex) {

    output.setText("錯誤:" + ex.toString());

    }

    }


14 2 activity 6

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-6

button2_Click()事件處理方法

  • 在button2_Click()事件處理方法將地址轉換成經緯度座標,首先取得使用者在EditText元件輸入的名稱,如下所示:

    public void button2_Click(View view) {

    EditText address = (EditText) findViewById(R.id.txtAddress);

    String addressName = address.getText().toString();

    try {

    List<Address> listGPSAddress = geocoder.

    getFromLocationName(addressName, 1);

  • 上述程式碼呼叫Geocoder物件的getFromLocationName()方法搜尋經緯度座標,第1個參數是名稱,第2個參數最多傳回幾個座標。


14 2 activity 7

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-7

  • 如果有傳回座標,就取出緯度和經度且將它顯示出來,如下所示:

    if (listGPSAddress != null) {

    double latitude = listGPSAddress.get(0).getLatitude();

    double longitude = listGPSAddress.get(0).getLongitude();

    output.setText("緯度: " + latitude +

    "\n經度: " + longitude);

    lat.setText(String.valueOf(latitude));

    lon.setText(String.valueOf(longitude));

    }

    } catch (Exception ex) {

    output.setText("錯誤:" + ex.toString());

    }

    }


14 2 activity 8

14-2 地圖解碼服務-找出景點座標步驟三:建立Activity活動類別找出景點座標-8

button3_Click()事件處理方法

  • button3_Click()事件處理方法使用Intent物件啟動Google地圖,它和第14-1-2節的button1_Click()事件處理方法相同,筆者就不重複說明。


14 2 androidmanifest xml internet

14-2 地圖解碼服務-找出景點座標步驟四:在AndroidManifest.xml新增存取Internet權限

  • 找出景點座標因為需要連線Internet,所以在AndroidManifest.xml檔需要新增INTERNET權限,如下所示:

    <uses-permission android:name="android.permission.INTERNET"/>


14 3 gps

14-3 本地服務與定位應用-GPS景點防撞雷達

  • GPS景點防撞雷達是本地服務與定位服務的應用,可以在行動裝置接近輸入的景點座標時,發出警告,其他可能的應用包含危險區域警示,和標示目標區域來檢查是否已經到達其範圍之中。


14 3 gps android

14-3 本地服務與定位應用-GPS景點防撞雷達步驟一:開啟和執行Android專案

  • 請啟動Eclipse IDE開啟Android專案Ch14_3,內含3個Java類別檔和版面配置檔main.xml,在執行前,請先在Android模擬器新增GPS硬體支援,然後就可以執行此專案,其執行結果如下圖所示:


14 3 gps gps

14-3 本地服務與定位應用-GPS景點防撞雷達步驟二:建立GPS景點防撞雷達使用介面的版面配置

  • GPS景點防撞雷達使用介面的版面配置是定義在main.xml檔,使用LinearLayout垂直編排3個水平LinearLayout,內含TextView和EditText元件輸入座標和Button按鈕元件,如下所示:

    <LinearLayout

    android:orientation="horizontal"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content">

    <TextView

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="經度(Longitude):"/>

    <EditText android:id="@+id/txtLong"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:text="121.51617"

    android:inputType="numberDecimal"/>

    </LinearLayout>


14 3 gps activity 1

14-3 本地服務與定位應用-GPS景點防撞雷達步驟三:建立Activity活動類別的事件處理方法-1

  • 在Ch14_3Activity活動類別的開頭宣告成員的EditText和TextView物件變數,如下所示:

    public class Ch14_3Activity extends Activity {

    private EditText lat, lon;

    private TextView output;

    }


14 3 gps activity 2

14-3 本地服務與定位應用-GPS景點防撞雷達步驟三:建立Activity活動類別的事件處理方法-2

onCreate()方法

  • 在覆寫的onCreate()方法載入版面配置後,可以取得EditText和TextView物件,如下所示:

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    lat = (EditText) findViewById(R.id.txtLat);

    lon = (EditText) findViewById(R.id.txtLong);

    output = (TextView) findViewById(R.id.output);

    }


14 3 gps activity 3

14-3 本地服務與定位應用-GPS景點防撞雷達步驟三:建立Activity活動類別的事件處理方法-3

start_Click()事件處理方法

  • 在start_Click()事件處理方法建立Intent物件後,呼叫startService()方法啟動GPSService.class服務,並且傳遞經緯度座標LATITUDE和LONGITUDE,如下所示:

    public void start_Click(View view) {

    float latitude = Float.parseFloat(lat.getText().toString());

    float longitude = Float.parseFloat(lon.getText().toString());

    Intent intent = new Intent(this, GPSService.class);

    intent.putExtra("LATITUDE", latitude);

    intent.putExtra("LONGITUDE", longitude);

    startService(intent);

    • output.setText("服務啟動中...");

      }


14 3 gps activity 4

14-3 本地服務與定位應用-GPS景點防撞雷達步驟三:建立Activity活動類別的事件處理方法-4

stop_Click()事件處理方法

  • 在stop_Click()事件處理方法建立Intent物件後,呼叫stopService()方法停止GPSService.class服務,如下所示:

    public void stop_Click(View view) {

    Intent intent = new Intent(this, GPSService.class);

    stopService(intent);

    output.setText("服務停止中...");

    }


14 3 gps activity 5

14-3 本地服務與定位應用-GPS景點防撞雷達步驟三:建立Activity活動類別的事件處理方法-5

finish_Click()事件處理方法

  • 在finish_Click()事件處理方法呼叫finish()方法結束活動,如下所示:

    public void finish_Click(View view) {

    finish();

    }


14 3 gps gpsservice 1

14-3 本地服務與定位應用-GPS景點防撞雷達步驟四:建立GPSService服務類別-1

  • 在GPSService服務類別使用GPS定位服務來檢查是否距離景點100公尺以內,如果是,送出廣播給GPSReceiver類別。

  • GPSService服務類別繼承Service類別且實作LocationListener介面,在開頭宣告LocationManager物件變數,如下所示:

    public class GPSService extends Service

    implements LocationListener {

    private LocationManager manager;

    private boolean isInArea;

    private double latitude, longitude;

    ….

    }


14 3 gps gpsservice 2

14-3 本地服務與定位應用-GPS景點防撞雷達步驟四:建立GPSService服務類別-2

onCreate()方法

  • 在onCreate()方法取得LOCATION_SERVICE系統服務的LocationManager物件後,註冊類別本身為傾聽者物件來定時更新位置資訊,如下所示:

    @Override

    public void onCreate() {

    manager = (LocationManager)

    getSystemService(LOCATION_SERVICE);

    manager.requestLocationUpdates(

    LocationManager.GPS_PROVIDER, 10000, 1, this);

    isInArea = false;

    }


14 3 gps gpsservice 3

14-3 本地服務與定位應用-GPS景點防撞雷達步驟四:建立GPSService服務類別-3

onStartCommand()方法

  • 在onStartCommand()方法取得Intent物件傳遞的經緯度座標LATITUDE和LONGITUDE,如下所示:

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

    latitude = (double) intent.getFloatExtra(

    "LATITUDE", 40.422005f);

    longitude = (double) intent.getFloatExtra(

    "LONGITUDE", -122.084095f);

    Log.d("GPSService", "lat/long: "+latitude+": "+longitude);

    return START_STICKY;

    }


14 3 gps gpsservice 4

14-3 本地服務與定位應用-GPS景點防撞雷達步驟四:建立GPSService服務類別-4

onDestroy()方法

  • 在onDestroy()方法呼叫removeUpdates()方法移除定位服務的位置更新,如下所示:

    @Override

    public void onDestroy() {

    manager.removeUpdates(this);

    }


14 3 gps gpsservice 5

14-3 本地服務與定位應用-GPS景點防撞雷達步驟四:建立GPSService服務類別-5

onBind()方法

  • onBind()方法並沒有使用,但是因為是抽象方法,類別一定要實作,所以傳回null,如下所示:

    @Override

    public IBinder onBind(Intent intent) {

    return null;

    }


14 3 gps gpsservice 6

14-3 本地服務與定位應用-GPS景點防撞雷達步驟四:建立GPSService服務類別-6

實作LocationListener介面的4個方法

  • 因為GPSService服務類別本身是實作LocationListener介面的傾聽者物件,所以需要實作介面的4個方法,不過,我們只有使用onLocationChanged()方法,如下所示:

    @Override

    public void onLocationChanged(Location current) {

    if (current == null) return;

    Location dest = new Location(current);

    dest.setLatitude(latitude);

    dest.setLongitude(longitude);

    float distance = current.distanceTo(dest);

    Log.d("Ch14_3", "距離: " + distance);

  • 程式碼在建立目標座標的Location物件後,呼叫參數current目前Location物件的distanceTo()方法,參數是目標的Location物件,可以計算2個座標之間的距離是多少公尺。


14 3 gps gpsservice 7

14-3 本地服務與定位應用-GPS景點防撞雷達步驟四:建立GPSService服務類別-7

  • 在下方if條件檢查距離是否小於100公尺,如果是,建立Intent物件送出廣播,如下所示:

    if (distance < 100.0) {

    if (isInArea == false) {

    Intent intent = new Intent(

    "android.broadcast.LOCATION");

    sendBroadcast(intent);

    isInArea = true;

    }

    } else {

    isInArea = false;

    }

    }


14 3 gps gpsreceiver

14-3 本地服務與定位應用-GPS景點防撞雷達步驟五:建立GPSReceiver廣播接收器類別

  • GPSReceiver廣播接收器類別是用來接收GPSService服務送出的android.broadcast.LOCATION廣播,可以使用Toast類別顯示訊息,和振動提醒已經接近景點範圍,如下所示:

    public class GPSReceiver extends BroadcastReceiver {

    @Override

    public void onReceive(Context context, Intent intent) {

    Toast.makeText(context, "已經接近景點範圍",

    Toast.LENGTH_LONG).show();

    Vibrator vibrator = (Vibrator) context.getSystemService(

    Context.VIBRATOR_SERVICE);

    vibrator.vibrate(500); // 半秒

    }

    }


14 3 gps androidmanifest xml

14-3 本地服務與定位應用-GPS景點防撞雷達步驟六:在AndroidManifest.xml註冊元件和新增權限

  • GPSService服務和GPSReceiver廣播接收器需要在AndroidManifest.xml檔註冊,可以處理android.broadcast.LOCATION的廣播,如下所示:

    <receiver android:name=".GPSReceiver">

    <intent-filter>

    <action android:name="android.broadcast.LOCATION" />

    </intent-filter>

    </receiver>

    <service android:name=".GPSService"/>

  • GPS景點防撞雷達需要使用定位服務和振動,所以需要新增2個權限,如下所示:

    <uses-permission android:name=

    "android.permission.ACCESS_FINE_LOCATION"/>

    <uses-permission android:name="android.permission.VIBRATE"/>


14 4 google maps api my

14-4 使用Google Maps API-My地圖

  • 14-4-1 取得Google Maps API金鑰

  • 14-4-2 使用MapView元件和MapActivity類別-My地圖


14 4 google maps api my1

14-4 使用Google Maps API-My地圖

  • Google Map(地圖)是一套內建Android作業系統的應用程式,在本節前我們已經使用Intent物件啟動地圖應用程式,顯示指定經緯度座標的地圖。

  • 在實務上,我們可能需要將Google Map內嵌在Android應用程式來建立所需的應用,不過,因為Google Map並不包含在Android SDK,請注意!我們需要取得Google Maps API金鑰,和在Build Target選Google API,才能在Android應用程式使用Google Map。


14 4 1 google maps api

14-4-1 取得Google Maps API金鑰

  • 在將Google Map整合至你的Android應用程式之前,我們需要先取得免費的Google Maps API金鑰。對於在Android模擬器或連接開發電腦實機上測試執行應用程式所需的金鑰,我們是使用SDK偵錯憑證(Debug Certificate)來申請金鑰。

    • 步驟一:取得SDK偵錯憑證的路徑

    • 步驟二:取出申請所需MD5認證指紋碼

    • 步驟三:上網申請金鑰


14 4 2 mapview mapactivity my

14-4-2 使用MapView元件和MapActivity類別-My地圖

  • 在取得Google Maps API金鑰後,我們就可以使用MapView元件和繼承MapActivity抽象類別來建立自己的地圖程式,My地圖是使用GPS定位服務,當位置座標改變時,馬上更新地圖顯示的位置。


14 4 2 mapview mapactivity my android

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟一:開啟和執行Android專案

  • 請啟動Eclipse IDE開啟Android專案Ch14_4_2,然後就可以執行此專案,內含1個Java類別檔和版面配置檔main.xml,其執行結果如下圖所示:


14 4 2 mapview mapactivity my mapview

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟二:建立MapView元件的版面配置

  • My地圖使用介面的版面配置是定義在main.xml檔,使用LinearLayout垂直編排1個TextView和MapView元件,如下所示:

    <TextView android:id="@+id/output"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:text="在地圖上顯示你的位置"/>

    <com.google.android.maps.MapView

    android:id="@+id/mapView"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:enabled="true"

    android:clickable="true"

    android:apiKey="0JNEnTMsG9nVME5Lbx2LxFQr1zTh65aObDEbzsw"/>


14 4 2 mapview mapactivity my mapactivity 1

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務1

  • 在Ch14_4_2Activity活動類別因為使用MapView元件,所以需要繼承MapActivity抽象類別,而不是Activity類別,因為MapActivity抽象類別已經實作一些顯示MapView元件所需的方法,如下所示:

    public class Ch14_4_2Activity extends MapActivity {

    private MapView mapView;

    private TextView output;

    private MapController mc;

    private GeoPoint gp;

    private LocationManager manager;

    private LocationListener locationListener;

    }


14 4 2 mapview mapactivity my mapactivity 2

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務2

onCreate()方法

  • 在覆寫的onCreate()方法載入版面配置後,就可以取得系統服務的LocationManager物件,if條件檢查是否有啟用GPS,如下所示:

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    output = (TextView) findViewById(R.id.output);

    manager = (LocationManager)

    getSystemService(LOCATION_SERVICE);

    if (!manager.isProviderEnabled(

    LocationManager.GPS_PROVIDER)) {

    }

  • 上述if條件的程式碼和第14-1-2節的onCreate()方法相同,筆者就不重複說明。


14 4 2 mapview mapactivity my mapactivity 3

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務3

  • 在下方取得MapView物件後,呼叫setBuiltInZoomControls()方法,參數true是使用內建縮放控制,如下所示:

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

    mapView.setBuiltInZoomControls(true);

    mapView.setSatellite(false);

  • setSatellite()方法可以指定成衛星空照圖的顯示方式,因為參數是false,就是使用標準方式來顯示。


14 4 2 mapview mapactivity my mapactivity 4

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務4

  • 在下方呼叫getController()方法取得MapController物件後,取得預設的經緯度座標lng和lat,如下所示:

    mc = mapView.getController();

    double lat = Double.parseDouble("25.06924");

    double lng = Double.parseDouble("121.51617");

    gp = new GeoPoint((int) (lat * 1E6),(int) (lng * 1E6));

    mc.animateTo(gp);

    mc.setZoom(18);

    }


14 4 2 mapview mapactivity my mapactivity 5

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務5

onResume()方法

  • 在覆寫的onResume()方法建立定位服務的傾聽者物件,即之後的內層類別GPSLocationListener,在設定更新位置頻率的條件後,呼叫requestLocationUpdates()方法註冊傾聽者物件來周期性回報目前的位置,如下所示:

    @Override

    protected void onResume() {

    super.onResume();

    locationListener = new GPSLocationListener();

    int minTime = 1000; // 毫秒

    loat minDistance = 1; // 公尺

    manager.requestLocationUpdates(

    LocationManager.GPS_PROVIDER,

    minTime, minDistance,locationListener);

    manager.requestLocationUpdates(

    LocationManager.NETWORK_PROVIDER,

    minTime, minDistance,locationListener);

    }


14 4 2 mapview mapactivity my mapactivity 6

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務6

實作LocationListener介面的內層類別

  • 實作LocationListener介面的內層類別就是用來建立定位服務更新位置的傾聽者物件,介面需實作4個方法,不過,我們只有使用onLocationChanged()方法,如下所示:

    class GPSLocationListener implements LocationListener {

    @Override

    public void onLocationChanged(Location current) {

    double lat, lng;

    if (current != null) {

    lat = current.getLatitude();

    lng = current.getLongitude();

    Toast.makeText(Ch14_4_2Activity.this,

    "經緯度座標變更....", Toast.LENGTH_SHORT).show();

    output.setText("緯度: " + lat + " 經度: " + lng);

    gp = new GeoPoint((int) (lat * 1E6),(int) (lng * 1E6));

    mc.animateTo(gp);

    mc.setZoom(18);

    }

    }


14 4 2 mapview mapactivity my mapactivity 7

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務7

  • 後面的3個實作方法並沒有使用,如下所示:

    @Override

    public void onProviderDisabled(String provider) {

    }

    @Override

    public void onProviderEnabled(String provider) {

    }

    @Override

    public void onStatusChanged(String provider,

    int status, Bundle extras) {

    }

    }


14 4 2 mapview mapactivity my mapactivity 8

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟三:建立MapActivity活動類別和使用定位服務8

isRouteDisplayed()方法

  • 因為MapActivity是抽象類別,繼承的類別一定要實作isRouteDisplayed()抽象方法,傳回是否顯示任何規劃路徑,沒有傳回false,如下所示:

    @Override

    protected boolean isRouteDisplayed() {

    return false;

    }


14 4 2 mapview mapactivity my androidmanifest xml

14-4-2 使用MapView元件和MapActivity類別-My地圖步驟四:在AndroidManifest.xml註冊函數庫和新增權限

  • 因為Google Maps API不是Android內建函數庫,所以當Android應用程式使用Google Maps API時,我們需要在application元素新增uses-library子元素,讓應用程式可以使用此函數庫,如下所示:

    <uses-library android:name="com.google.android.maps"/>

  • My地圖需要存取網路和使用定位服務,所以需要新增2個權限,如下所示:

    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name=

    "android.permission.ACCESS_FINE_LOCATION"/>


14 5 google

14-5 標記Google地圖-追蹤個人行蹤

  • 實務上,我們不只可以使用MapView元件和MapActivity類別來建立地圖程式,更可以在地圖上作記號,例如:標記加油站、停車場位置或個人行蹤等。

  • 標記Google地圖是使用Overlay類別,它如同是一片透明投影片,可以讓我們在上面作記號,然後如同圖層般一層一層疊在地圖上。


14 5 google android

14-5 標記Google地圖-追蹤個人行蹤步驟一:開啟和執行Android專案

  • 請啟動Eclipse IDE開啟Android專案Ch14_5,就可以執行此專案,內含3個Java類別檔和2個版面配置檔,其執行結果如下圖所示:


14 5 google 1

14-5 標記Google地圖-追蹤個人行蹤步驟二:建立主活動使用介面的版面配置-1

  • 主活動使用介面的版面配置是定義在main.xml檔,使用LinearLayout垂直編排2個TextView元件和1個水平的LinearLayout,內含2個Button元件,如下所示:

    <TextView android:id="@+id/output"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"/>

    <LinearLayout

    android:orientation="horizontal"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content">

    <Button android:id="@+id/button1"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"


14 5 google 2

14-5 標記Google地圖-追蹤個人行蹤步驟二:建立主活動使用介面的版面配置-2

android:text="顯示Google地圖"

android:onClick="button1_Click"/>

<Button android:id="@+id/button2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="追蹤個人行蹤"

android:onClick="button2_Click"/>

</LinearLayout>

<TextView android:id="@+id/list"

android:layout_width="fill_parent"

android:layout_height="wrap_content"/>


14 5 google activity 1

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-1

  • 在Ch14_5Activity活動類別的開頭宣告常數與成員變數,使用GPLat[]和GPLng[]陣列儲存個人行蹤的座標,如下所示:

    public class Ch14_5Activity extends Activity {

    private final int MAX_RECORDS = 10;

    private LocationManager manager;

    private Location currentLocation;

    private String best;

    private int index = 0, count = 0;

    private double[] GPLat = new double[MAX_RECORDS];

    private double[] GPLng = new double[MAX_RECORDS];

    }


14 5 google activity 2

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-2

onCreate()方法

  • 在覆寫的onCreate()方法載入版面配置後,取得系統服務的LocationManager物件,如下所示:

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    manager = (LocationManager)

    getSystemService(LOCATION_SERVICE);

    }


14 5 google activity 3

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-3

onResume()方法

  • onResume()方法和第14-1-2節步驟三的同名方法相同,只是更新位置頻率的條件不同,如下所示:

    int minTime = 5000; // 毫秒

    float minDistance = 15; // 公尺


14 5 google activity 4

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-4

onPause()方法

  • 在覆寫onPause()方法呼叫removeUpdates()方法取消周期更新位置,此方法和第14-1-2節步驟三的同名方法相同。


14 5 google activity 5

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-5

updatePosition()方法

  • 在自訂updatePosition()方法更新TextView元件顯示的位置資訊和個人行蹤的座標清單,如下所示:

    @Override

    private void updatePosition() {

    TextView output, list;

    String str = "最近個人行蹤的座標清單:\n";

    output = (TextView) findViewById(R.id.output);

    list = (TextView) findViewById(R.id.list);

    if (currentLocation == null) {

    output.setText("取得定位資訊中...");

    } else {

    output.setText(getLocationInfo(currentLocation));

    for (int i = 0; i < MAX_RECORDS; i++) {

    if (GPLat[i] != 0.0)

    str += GPLat[i] + "/" + GPLng[i] +"\n";

    }

    list.setText(str);

    }

    }


14 5 google activity 6

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-6

LocationListener傾聽者物件

  • 在requestLocationUpdates()方法需要註冊定位服務的傾聽者物件,即使用匿名內層類別實作LocationListener介面來建立此物件,此物件和第14-1-2節步驟三的同名物件相同。


14 5 google activity 7

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-7

getLocationInfo()方法

  • 在自訂getLocationInfo()方法可以從參數Loaction物件取得定位資訊和檢查是否需要儲存個人行蹤的座標,如下所示:

    public String getLocationInfo(Location location) {

    boolean isSave = true;

    double lat, lng;

    lat = location.getLatitude();

    lng = location.getLongitude();

    StringBuffer str = new StringBuffer();

    str.append("定位提供者(Provider): "+

    location.getProvider());

    str.append("\n緯度(Latitude): " +

    Double.toString(lat));

    str.append("\n經度(Longitude): " +

    Double.toString(lng));


14 5 google activity 8

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-8

  • 如果是,就可以計算第2個座標和前一個座標的距離,首先建立目地GPS座標的Location物件,如下所示:

    if (count >= 1) {

    Location dest = new Location(location);

    int preIndex = index - 1;

    if (preIndex < 0 ) preIndex = GPLat.length - 1;

    dest.setLatitude(GPLat[preIndex]);

    dest.setLongitude(GPLng[preIndex]);

  • 在下方使用distanceTo()方法計算與目地座標的距離,如果距離小於20公尺就不儲存,此時旗標變數isSave的值為false,如下所示:

    float distance = location.distanceTo(dest);

    Toast.makeText(this, "距離: " + distance + "公尺",

    Toast.LENGTH_SHORT).show();

    if (distance < 20.0) isSave = false;

    }

    if (isSave) {


14 5 google activity 9

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-9

  • 上述if條件的isSave旗標變數值為true,表示需要新增座標,count變數記錄共儲存幾個座標,如果超過陣列尺寸,就指定為陣列尺寸的個數,如下所示:

    GPLat[index] = lat;

    GPLng[index] = lng;

    count++;

    if (count >= MAX_RECORDS)

    count = MAX_RECORDS;

    index++;

    if (index >= MAX_RECORDS) index = 0;

    }

    return str.toString();

    }


14 5 google activity 10

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-10

button1_Click()事件處理方法

  • button1_Click()事件處理方法可以依據目前的位置座標來啟動Google地圖,它和第14-1-2節步驟三的同名方法相同。


14 5 google activity 11

14-5 標記Google地圖-追蹤個人行蹤步驟三:建立Activity主活動類別記錄座標清單-11

button2_Click()事件處理方法

  • button2_Click()事件處理方法可以在MapView元件顯示個人行蹤,這是使用Intent物件啟動MyMapActivity活動類別,附件是個人行蹤座標的2個陣列,和座標數的count變數值,如下所示:

    public void button2_Click(View view) {

    Intent mapView = new Intent(this, MyMapActivity.class);

    mapView.putExtra("GPSLATITUDE", GPLat);

    mapView.putExtra("GPSLONGITUDE", GPLng);

    mapView.putExtra("MAX_INDEX", count);

    startActivity(mapView);

    }


14 5 google mapview

14-5 標記Google地圖-追蹤個人行蹤步驟四:建立MapView元件的版面配置

  • MyMapActivity活動類別的版面配置是定義在map.xml檔,使用LinearLayout垂直編排1個MapView元件,如下所示:

    <com.google.android.maps.MapView

    android:id="@+id/mapView"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:enabled="true"

    android:clickable="true"

    android:apiKey="0JNEnTMsG9nVME5Lbx2LxFQr1zTh65aObDEbzsw"/>


14 5 google mymapactivity 1

14-5 標記Google地圖-追蹤個人行蹤步驟五:建立MyMapActivity活動類別來標記地圖-1

  • MyMapActivity活動類別是繼承MapActivity抽象類別,在類別開頭宣告MapView和MapController物件變數,如下所示:

    public class MyMapActivity extends MapActivity {

    private MapView mapView;

    private MapController mc;

    }


14 5 google mymapactivity 2

14-5 標記Google地圖-追蹤個人行蹤步驟五:建立MyMapActivity活動類別來標記地圖-2

onCreate()方法

  • 在覆寫的onCreate()方法載入版面配置後,就可以取得MapView元件和MapController物件,如下所示:

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.map);

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

    mc = mapView.getController();

    ArrayList<GeoPoint> locations = new ArrayList<GeoPoint>();

    ArrayList<Drawable> images = new ArrayList<Drawable>();

    double[] GPLat, GPLng;

    int max_index;


14 5 google mymapactivity 3

14-5 標記Google地圖-追蹤個人行蹤步驟五:建立MyMapActivity活動類別來標記地圖-3

  • 然後在下方取得Intent物件傳遞的座標陣列,如下所示:

    GPLat = getIntent().getDoubleArrayExtra("GPSLATITUDE");

    GPLng = getIntent().getDoubleArrayExtra("GPSLONGITUDE");

    max_index = getIntent().getIntExtra("MAX_INDEX", 10);

    for (int i = 0; i < max_index; i++) {

    int gpLat, gpLng;

    gpLat = (int) (GPLat[i]*1000000);

    gpLng = (int) (GPLng[i]*1000000);

    locations.add(new GeoPoint(gpLat,gpLng));

    images.add(getResources().getDrawable(R.drawable.pin));

    }

  • for迴圈一一將陣列座標轉換成GeoPoint座標後,新增至ArrayList集合物件,標記圖示都是同一個pin.png,換句話說,如果需要,每一個座標可以使用不同的標記圖示。


14 5 google mymapactivity 4

14-5 標記Google地圖-追蹤個人行蹤步驟五:建立MyMapActivity活動類別來標記地圖-4

  • 在下方建立LocationOverlay物件,其宣告在下一步驟,這是一個繼承ItemizedOverlay類別的物件,建構子參數是預設標記圖示和Context物件this,如下所示:

    LocationOverlay myOverlay = new LocationOverlay(

    getResources().getDrawable(R.drawable.icon), this);

    myOverlay.setItems(locations, images);

    mapView.getOverlays().add(myOverlay);

  • 上述程式碼呼叫setItems()方法指定標記的座標和圖示的ArrayList物件後,呼叫MapView物件的getOverlays()方法取得圖層Overlay的List集合物件,即可呼叫add()方法新增Overlay物件。


14 5 google mymapactivity 5

14-5 標記Google地圖-追蹤個人行蹤步驟五:建立MyMapActivity活動類別來標記地圖-5

最後在下方指定MapView參數為內建縮放控制、衛星空照圖顯示,和使用MapController物件指定地圖置中和放大15,如下所示:

mapView.setBuiltInZoomControls(true);

mapView.setSatellite(true);

mc.setCenter(locations.get(0));

mc.setZoom(15);

}


14 5 google mymapactivity 6

14-5 標記Google地圖-追蹤個人行蹤步驟五:建立MyMapActivity活動類別來標記地圖-6

isRouteDisplayed()方法

  • 繼承類別一定要實作isRouteDisplayed()抽象方法,傳回是否顯示任何規劃路徑,沒有傳回false,如下所示:

    @Override

    protected boolean isRouteDisplayed() {

    return false;

    }


14 5 google locationoverlay 1

14-5 標記Google地圖-追蹤個人行蹤步驟六:建立LocationOverlay類別-1

  • LocationOverlay類別繼承ItemizedOverlay類別,這是一種項目化的Overlay類別,可以使用List集合物件儲存多個GeoPoint座標和標記圖示,以便在Google地圖上同時使用不同圖示來標示多個座標。

  • 在LocationOverlay類別開頭宣告List集合物件變數myItems和myMarkers,如下所示:

    public class LocationOverlay extends ItemizedOverlay<OverlayItem> {

    private List<GeoPoint> myItems;

    private List<Drawable> myMarkers;

    private Context context;

    }


14 5 google locationoverlay 2

14-5 標記Google地圖-追蹤個人行蹤步驟六:建立LocationOverlay類別-2

建構子

  • 在類別建構子呼叫父類別的建構子,參數是預設標示圖示,然後指定成員物件變數context的值,如下所示:

    public LocationOverlay(Drawable defaultMarker, Context context) {

    super(boundCenterBottom(defaultMarker));

    this.context = context;

    }


14 5 google locationoverlay 3

14-5 標記Google地圖-追蹤個人行蹤步驟六:建立LocationOverlay類別-3

setItems()方法

  • 在自訂setItems()方法指定各項目的座標和標記圖示,參數是ArrayList集合物件,如下所示:

    public void setItems(ArrayList<GeoPoint> items,

    ArrayList<Drawable> drawables) {

    myItems = items;

    myMarkers = drawables;

    populate();

    }


14 5 google locationoverlay 4

14-5 標記Google地圖-追蹤個人行蹤步驟六:建立LocationOverlay類別-4

createItem()方法

  • 在實作createItem()抽象方法建立OverlayItem項目物件,和呼叫setMarker()方法指定標記圖示,方法參數是索引,此方法是由populate()方法來呼叫,如下所示:

    @Override

    protected OverlayItem createItem(int i) {

    OverlayItem item = new OverlayItem(

    myItems.get(i), null, null);

    item.setMarker(boundCenterBottom(

    myMarkers.get(i)));

    return item;

    }


14 5 google locationoverlay 41

14-5 標記Google地圖-追蹤個人行蹤步驟六:建立LocationOverlay類別-4

size()方法

  • 在實作size()抽象方法傳回項目數,如下所示:

    @Override

    public int size() {

    return myItems.size();

    }


14 5 google locationoverlay 5

14-5 標記Google地圖-追蹤個人行蹤步驟六:建立LocationOverlay類別-5

onTap()方法

  • 覆寫onTap()方法來處理指定項目的Tap事件,也就是說,觸摸一下標記圖示,可以使用Toast類別顯示此點的座標,如下所示:

    @Override

    protected boolean onTap(int i) {

    GeoPoint gp = myItems.get(i);

    Toast.makeText(context,

    "座標: "+

    gp.getLatitudeE6() / 1E6 + "," +

    gp.getLongitudeE6() /1E6 ,

    Toast.LENGTH_SHORT).show();

    return true;

    }


14 5 google androidmanifest xml

14-5 標記Google地圖-追蹤個人行蹤步驟七:在AndroidManifest.xml註冊函數庫和新增權限

  • 因為Google Maps API不是Android內建函數庫,所以當Android應用程式使用Google Maps API時,我們需要在application元素新增uses-library子元素,讓應用程式可以使用此函數庫,如下所示:

    <uses-library android:name="com.google.android.maps"/>

  • 程式需要存取網路和使用定位服務,所以需要新增3個權限,如下所示:

    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name=

    "android.permission.ACCESS_COARSE_LOCATION"/>

    <uses-permission android:name=

    "android.permission.ACCESS_FINE_LOCATION"/>


14 google

End


  • Login