Google Maps Android API V2で現在地の緯度・経度・標高を表示


Google Maps Android API V2でLocationを使った場合、標高(Altitude)を取得しようとしても、0.0の値しか返ってこないことがあります。

こういう場合、標高をHttpリクエストを使って、GoogleのElevation APIから取得してみます。

現在位置の取得には、端末のGPS機能を使います。

Eclipseの新規プロジェクトを作成する場合、Google-play-service_libを使います。

Google-play-service_libの使い方やMapsのAPIキー取得についてはこのページ参照

現在位置の取得の場合、上のページと異なるコードは以下の2つ。

【activity_main.xml】

<RelativeLayout 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"
    tools:context=".MainActivity" >
 
    <TextView
        android:id="@+id/textview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
 
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/textview1"
        class="com.google.android.gms.maps.SupportMapFragment" />
 
</RelativeLayout>

【MainActivity.java】

import android.location.Criteria;
import android.location.Location;

import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.widget.TextView;
 
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;

import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.ConnectionResult;
import android.app.Dialog;

import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.model.CameraPosition;


public class MainActivity extends FragmentActivity implements OnConnectionFailedListener, LocationListener, ConnectionCallbacks {

    GoogleMap googleMap;
    
    HttpResponse httpResponse;
    
    public double latitude = 0;
    public double longitude = 0;
    
     private LocationClient mLocationClient = null;
     private static final LocationRequest REQUEST = LocationRequest.create()
            .setInterval(5000) // 5 seconds
            .setFastestInterval(16) // 16ms = 60fps
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    
    
    
    LocationManager locationManager;
        String provider;
        Location location;
        SupportMapFragment mapfragment;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        //Google Play Servicesが使えるかどうかのステータス
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
 
        if(status!=ConnectionResult.SUCCESS){ 
            // Google Play Services が使えない場合
            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
            dialog.show();
 
        }else { 
            // Google Play Services が使える場合
            //activity_main.xmlのSupportMapFragmentへの参照を取得
            SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
            
            //fragmentからGoogleMap objectを取得
            googleMap = fm.getMap();
            
            //Google MapのMyLocationレイヤーを使用可能にする
            googleMap.setMyLocationEnabled(true);
            
            //システムサービスのLOCATION_SERVICEからLocationManager objectを取得
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        mLocationClient = new LocationClient(getApplicationContext(), this, this); // ConnectionCallbacks, OnConnectionFailedListener
        if (mLocationClient != null) {
            // Google Play Servicesに接続
            mLocationClient.connect();
        }
    
        
        
    }
    
    @Override
    public void onPause(){
        super.onPause();
        
        if (mLocationClient != null) {
            // Google Play Servicesに接続
            mLocationClient.disconnect();
        }
        
    }


    @Override
    public void onLocationChanged(Location location) {

    // 現在地に移動
        CameraPosition cameraPos = new CameraPosition.Builder()
            .target(new LatLng(location.getLatitude(), location.getLongitude())).zoom(17.0f)
            .bearing(0).build();
        gMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPos)); 
    }
 
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        // TODO Auto-generated method stub
        mLocationClient.requestLocationUpdates(REQUEST,this); // LocationListener
    }

    @Override
    public void onDisconnected() {
        // TODO Auto-generated method stub
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}


標高を取得して、緯度・経度と一緒にTextViewに表示してみます。

AsyncTaskを使わない場合

private void getAltitude(double lat,double lon){
        
        HttpClient httpClient = new DefaultHttpClient();
        //Google Elevation APIサービスにアクセスして標高取得
    //ここではJSONではなくXMLで結果を返すようにしています
        String uri = "http://maps.googleapis.com/maps/api/elevation/xml?locations=" + lat + "," + lon + "&sensor=true";
        HttpGet request = new HttpGet(uri);
        
        
        try {
            httpResponse = httpClient.execute(request);
        } catch (Exception e) {
            Log.e("HttpSampleActivity", "Execute エラー");
        }
        
        int status = httpResponse.getStatusLine().getStatusCode();
         
        if (HttpStatus.SC_OK == status) {
            try {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                httpResponse.getEntity().writeTo(outputStream);
        //パーサーに渡す
                xml_parse(outputStream.toString());
            } catch (Exception e) {
                Log.e("HttpSampleActivity", "エラー");
            }
        } else {
            Log.e("HttpSampleActivity", "Status" + status);
        }
    }
    
    //XMLパーサーで解析して標高値を取り出す
    private void xml_parse(String str) {
        try{
            XmlPullParser xmlPullParser = Xml.newPullParser();
            xmlPullParser.setInput(new StringReader(str));
     
            int eventType;
            while ((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) {
                if (eventType == XmlPullParser.START_TAG && "elevation".equals(xmlPullParser.getName())) {
                    //Log.d("HttpSampleActivity", xmlPullParser.nextText());
                    String ALT = xmlPullParser.nextText();
            //標高値の桁数調整
                double temp = Double.parseDouble(ALT);
                temp = temp * 100;
                temp = Math.ceil(temp);
                temp = temp / 100;
                ALT = String.valueOf(temp);
                    
                    //
                    TextView textview = (TextView) findViewById(R.id.textview1);
                    textview.setText("標高:約" + ALT + "(m),緯度:" + latitude + ",経度:" + longitude);
                    
                }
            }
        } catch (Exception e){
            Log.d("HttpSampleActivity", "Error:parse");
        }
    }

こんな感じ。表示対象は画像中央の青い点のところ。
Google Maps Android API V2


インストール

インストール・実行は自己責任でお願いします。

Target:Android 2.3.3 or later

動作確認実機:Xperia acro(docomo) Android 2.3.4

AsyncTaskを使っていないので、Android 3.0以上では使えません…..の筈です。


アプリをQRコードからインストールする方法はコチラを参照

Be the first to comment

Leave a Reply

Your email address will not be published.


*