Android-使用webview在V3版的Google地圖GPS定位

目的:透過GPS或網路定位來決定裝置目前的位置

程式執行動態畫面錄影:

https://www.youtube.com/watch?v=_Bw2YP39WOw
畫面中可看到經緯度的資料約每隔一秒更新一次。

測試時必須要用GPS的模擬器播放預存的GPS記錄檔(KML)來模擬實際GPS抓到定位的資料,如下畫面:

程式要能接收GPS或網路的定位資料必須實作LocationListener介面,其中有幾個介面方法可以用在實際上的程式撰寫,像是定位資料的變化的相關方法「public void onLocationChanged(Location location」,其他像是偵測GPS裝置是否啟動或不啟動的方法。

主程式:

package wells.example.googlemapexample;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements LocationListener{
 private static final String MAP_URL = "file:///android_asset/googleMap.html";
 private WebView webView;
 private EditText LatText, LogText;
 private Button submit;
 private boolean webviewReady = false;
 private Location mostRecentLocation = null;

 private void getLocation() {//取得裝置的GPS位置資料
   LocationManager locationManager =
     (LocationManager)getSystemService(Context.LOCATION_SERVICE);
   Criteria criteria = new Criteria();
   criteria.setAccuracy(Criteria.ACCURACY_FINE);
   String provider = locationManager.getBestProvider(criteria,true);
   //In order to make sure the device is getting the location, request updates.
   locationManager.requestLocationUpdates(provider, 1, 0, this);
   mostRecentLocation = locationManager.getLastKnownLocation(provider);
 }

 @Override
 /** Called when the activity is first created. */
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.googlemaps);
   LatText = (EditText) findViewById(R.id.LatText);
   LogText = (EditText) findViewById(R.id.LogText);
   submit = (Button) findViewById(R.id.submit);
   submit.setOnClickListener(new Button.OnClickListener(){ 
            @Override
            public void onClick(View v) {

                // TODO Auto-generated method stub
           
            if (webviewReady) {
            //由輸入的經緯度值標註在地圖上,呼叫在googlemaps.html中的mark函式
                final String markURL = "javascript:mark(" +
               LatText.getText() + "," +
               LogText.getText() + ")";
            webView.loadUrl(markURL);
           
            //畫面移至標註點位置,呼叫在googlemaps.html中的centerAt函式
            final String centerURL = "javascript:centerAt(" +
                 LatText.getText() + "," +
                 LogText.getText() + ")";
            webView.loadUrl(centerURL);
            }
               
            }   
   });
   getLocation();//取得定位位置
   setupWebView();//設定webview  
   if (mostRecentLocation!=null){
     LatText.setText("" + mostRecentLocation.getLatitude());
     LogText.setText("" + mostRecentLocation.getLongitude());
 
     //將畫面移至定位點的位置
     final String centerURL = "javascript:centerAt(" +
     mostRecentLocation.getLatitude() + "," +
     mostRecentLocation.getLongitude()+ ")";
     if (webviewReady) webView.loadUrl(centerURL);
   }
 
 }

 
 /** Sets up the WebView object and loads the URL of the page **/
 private void setupWebView(){

   webView = (WebView) findViewById(R.id.webview);
   webView.getSettings().setJavaScriptEnabled(true);
   //Wait for the page to load then send the location information
   webView.setWebViewClient(new WebViewClient(){
     @Override
     public void onPageFinished(WebView view, String url)
     {
       //webView.loadUrl(centerURL);
     webviewReady = true;//webview已經載入完畢
     }

   });
   webView.loadUrl(MAP_URL);
 }

@Override
public void onLocationChanged(Location location) {//定位位置改變時會執行的方法
// TODO Auto-generated method stub
   if (location !=null){
     LatText.setText("" + location.getLatitude());  
     LogText.setText("" + location.getLongitude());      
     //將畫面移至定位點的位置,呼叫在googlemaps.html中的centerAt函式
     final String centerURL = "javascript:centerAt(" +
     location.getLatitude() + "," +
     location.getLongitude()+ ")";
     if (webviewReady) webView.loadUrl(centerURL);
   }
}

