GoogleMapの現在地表示プログラムについて

866 views
Skip to first unread message

永眠人形

unread,
Oct 11, 2012, 7:27:02 AM10/11/12
to android-g...@googlegroups.com
永眠人形と申します。

取得したGPSの現在地情報を用いて、GoogleMapを表示させる&現在地にアイコンを描画するプログラムを書いています。
プログラム内で位置情報が取得できない場合は、東京駅を初期値にして表示させるようにしています。
一度は確かにプログラムが正常に動き、現在地が表示されたのですが、
次の日以降は東京が表示されるだけで、現在地の表示が出来なくなってしまいました。

試行錯誤したのですが、原因がわからなかったので、質問させていただきました。
問題点や解決策がありましたら、ご教授くださればと思います。

MainActivity.java以外にPinItemizedOverlay.javaとPinOverlayItem.javaがありますが。
問題はどちらかというとMainActivityにあると思うので、そちらは割愛します。

よろしくお願いいたします。




[環境]
実機:Motorola XT701
androidバージョン:2.1 -update1
eclipse Juno
SDKはandroid-sdk_r18-windowsを利用しました。

[ソース]
■MainActivity.java
package com.example.androidmap;

import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class MainActivity extends MapActivity {

final double DEG_RATE = 1E6;

private MapView map_mv;
private GeoPoint geoPoint;
MapController mapCntl;
private LocationManager mlManager;
private PinItemizedOverlay pinOverlay;
//東京の位置情報
final GeoPoint GEO_TOKYO_STA = new GeoPoint(35681980,139766092);
final int ZOOM_NORMAL = 16;

@Override
public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      
      //地図作成
      map_mv = (MapView)findViewById(R.id.MapView);
      mapCntl = map_mv.getController();
      mapCntl.setZoom(ZOOM_NORMAL);
      
      //位置情報の取得
      mlManager = (LocationManager) getSystemService(LOCATION_SERVICE);
      
    //ピンアイコン取得
      Drawable pin = getResources().getDrawable(R.drawable.star);
      //ピンオーバーレイの作成
      pinOverlay = new PinItemizedOverlay(pin);
      //ピンオーバーレイをマップに追加
      map_mv.getOverlays().add(pinOverlay);
}

public void onRestart() {
super.onRestart();
}

public void onStart() {
super.onStart();
}

  @Override
  public void onResume() {
 super.onResume();

 String provider = mlManager.getBestProvider(new Criteria(), true);
 Location location = null;

 if (provider != null) {
 //最後の位置情報
 location = mlManager.getLastKnownLocation(provider);
 }

 double lat = 0.0D;
 double lng = 0.0D;
  if (location != null) {
  lat = location.getLatitude();
  lng = location.getLongitude();
  geoPoint = new GeoPoint((int)(lat * DEG_RATE),
  (int)(lng * DEG_RATE));
  //ピンの場所を決定する
  pinOverlay.addPoint(geoPoint);
 
  } else {
  geoPoint = GEO_TOKYO_STA;
  lat = geoPoint.getLatitudeE6() / DEG_RATE;
  lng = geoPoint.getLongitudeE6() / DEG_RATE;
  }

  mapCntl.animateTo(geoPoint);
  }

  @Override
  public void onPause() {
  super.onPause();
  }

  public void onStop() {
  super.onStop();
  }

  public void onDestroy() {
  super.onDestroy();
  }

  @Override
  protected boolean isRouteDisplayed() {
  // TODO 自動生成されたメソッド・スタブ
  return false;
  }

}

Shin Miyazaki

unread,
Oct 11, 2012, 8:06:11 AM10/11/12
to android-g...@googlegroups.com
こんばんは、みやざきです。

requestLocationUpdates呼び出しが無いですね。
一度動いたのは、たまたま他のGPSを使用するアプリを使用したからでは?

2012年10月11日 20:27 永眠人形 <ag.r...@gmail.com>:

