2014年12月22日 星期一

[Android Sample Code] 利用GPS定位

Android提供下列定位方式的API:
1. GPS定位
2. Wi-Fi訊號/基地台訊號定位

由於GPS是透過衛星定位所以只能用於戶外環境,跟其它兩種方法比它的精確度最高但是缺點是比較耗電而且回傳位置資訊的速度較慢,相較之下Wi-Fi和基地台定位室內、室外都可以使用但是精確度較差,不過和GPS相比較不耗電,回傳位置資訊的速度也較快,總結如下表:

                                  TABLE I

GPS
Wi-Fi訊號/基地台訊號定位
可應用環境
室內
室內/室外
精確度
較差
回傳位置資訊所需時間
較長
較短
耗電量
較高
較低

想要使用這幾種定位方式的其中一種的話,必須在AndroidManifest.xml裡添加下列這行App權限設定:

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

其中"android.permission.ACCESS_COARSE_LOCATION"是讓App能透過Wi-Fi/基地台訊號存取大概的位置資訊;而"android.permission.ACCESS_FINE_LOCATION" 則是能讓App透過GPS和Wi-Fi/基地台訊號精確的存取Android裝置的位置。

要寫定位的App,需用到以下物件:
1. LocationManager: 用來取得與更新目前裝置的資訊,透過呼叫LocationManagerrequestLocationUpdates()並傳入實作LocationListener介面(Interface)之call back object來達成。
2. 實作LocationListener

利用GPS取得經緯度的範例程式如下所示,App的外觀僅添加一TextView用來顯示所取得之位置資訊,在寫定位App時不需實體化LocationManager物件,而是透過呼叫Context (由Activity繼承的父類別)的getSystemService()方法 (Method)回傳一LocationManager的參照 (Reference)給App,如第36行所示,傳入參數Context.LOCATION_SERVICE給getSystemService()即會回傳一LocationManager參照,接下來第37行只需要呼叫LocationManagerrequestLocationUpdates方法並註冊監聽者-LocationListener即可,第一個參數式指定想要使用哪一種定位服務,可以選用GPS_PROVIDER或是NETWORK_PROVIDER, 第二和第三個參數則是設定更新位置資訊的最小時間週期 (單位是毫秒)以及更新資訊所需之最短距離 (單位為公尺),都設0則是代表請求盡快回傳位置的資訊,最後一個參數則是傳入所實作之call back object,即locationListener
第15到29行實作了LocationListener的介面,本範例僅實作onStatusChanged()方法,當位置資訊一更新時,locationListener call back物件就會被其它物件呼叫,然後onLocationChanged()方法就會被執行並呼叫updateWithNewLocation()方法顯示目前位置的經緯度到螢幕上,參數location即為被更新位置的資訊。
package com.example.locationtest;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
 TextView positionTextView;
 LocationManager locationManager;
 
 LocationListener locationListener = new LocationListener(){
  @Override
     public void onLocationChanged(Location location){
      //implementation 
      updateWithNewLocation(location);
     }
  
     @Override
     public void onStatusChanged(String provider,int status,Bundle extras){}
     
     @Override
     public void onProviderEnabled(String provider){}
     @Override
     public void onProviderDisabled(String provider){}
    }; 
    
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        positionTextView = (TextView) findViewById(R.id.PositionTextView);
        locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, locationListener);
        //you also can register LocationManager.NETWORK_PROVIDER in the same time and handle information 
        //from these provider in the Locationlistener.
        //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, loctionListener);
        //You also can call below method to get the cached location.
       //Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
       //or
       //Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
       //updateWithNewLocation(location);
    }
    
 private void updateWithNewLocation(Location location) {
  if (location != null) {
   double lat = location.getLatitude();
   double lng = location.getLongitude();
   String latLongString = "Latitude:" + lat + "\nLongitude:" + lng;
   positionTextView.setText("Your Current Position is:\n" + latLongString);
  } 
 }
}


要讓App可以正確的獲取位置資訊必須開啟下圖的設定,「存取我的地點」和「GPS衛星定位都必須開啟」。
Fig. 1 啟用裝置上的位置資訊服務


執行結果:
Fig. 2. 執行結果

沒有留言:

張貼留言