簡介
Android提供兩種定位方式,一種是GPS,另一種是網路定位(Network)。前者用於室外;後者用於室內。
程式範例
- 加入權限(AndroidManifest.xml):
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- android.permission.ACCESS_FINE_LOCATION: 使用GPS定位服務
- android.permission.ACCESS_COARSE_LOCATION: 使用網路定位服務
- 將java/res/layout/activity_main.xml版面改成FrameLayout並加入一個TextView用來顯示定位資訊:
<FrameLayout 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"> <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent"/> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/info" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="Provider: network\nPosition:" android:textColor="#ff00ff" android:shadowDx="3" android:shadowDy="3" android:shadowColor="#000000" android:shadowRadius="3"/> </LinearLayout> </FrameLayout>
- 實現
LocationListener
介面及其抽象方法(可直接由MainActivity
來實現):- onLocationChanged: 座標更新時會觸發的方法。
- onProviderDisabled: 定位服務被關閉時會觸發的方法。
- onProviderEnabled: 定位服務開啟時會觸發的方法。
- onStatusChanged: 定位服務狀態變更時會觸發的方法。
實現LocationListener
介面:public class MainActivity extends ActionBarActivity implements LocationListener { TextView info = null; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 關聯WebView myWebView = (WebView)findViewById(R.id.webview); info = (TextView)findViewById(R.id.info); ...以下省略...
實現LocationListerner
介面方法:public class MainActivity extends ActionBarActivity implements LocationListener { ...以上省略... // 用來存放目前最新位置 Location loc = null; // 接收最新的定位訊息 @Override public void onLocationChanged(Location location) { // 存下最新位置資訊 loc = location; // 取得經緯度 double lat = location.getLatitude(); // 緯度 double lng = location.getLongitude(); // 經度 // 更新最新資訊到TextView上 float acc = location.getAccuracy(); // 單位: 公尺 float bea = location.getBearing(); // 方向 float spd = location.getSpeed(); // 速度: 小時/公尺 float time = location.getTime(); // 該資訊的時間(1970年1月1日到現在經過的毫秒, UTC) info.setText("Latitude: " + lat + "\n" + "Longitude: " + lng + "\n" + "Accuracy: " + acc + "\n" + "Bearing: " + bea + "\n" + "Speed: " + spd + "\n" + "Time: " + time); // 呼叫JavaScript // 例: javascript:centerAt(25.12345, 33.0987); myWebView.loadUrl("javascript:centerAt(" + lat + ", " + lng + ");"); Toast.makeText(this, "位置更新: " + lat + ", " + lng + "(" + location.getProvider() + ")", Toast.LENGTH_LONG).show(); } @Override public void onProviderDisabled(String provider) { Toast.makeText(this, provider + "被關閉了.", Toast.LENGTH_LONG).show(); } @Override public void onProviderEnabled(String provider) { Toast.makeText(this, provider + "被啟動了.", Toast.LENGTH_LONG).show(); } @Override public void onStatusChanged(String provider, int status, Bundle arg2) { switch (status) { case LocationProvider.AVAILABLE: Toast.makeText(this, provider + "服務中", Toast.LENGTH_SHORT).show(); break; case LocationProvider.OUT_OF_SERVICE: Toast.makeText(this, provider + "沒有服務", Toast.LENGTH_SHORT).show(); break; case LocationProvider.TEMPORARILY_UNAVAILABLE: Toast.makeText(this, provider + "暫時不可使用", Toast.LENGTH_SHORT).show(); break; } } }
- 使用
LocationManager
物件來初始化定位服務:public class MainActivity extends ActionBarActivity implements LocationListener { ...以上省略... // Android系統透過LocationManager物件來使用定位相關服務 LocationManager lm = null; // 初始化定位服務 // 需要權限: // android.permission.ACCESS_FINE_LOCATION // android.permission.ACCESS_COARSE_LOCATION private void setupLocationService() { // 取得LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); // 判斷GPS定位服務或Network定位服務是否有打開 if(!lm.isProviderEnabled(LocationManager.GPS_PROVIDER) && !lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { // 顯示錯誤訊息 AlertDialog.Builder dlg = new AlertDialog.Builder(this); dlg.setTitle("警告"); dlg.setMessage("請至少開啟GPS或網路來使用定位服務"); dlg.show(); return; } // 如果Network是打開的, 則啟動Network定位 if(lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { Toast.makeText(this, "NETWORK已開啟 使用NETWORK定位", Toast.LENGTH_SHORT).show(); // 開啟NETWORK定位 lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, // 要使用的Provider 1000, // 獲取GPS資訊的時間單位(毫秒), 時間越短會越耗電 0, // 觸發listener位置改變的距離(公尺), 在該距離之內不做回應 this); } // 如果GPS是打開的, 則啟動GPS定位 if(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Toast.makeText(this, "GPS已開啟 使用GPS定位", Toast.LENGTH_SHORT).show(); // 開啟GPS定位 lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, // 要使用的Provider 1000, // 獲取GPS資訊的時間單位(毫秒), 時間越短會越耗電 0, // 觸發listener位置改變的距離(公尺), 在該距離之內不做回應 this); } } ... 以下省略... }
- 在
WebViewClient
物件中的onPageFinished()
方法中初始化定位服務:// 初始化定位服務 setupLocationService();
- 在Activity的
onDestory()
生命週期中解除定位服務:@Override protected void onDestroy() { // 關閉定位, 否則定位服務在離開app後仍然會一直定位 lm.removeUpdates(this); super.onDestroy(); }
- 完成。