@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub

}
}


專案必須打開的權限:
    <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" />  



googlemaps.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/RelativeLayout1"
        android:layout_width="fill_parent"
        android:layout_height="133dp"
        android:focusable="true"
        android:focusableInTouchMode="true" >

        <TextView 
            android:id="@+id/textView2" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_centerVertical="true" 
            android:text="緯度(Latitude)"/>
        
        <EditText
            android:id="@+id/LogText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/textView1"
            android:layout_weight="1"
            android:clickable="false"
            android:ems="10"
            android:inputType="text"
            android:text="120.580806" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="經度(Longtitude)" />

        <EditText
            android:id="@+id/LatText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/textView2"
            android:layout_alignBottom="@+id/textView2"
            android:layout_alignParentRight="true"
            android:ems="10"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:inputType="text"
            android:text="24.217712" >

            <requestFocus />
        </EditText>

        <Button
            android:id="@+id/submit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/LatText"
            android:layout_alignParentBottom="true"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:text="標註" />

    </RelativeLayout>

    <WebView
        android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="629dp" />

</LinearLayout>


googleMap.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Google Maps JavaScript API v3 Example: Marker Animations</title>
    <link href="/maps/documentation/javascript/examples/default.css" rel="stylesheet">
    <script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script>
      var centerPoint = new google.maps.LatLng(24.217712, 120.580806); //弘光科技大學,台中市中棲路34號
      var marker;
      var map;
      var image = 'taxi-icon.png';//image變數指向計程車圖示檔案,圖示檔案請放在相同目錄
      function mark(lat, log){//標註座標函式
        var m = new google.maps.LatLng(lat, log);
        marker = new google.maps.Marker({
          map:map,
          draggable:true,
          position: m,
          icon: image //指定標示圖案為image
        });     
      }

      function initialize() {
        var mapOptions = {
          zoom: 15,
          mapTypeId: google.maps.MapTypeId.ROADMAP,
          center: centerPoint
        };

        map = new google.maps.Map(document.getElementById('map_canvas'),
                mapOptions);

      }
      
      function centerAt(latitude, longitude){//地圖以給予的座標為中心,即移動地圖至給定的座標
          myLatlng = new google.maps.LatLng(latitude,longitude);
          map.panTo(myLatlng);
      }    

    </script>
  </head>
  <body onload="initialize()">
    <div id="map_canvas" style="width: device-width; height: 460px;">map div</div>
  </body>
</html>


專案目錄:


Comments

颯塔 said…
請問一下 我將下面的文章有一個切換分頁的程式和這個結合起來,想說按個按鈕到第二個分頁就可以使用GPS定位,可是地圖都呈白色的,如果只按照這篇文章做倒是有地圖跑出來,我想問如何解決它不在主頁地圖會白畫面
颯塔 said…
我想請問一下 我按照其他篇文章創造另一個分頁 把地圖放在另一個分頁 可是這樣地圖就變白色的 但是如果我按照這篇文章倒是地圖會顯示出來 我想問的是在主頁可以顯示地圖 但分頁就不能顯示 該如何解決呢?
Unknown said…
謝謝您的教學文,對我的幫助很大!
我最近剛好在做畢業專題,面臨到google從v2改成v3,可以參考的資料變得很少!
感謝有您的部落格教學,讓我省了不少麻煩:)
Doctor said…
請問要如何改成不按Button,它會自動擷取經緯度並標註在地圖上?
Doctor said…
請問如何改成不按Button,它會自動擷取經緯度並標註在地圖上?
NDistance said…
Hi, 陳先生你好,想請問一下要怎麼用v3協定去寫Google map的軌跡紀錄?
剛接觸這領域的東西,也請您多多指教,謝謝您。

Popular posts from this blog