--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msg/android-group-japan/-/ZJsnOJpv8wYJ にアクセスしてください。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。

Yusuke Naka

unread,
Oct 11, 2012, 9:13:30 AM10/11/12
to android-g...@googlegroups.com
はじめまして。
なかと申します。

まず、getBestProvider は使わない方がいいです。
機種によってはGPSプロバイダーを返してくれなかったりします。
スマホではGPS測位かネットワーク測位しか手段は無いと思いますのでどちらが利用可能か、

mlManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
mlManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

で、確認して下さい。
GPSは位置精度は高いですが取得に時間がかかりますので、どちらの優先順位を高くするかはお好みで。

取得可能なプロバイダーが判明すれば、そのプロバイダーに対して最終位置情報を取得します。

//GPSの場合
mlManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
//ネットワークの場合
mlManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)

mlManager.getLastKnownLocation
は最後に端末が取得した位置情報を返却するので、他の位置取得アプリも含めて、その端末が全く位置情報を取得できていなければnullが返ります。
みやざきさま がおっしゃる通り、結果がnullであれば requestLocationUpdates で位置取得を行って下さい。
getBestProvider ではなく getProviders を利用して利用可能なすべてのプロバイダーに対して位置取得した方が確実に位置情報がとれます。

List<String> providers = mlManager.getProviders(true);
for (String provider : providers) {
mlManager.requestLocationUpdates(provider,0, 0,this);
}

あとは、位置情報が更新されたら以下のメソッドが呼び出されるので、
オーバーライドし処理を追記して下さい。

public void onLocationChanged(Location location) {}


以上です。
間違いがあれば、ご容赦ください。

永眠人形

unread,
Oct 13, 2012, 2:58:42 AM10/13/12
to android-g...@googlegroups.com
みやざきさま、なかさま、アドバイスありがとうございます。

getBestProvider を使うのをやめ、ボタンがクリックされた際に
Location location = mlManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);を調べ、
location がnullの場合に、以下のようにすることでGPSが動くようになりました。

List<String> providers = mlManager.getProviders(true); 
for (String provider : providers) { 
        mlManager.requestLocationUpdates(provider,0, 0,this); 
}

位置情報が更新されたら、onLocationChangedが呼び出されるので、
そこで以下のような経度と緯度を取得する処理を記述しているはずなのですが、
中々、onLocationChagedが呼び出されないようです。

TextView snippet = (TextView)findViewById(R.id.text_location_snippet);
snippet.setText("緯度:" + location.getLatitude() + "経度:" + location.getLongitude() +
"精度:" + location.getAccuracy() + "m");

初めての測位には時間がかかる、または屋内では測位できないことがあるということなのでしょうか?

 
2012年10月11日木曜日 22時13分30秒 UTC+9 Yusuke Naka:

Yusuke Naka

unread,
Oct 13, 2012, 11:15:03 PM10/13/12
to android-g...@googlegroups.com
永眠人形さま

仲です。

屋内での初回GPS取得は、窓ガラスにベッタリくっつけてしばらく粘ったりしない限り、まず不可能だと思います。

初回の取得時間を短縮する手段としては、
事前に他のGPSアプリなどで位置取得を行なっておくか(そのような用途のアプリもあります)、
最初の取得取得をネットワークプロバイダーから行い、GPSで取得が可能になるまで時間をかせぐなどの手段があるかと思います。
ネットワークプロバイダーからの取得はwi-fiがONになっていれば大抵取得できます。
精度は期待できませんが、屋内での利用も想定するのであれば必須かと思います。

また、requestLocationUpdatesnのminTimeとminDistanceを調整してみるのもいいかもしれません。
GPS周りは、機種依存やAndroidのバージョン違いによる動作差異がありますので、
根気よくチューニングしてみてください。

以上です。

--
from Yusuke
Reply all
Reply to author
Forward
0 new messages