現在取り組んでいるアプリに Google マップを統合する作業を行っていますが、これまでのところ、かなり不快な時間を過ごしてきました。とにかく、地図を表示する SupportMapFragment を最終的に取得し、場所とズーム レベルを設定しました。
これまでの私のコードの機能ビットは次のとおりです。
@Override
public void onActivityCreated( Bundle savedInstanceState ) {
super.onActivityCreated( savedInstanceState );
Location location = BundleChecker.getExtraOrThrow( KEY_LOCATION, new Bundle[] { savedInstanceState, getArguments() } );
setLocation( location );
if ( checkGooglePlayServicesStatus() == ConnectionResult.SUCCESS ) {
setMapFragment( new SupportMapFragment() );
getActivity().getSupportFragmentManager().beginTransaction().add( R.id.location_detail_mapFrame, getMapFragment() ).commit();
}
populateAddress();
attachButtonListeners();
Runnable initMap = new Runnable() {
@Override
public void run() {
if ( checkGooglePlayServicesStatus() == ConnectionResult.SUCCESS ) {
try {
GoogleMap map = getMapFragment().getMap();
LatLng latLng = getLocation().getAddress().getLatLng( getActivity() );
CameraUpdate update = CameraUpdateFactory.newLatLngZoom( latLng, DEFAULT_MAP_ZOOM );
map.animateCamera( update );
}
catch (IOException e) {
Log.e( TAG, e.getMessage(), e );
Toast.makeText( getActivity(), "Unable to find location", Toast.LENGTH_SHORT ).show();
}
}
}
};
Handler handler = new Handler();
handler.postDelayed( initMap, 200 );
}
また、Address モデルから LatLng を取得するための簡単な便利なメソッドを作成しましたが、これも批判される可能性があります。
/*
* Convenience method to easily check if there is a valid lat & lng in this address
*/
public boolean hasLatLng() {
return getLatitude() != null && getLongitude() != null;
}
/*
* Convenience method for use with Google Maps API
*/
public LatLng getLatLng( Context context ) throws IOException {
LatLng latLng = null;
if ( hasLatLng() ) {
latLng = new LatLng( getLatitude(), getLongitude() );
}
else {
String locationString = getStreet() + ", " + AddressUtil.makeCityStateZipString( this );
Geocoder geoCoder = new Geocoder( context );
try {
List<android.location.Address> matches = geoCoder.getFromLocationName( locationString, 2 );
if ( matches != null && matches.size() > 0 ) {
double lat = matches.get( 0 ).getLatitude();
double lng = matches.get( 0 ).getLongitude();
latLng = new LatLng( lat, lng );
}
}
catch (IOException e) {
throw new IOException( e );
}
}
return latLng;
}
このコードは理想的ではなく、リファクタリングする必要があることは承知しています。Google マップを使用するのはこれが初めてなので、どのようにすればよいかについて提案をお気軽に提供してください。MapFragment をレイアウト XML として使用しようとしたときに多くの問題が発生したため、プログラムで作成しています。
問題の核心: ステージング サーバーから偽の住所データを取得していたため、Address#getLatLng メソッドが null を返し、CameraUpdateFactory.newLatLngZoom を呼び出すときに例外が発生しました。この例外を受け取った後、Google から地図データを取得できなくなりました。マップ フラグメントは空白になり、logcat にメッセージが表示されます。
05-21 18:11:42.903: I/Google Maps Android API(15747): Google サーバーへの接続に失敗しました。接続が確立されると、別の試行が行われます。
05-21 18:11:43.093: E/Google Maps Android API(15747): マップの読み込みに失敗しました。Google サーバーへの接続中にエラーが発生しました。これはおそらく認証の問題です (ただし、ネットワーク エラーが原因である可能性があります)。
新しい API キーを作成し、マニフェストの現在の API キーを変更せずに置き換えました。上記のコードに加えた唯一の変更は、null LatLng を説明することでした。その後、コードを機能状態に戻そうとする無意味な試みで、これらの変更を元に戻しました。
さらに、少し奇妙なことに、Google Play Services Extras に含まれているサンプル マップ プロジェクトを作成しました。これは完全に機能します (別の API キーがあります)。
ここで何が間違っていたのでしょうか? 私は明らかな何かを見落としていますか?