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】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="tag"><RelativeLayout <span class="attr">xmlns:android=</span><span class="value">"http://schemas.android.com/apk/res/android"</span> <span class="attr">xmlns:tools=</span><span class="value">"http://schemas.android.com/tools"</span> <span class="attr">android:layout_width=</span><span class="value">"match_parent"</span> <span class="attr">android:layout_height=</span><span class="value">"match_parent"</span> <span class="attr">tools:context=</span><span class="value">".MainActivity"</span> ></span> <span class="tag"><TextView <span class="attr">android:id=</span><span class="value">"@+id/textview1"</span> <span class="attr">android:layout_width=</span><span class="value">"wrap_content"</span> <span class="attr">android:layout_height=</span><span class="value">"wrap_content"</span> /></span> <span class="tag"><fragment <span class="attr">xmlns:android=</span><span class="value">"http://schemas.android.com/apk/res/android"</span> <span class="attr">android:id=</span><span class="value">"@+id/map"</span> <span class="attr">android:layout_width=</span><span class="value">"match_parent"</span> <span class="attr">android:layout_height=</span><span class="value">"match_parent"</span> <span class="attr">android:layout_below=</span><span class="value">"@id/textview1"</span> <span class="attr">class=</span><span class="value">"com.google.android.gms.maps.SupportMapFragment"</span> /></span> <span class="tag"></RelativeLayout></span> |
【MainActivity.java】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
<span class="keyword">import</span> android.location.Criteria; <span class="keyword">import</span> android.location.Location; <span class="keyword">import</span> android.location.LocationManager; <span class="keyword">import</span> android.os.Bundle; <span class="keyword">import</span> android.support.v4.app.FragmentActivity; <span class="keyword">import</span> android.view.Menu; <span class="keyword">import</span> android.widget.TextView; <span class="keyword">import</span> com.google.android.gms.maps.CameraUpdateFactory; <span class="keyword">import</span> com.google.android.gms.maps.GoogleMap; <span class="keyword">import</span> com.google.android.gms.maps.SupportMapFragment; <span class="keyword">import</span> com.google.android.gms.maps.model.LatLng; <span class="keyword">import</span> com.google.android.gms.common.GooglePlayServicesUtil; <span class="keyword">import</span> com.google.android.gms.common.ConnectionResult; <span class="keyword">import</span> android.app.Dialog; <span class="keyword">import</span> android.util.Log; <span class="keyword">import</span> com.google.android.gms.common.ConnectionResult; <span class="keyword">import</span> com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; <span class="keyword">import</span> com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; <span class="keyword">import</span> com.google.android.gms.location.LocationClient; <span class="keyword">import</span> com.google.android.gms.location.LocationListener; <span class="keyword">import</span> com.google.android.gms.location.LocationRequest; <span class="keyword">import</span> com.google.android.gms.maps.model.CameraPosition; <span class="keyword">public</span> <span class="keyword">class</span> MainActivity <span class="keyword">extends</span> FragmentActivity <span class="keyword">implements</span> OnConnectionFailedListener, LocationListener, ConnectionCallbacks { GoogleMap googleMap; HttpResponse httpResponse; <span class="keyword">public</span> <span class="keyword">double</span> latitude = <span class="num">0</span>; <span class="keyword">public</span> <span class="keyword">double</span> longitude = <span class="num">0</span>; <span class="keyword">private</span> LocationClient mLocationClient = null; <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> LocationRequest REQUEST = LocationRequest.create() .setInterval(<span class="num">5000</span>) <span class="rem">// 5 seconds</span> .setFastestInterval(<span class="num">16</span>) <span class="rem">// 16ms = 60fps</span> .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationManager locationManager; String provider; Location location; SupportMapFragment mapfragment; @Override <span class="keyword">public</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) { <span class="keyword">super</span>.onCreate(savedInstanceState); setContentView(R.layout.activity_main); <span class="rem">//Google Play Servicesが使えるかどうかのステータス</span> <span class="keyword">int</span> status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext()); <span class="keyword">if</span>(status!=ConnectionResult.SUCCESS){ <span class="rem">// Google Play Services が使えない場合</span> <span class="keyword">int</span> requestCode = <span class="num">10</span>; Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, <span class="keyword">this</span>, requestCode); dialog.show(); }<span class="keyword">else</span> { <span class="rem">// Google Play Services が使える場合</span> <span class="rem">//activity_main.xmlのSupportMapFragmentへの参照を取得</span> SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); <span class="rem">//fragmentからGoogleMap objectを取得</span> googleMap = fm.getMap(); <span class="rem">//Google MapのMyLocationレイヤーを使用可能にする</span> googleMap.setMyLocationEnabled(true); <span class="rem">//システムサービスのLOCATION_SERVICEからLocationManager objectを取得</span> locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); mLocationClient = <span class="keyword">new</span> LocationClient(getApplicationContext(), <span class="keyword">this</span>, <span class="keyword">this</span>); <span class="rem">// ConnectionCallbacks, OnConnectionFailedListener</span> <span class="keyword">if</span> (mLocationClient != null) { <span class="rem">// Google Play Servicesに接続</span> mLocationClient.connect(); } } @Override <span class="keyword">public</span> <span class="keyword">void</span> onPause(){ <span class="keyword">super</span>.onPause(); <span class="keyword">if</span> (mLocationClient != null) { <span class="rem">// Google Play Servicesに接続</span> mLocationClient.disconnect(); } } @Override <span class="keyword">public</span> <span class="keyword">void</span> onLocationChanged(Location location) { <span class="rem">// 現在地に移動</span> CameraPosition cameraPos = <span class="keyword">new</span> CameraPosition.Builder() .target(<span class="keyword">new</span> LatLng(location.getLatitude(), location.getLongitude())).zoom(<span class="num">17.0</span>f) .bearing(<span class="num">0</span>).build(); gMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPos)); } @Override <span class="keyword">public</span> <span class="keyword">void</span> onConnectionFailed(ConnectionResult result) { <span class="rem">// TODO Auto-generated method stub</span> } @Override <span class="keyword">public</span> <span class="keyword">void</span> onConnected(Bundle connectionHint) { <span class="rem">// TODO Auto-generated method stub</span> mLocationClient.requestLocationUpdates(REQUEST,<span class="keyword">this</span>); <span class="rem">// LocationListener</span> } @Override <span class="keyword">public</span> <span class="keyword">void</span> onDisconnected() { <span class="rem">// TODO Auto-generated method stub</span> } @Override <span class="keyword">public</span> <span class="keyword">boolean</span> onCreateOptionsMenu(Menu menu) { <span class="rem">// Inflate the menu; this adds items to the action bar if it is present.</span> getMenuInflater().inflate(R.menu.main, menu); <span class="keyword">return</span> true; } } |
標高を取得して、緯度・経度と一緒にTextViewに表示してみます。
AsyncTaskを使わない場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<span class="keyword">private</span> <span class="keyword">void</span> getAltitude(<span class="keyword">double</span> lat,<span class="keyword">double</span> lon){ HttpClient httpClient = <span class="keyword">new</span> DefaultHttpClient(); <span class="rem">//Google Elevation APIサービスにアクセスして標高取得</span> <span class="rem">//ここではJSONではなくXMLで結果を返すようにしています</span> String uri = <span class="str">"http://maps.googleapis.com/maps/api/elevation/xml?locations="</span> + lat + <span class="str">","</span> + lon + <span class="str">"&sensor=true"</span>; HttpGet request = <span class="keyword">new</span> HttpGet(uri); <span class="keyword">try</span> { httpResponse = httpClient.execute(request); } <span class="keyword">catch</span> (Exception e) { Log.e(<span class="str">"HttpSampleActivity"</span>, <span class="str">"Execute エラー"</span>); } <span class="keyword">int</span> status = httpResponse.getStatusLine().getStatusCode(); <span class="keyword">if</span> (HttpStatus.SC_OK == status) { <span class="keyword">try</span> { ByteArrayOutputStream outputStream = <span class="keyword">new</span> ByteArrayOutputStream(); httpResponse.getEntity().writeTo(outputStream); <span class="rem">//パーサーに渡す</span> xml_parse(outputStream.toString()); } <span class="keyword">catch</span> (Exception e) { Log.e(<span class="str">"HttpSampleActivity"</span>, <span class="str">"エラー"</span>); } } <span class="keyword">else</span> { Log.e(<span class="str">"HttpSampleActivity"</span>, <span class="str">"Status"</span> + status); } } <span class="rem">//XMLパーサーで解析して標高値を取り出す</span> <span class="keyword">private</span> <span class="keyword">void</span> xml_parse(String str) { <span class="keyword">try</span>{ XmlPullParser xmlPullParser = Xml.newPullParser(); xmlPullParser.setInput(<span class="keyword">new</span> StringReader(str)); <span class="keyword">int</span> eventType; <span class="keyword">while</span> ((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) { <span class="keyword">if</span> (eventType == XmlPullParser.START_TAG && <span class="str">"elevation"</span>.equals(xmlPullParser.getName())) { <span class="rem">//Log.d("HttpSampleActivity", xmlPullParser.nextText());</span> String ALT = xmlPullParser.nextText(); <span class="rem">//標高値の桁数調整</span> <span class="keyword">double</span> temp = Double.parseDouble(ALT); temp = temp * <span class="num">100</span>; temp = Math.ceil(temp); temp = temp / <span class="num">100</span>; ALT = String.valueOf(temp); <span class="rem">//</span> TextView textview = (TextView) findViewById(R.id.textview1); textview.setText(<span class="str">"標高:約"</span> + ALT + <span class="str">"(m),緯度:"</span> + latitude + <span class="str">",経度:"</span> + longitude); } } } <span class="keyword">catch</span> (Exception e){ Log.d(<span class="str">"HttpSampleActivity"</span>, <span class="str">"Error:parse"</span>); } } |
こんな感じ。表示対象は画像中央の青い点のところ。
インストール
インストール・実行は自己責任でお願いします。
Target:Android 2.3.3 or later
動作確認実機:Xperia acro(docomo) Android 2.3.4
AsyncTaskを使っていないので、Android 3.0以上では使えません…..の筈です。
Leave a Reply