Create a new project. Select Google Maps Activity and enter the project name to proceed. Replace the YOUR_KEY_HERE part of the automatically generated res / values / google_maps_api.xml with your own API key that you have obtained.
google_maps_api.xml
<resources>
<!--Abbreviation-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>
At this point, start the program once and check that the map is displayed properly.
Create a layout for infoWindow. This time, I will make it simple with only one ImageView in LinearLayout.
info_window_layout.xml
<?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>
Implement InfoWindowAdapter in the onMapReady method of MapsActivity.java.
MapsActivity.java
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//~ Abbreviation ~
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
Marker lastMarker;
View infoWindow;
@Override
public View getInfoWindow(Marker marker) {
return null;
}
@Override
public View getInfoContents(Marker marker) {
//This time, describe the process here
return null;
}
});
The infoWindowAdapter must override both the getInfoWindow () and getInfoContents () methods, and write the process in one and return null in the other. This time, describe the process in getInfoContents (). Also, for the convenience of processing, declare the variables lastMarker and infoWindow in the class of infoWindowAdapter.
@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);
//↑ Implemented after this
}
return infoWindow;
}
As you can see if you follow the process in detail after implementing it to the end, if you try to display infoWindow by clicking the marker, the getInfoWindow () method will be called twice in total. The process of downloading the image runs the first time, and only return infoWindow; is executed the second time to prevent an infinite loop.
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();
}
}
Describe DownladImageTask, which is a class for image download processing. Since the image download needs to be done asynchronously, it inherits AsyncTask. The URL of the image is passed as a String when called by execute (), and is received by strings [0] of doInbackground (). The image is set in ImageView by onPostExecute () which is called after the image download is completed, and then the image is displayed in infoWindow by calling marker.showInfoWindow ().
The marker is the default position in Sydney, and the image is the url of what you see when you search for Sydney on the web version of Google map.
MapsActivity.java
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