1.プロジェクト作成
新規プロジェクトを作成します。
Google Maps Activityを選択し、プロジェクト名を入力して進みます。
自動的に生成されるres/values/google_maps_api.xmlのYOUR_KEY_HEREの部分を、取得してある自身のAPIキーで置き換えておきます。
<resources>
<!-- 略 -->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>
この時点で一度プログラムを起動し、地図がちゃんと表示される事を確認します。
#2.レイアウトファイルを記述する
infoWindow用のレイアウトを作成します。今回はLinearLayoutにImageViewが一つあるだけのシンプルなものにします。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
#3.InfoWindowAdapterの記述
MapsActivity.javaのonMapReadyメソッドにて、InfoWindowAdapterを実装します。
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// 〜略〜
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
Marker lastMarker;
View infoWindow;
@Override
public View getInfoWindow(Marker marker) {
return null;
}
@Override
public View getInfoContents(Marker marker) {
// 今回はこちらに処理を記述
return null;
}
});
infoWindowAdapterはgetInfoWindow()メソッドとgetInfoContents()メソッドの両方をオーバーライドする必要があり、かつどちらかに処理を記述しもう片方はnullを返す必要があります。今回はgetInfoContents()に処理を記述します。また、処理の都合上必要な変数lastMarkerとinfoWindowをinfoWindowAdapterのクラス内で宣言しておきます。
#4.getInfoContents()メソッドの記述
@Override
public View getInfoContents(Marker marker) {
if(lastMarker==null || !lastMarker.equals(marker)){
lastMarker = marker;
infoWindow = getLayoutInflater().inflate(R.layout.info_window_layout,null);
ImageView img = infoWindow.findViewById(R.id.img);
new DownloadImageTask(img,marker).execute(imgUrl);
// ↑このあと実装
}
return infoWindow;
}
最後まで実装してから細かく処理を追えばわかることですが、マーカーをクリックしてinfoWindowを表示させようとするとgetInfoWindow()メソッドは合計2回呼ばれることになります。1回目で画像をダウンロードする処理が走り、2回目はreturn infoWindow;だけ実行され、無限ループにならないようにしています。
#5.画像のダウンロード処理のクラスを記述
private class DownloadImageTask extends AsyncTask<String,Void, Bitmap>{
ImageView img = null;
Marker marker = null;
DownloadImageTask(ImageView img, Marker marker){
this.img = img;
this.marker = marker;
}
@Override
protected Bitmap doInBackground(String... strings) {
Bitmap bmp = null;
try{
String urlStr = strings[0];
URL url = new URL(urlStr);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
con.connect();
int resp = con.getResponseCode();
switch (resp){
case HttpURLConnection.HTTP_OK:
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
is.close();
break;
default:
break;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bmp;
}
@Override
protected void onPostExecute(Bitmap bmp){
img.setImageBitmap(bmp);
marker.showInfoWindow();
}
}
画像のダウンロード処理のクラスであるDownladImageTaskを記述します。画像のダウンロードは非同期で行う必要があるのでAsyncTaskを継承しています。画像のURLは、execute()で呼び出すときにStringで受け渡し、doInbackground()のstrings[0]で受け取ります。画像のダウンロードが完了したあとで呼ばれるonPostExecute()でImageViewに画像をセットしており、そのあとmarker.showInfoWindow()を呼ぶことでinfoWindowに画像が表示されます。
6.MapsActivity.javaの全体
マーカーはデフォルトの位置であるシドニー、画像は、ウェブ版のGoogle mapでシドニーで検索したときに出たもののurlを指定しています。
package com.example.test;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
final String imgUrl = "https://lh5.googleusercontent.com/p/AF1QipNUrZvzjGohRsYfuwIpCS2MjYdAq_3xruYM5imS=w408-h271-k-no";
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
Marker lastMarker;
View infoWindow;
@Override
public View getInfoWindow(Marker marker) {
return null;
}
@Override
public View getInfoContents(Marker marker) {
if(lastMarker==null || !lastMarker.equals(marker)){
lastMarker = marker;
infoWindow = getLayoutInflater().inflate(R.layout.info_window_layout,null);
ImageView img = infoWindow.findViewById(R.id.img);
new DownloadImageTask(img,marker).execute(imgUrl);
}
return infoWindow;
}
});
}
private class DownloadImageTask extends AsyncTask<String,Void, Bitmap>{
ImageView img = null;
Marker marker = null;
DownloadImageTask(ImageView img, Marker marker){
this.img = img;
this.marker = marker;
}
@Override
protected Bitmap doInBackground(String... strings) {
Bitmap bmp = null;
try{
String urlStr = strings[0];
URL url = new URL(urlStr);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
con.connect();
int resp = con.getResponseCode();
switch (resp){
case HttpURLConnection.HTTP_OK:
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
is.close();
break;
default:
break;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bmp;
}
@Override
protected void onPostExecute(Bitmap bmp){
img.setImageBitmap(bmp);
marker.showInfoWindow();
}
}
}
#参考
https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter
https://stackoverflow.com/questions/36335004/how-to-get-image-in-infowindow-on-google-maps-with-picasso-android