Android Google 地图中未显示名胜古迹
Places of Interest not showing in Android Google Maps
所以我正在按照教程查找感兴趣的地方:LINK。我在 Google 控制台中打开了我的地点 API 和 Google 地图 V2。我有我的 API 密钥并且所有设置都正确,因为我的地图和我的当前位置确实出现了。但是这些地方永远不会显示。我在 logcat 中也没有看到任何错误。
这是我的代码:
MapsActivity.java
package indabutt.com.indabuttalpha;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
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 android.location.Location;
import android.location.LocationManager;
import android.content.Context;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class MapsActivity extends FragmentActivity {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private LocationManager locMan;
private Marker userMarker;
private Marker[] placeMarkers;
private final int MAX_PLACES = 10;
private MarkerOptions[] places;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
}
private void updatePlaces(){
//Update Location
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location lastLoc = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
double lat = lastLoc.getLatitude();
double lng = lastLoc.getLongitude();
LatLng lastLatLng = new LatLng(lat,lng);
if(userMarker!=null) userMarker.remove();
userMarker = mMap.addMarker(new MarkerOptions()
.position(lastLatLng)
.title("You are here!")
.snippet("I am here BITCH!!!"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(lastLatLng,10));
String latVal=String.valueOf(lat);
String lngVal=String.valueOf(lng);
String url;
try {
url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="
+URLEncoder.encode(latVal, "UTF-8")
+","
+URLEncoder.encode(lngVal, "UTF-8")
+"&radius="
+URLEncoder.encode("5000", "UTF-8")
+"&sensor="
+URLEncoder.encode("true", "UTF-8")
+"&types="
+URLEncoder.encode("food|bar|church|museum|art_gallery", "UTF-8")
+"&key="
+ URLEncoder.encode("AIzaSyBOY3eUzIL_Pz8NB9pSdRJcABiCw_kQ0M8", "UTF-8");
new GetPlaces().execute(url);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {@link #setUpMap()} once when {@link #mMap} is not null.
* <p/>
* If it isn't installed {@link SupportMapFragment} (and
* {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
* method in {@link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p/>
* This should only be called once and when we are sure that {@link #mMap} is not null.
*/
private void setUpMap() {
//mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
placeMarkers = new Marker[MAX_PLACES];
updatePlaces();
}
private class GetPlaces extends AsyncTask<String, Void, String>{
//fetch and parse place data
protected String doInBackground(String... placesURL){
//fetch places
StringBuilder placesBuilder = new StringBuilder();
//process search parameter string(s)
for (String placeSearchURL : placesURL){
//execute Search
HttpClient placesClient = new DefaultHttpClient();
try {
//try to fetch the data
//HTTP Get receives URL string
HttpGet placesGet = new HttpGet(placeSearchURL);
//execute GET with Client - return response
HttpResponse placesResponse = placesClient.execute(placesGet);
//check response status
StatusLine placeSearchStatus = placesResponse.getStatusLine();
//only carry on if response is OK
if (placeSearchStatus.getStatusCode() == 200) {
//get response entity
HttpEntity placesEntity = placesResponse.getEntity();
//get input stream setup
InputStream placesContent = placesEntity.getContent();
//create reader
InputStreamReader placesInput = new InputStreamReader(placesContent);
//use buffered reader to process
BufferedReader placesReader = new BufferedReader(placesInput);
//read a line at a time, append to string builder
String lineIn;
while ((lineIn = placesReader.readLine()) != null) {
placesBuilder.append(lineIn);
}
}
}
catch (Exception e){
e.printStackTrace();
}
}
return placesBuilder.toString();
}
protected void onPostExecute(String result){
//parse place data returned from Google Places
if(placeMarkers!=null){
for(int pm=0; pm<placeMarkers.length; pm++){
if(placeMarkers[pm]!=null)
placeMarkers[pm].remove();
}
}
try{
//parse JSON
JSONObject resultObject = new JSONObject(result);
JSONArray placesArray = resultObject.getJSONArray("results");
places = new MarkerOptions[placesArray.length()];
//loop through places
for(int p=0; p<placesArray.length();p++){
//parse each place
boolean missingValue = false;
LatLng placeLL = null;
String placeName = "";
String vicinity = "";
// int currIcon = othericon;
try{
//attempt to retrieve place data values
missingValue=false;
JSONObject placeObject = placesArray.getJSONObject(p);
JSONObject loc = placeObject.getJSONObject("geometry").getJSONObject("location");
placeLL = new LatLng(
Double.valueOf(loc.getString("lat")),
Double.valueOf(loc.getString("lng"))
);
JSONArray types = placeObject.getJSONArray("types");
for(int t=0; t<types.length();t++){
//what type is it
String thisType = types.get(t).toString();
if(thisType.contains("food")){
// currIcon = foodIcon;
System.out.println("HELLO JAMAL THIS IS FOOD");
break;
}
else if(thisType.contains("bar")){
// currIcon = drinkIcon;
System.out.println("HELLO JAMAL THIS IS BAR");
break;
}
else if(thisType.contains("store")){
System.out.println("HELLO JAMAL THIS IS store");
// currIcon = shopIcon;
break;
}
}
vicinity = placeObject.getString("vicinity");
placeName = placeObject.getString("name");
}
catch (JSONException jse){
missingValue=true;
jse.printStackTrace();
}
if(missingValue) {
places[p] = null;
Log.e("<Jamal>", "Places is missing!");
}
else{
places[p]=new MarkerOptions()
.position(placeLL)
.title(placeName)
// .icon(BitmapDescriptorFactory.fromResource(currIcon))
.snippet(vicinity);
Log.e("<Jamal>", "Places is HERE BITCH!");
}
}
}
catch (Exception e){
e.printStackTrace();
}
if(places!=null && placeMarkers!=null){
for(int p=0; p<places.length && p<placeMarkers.length;p++){
//will be null if a value was missing
if(places[p]!=null)
placeMarkers[p]=mMap.addMarker(places[p]);
}
}
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="indabutt.com.indabuttalpha" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but are recommended.
-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
请回复任何可能的解决方案!
谢谢
谢谢bjiang,但是我在设置我的API Key时犯了一个错误,为了使用Places API,你需要一个Browser Key 以获得接受的 JSON 响应。我正在使用我的 API 密钥,它给了我一个拒绝响应。
我通过将这行代码放入
来捕获有关 JSON 响应的一些日志
while ((lineIn = placesReader.readLine()) != null) {
placesBuilder.append(lineIn);
Log.e("<Five>", lineIn);
}
现在一切正常:)
所以我正在按照教程查找感兴趣的地方:LINK。我在 Google 控制台中打开了我的地点 API 和 Google 地图 V2。我有我的 API 密钥并且所有设置都正确,因为我的地图和我的当前位置确实出现了。但是这些地方永远不会显示。我在 logcat 中也没有看到任何错误。
这是我的代码:
MapsActivity.java
package indabutt.com.indabuttalpha;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
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 android.location.Location;
import android.location.LocationManager;
import android.content.Context;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class MapsActivity extends FragmentActivity {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private LocationManager locMan;
private Marker userMarker;
private Marker[] placeMarkers;
private final int MAX_PLACES = 10;
private MarkerOptions[] places;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
}
private void updatePlaces(){
//Update Location
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location lastLoc = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
double lat = lastLoc.getLatitude();
double lng = lastLoc.getLongitude();
LatLng lastLatLng = new LatLng(lat,lng);
if(userMarker!=null) userMarker.remove();
userMarker = mMap.addMarker(new MarkerOptions()
.position(lastLatLng)
.title("You are here!")
.snippet("I am here BITCH!!!"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(lastLatLng,10));
String latVal=String.valueOf(lat);
String lngVal=String.valueOf(lng);
String url;
try {
url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="
+URLEncoder.encode(latVal, "UTF-8")
+","
+URLEncoder.encode(lngVal, "UTF-8")
+"&radius="
+URLEncoder.encode("5000", "UTF-8")
+"&sensor="
+URLEncoder.encode("true", "UTF-8")
+"&types="
+URLEncoder.encode("food|bar|church|museum|art_gallery", "UTF-8")
+"&key="
+ URLEncoder.encode("AIzaSyBOY3eUzIL_Pz8NB9pSdRJcABiCw_kQ0M8", "UTF-8");
new GetPlaces().execute(url);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {@link #setUpMap()} once when {@link #mMap} is not null.
* <p/>
* If it isn't installed {@link SupportMapFragment} (and
* {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
* method in {@link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p/>
* This should only be called once and when we are sure that {@link #mMap} is not null.
*/
private void setUpMap() {
//mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
placeMarkers = new Marker[MAX_PLACES];
updatePlaces();
}
private class GetPlaces extends AsyncTask<String, Void, String>{
//fetch and parse place data
protected String doInBackground(String... placesURL){
//fetch places
StringBuilder placesBuilder = new StringBuilder();
//process search parameter string(s)
for (String placeSearchURL : placesURL){
//execute Search
HttpClient placesClient = new DefaultHttpClient();
try {
//try to fetch the data
//HTTP Get receives URL string
HttpGet placesGet = new HttpGet(placeSearchURL);
//execute GET with Client - return response
HttpResponse placesResponse = placesClient.execute(placesGet);
//check response status
StatusLine placeSearchStatus = placesResponse.getStatusLine();
//only carry on if response is OK
if (placeSearchStatus.getStatusCode() == 200) {
//get response entity
HttpEntity placesEntity = placesResponse.getEntity();
//get input stream setup
InputStream placesContent = placesEntity.getContent();
//create reader
InputStreamReader placesInput = new InputStreamReader(placesContent);
//use buffered reader to process
BufferedReader placesReader = new BufferedReader(placesInput);
//read a line at a time, append to string builder
String lineIn;
while ((lineIn = placesReader.readLine()) != null) {
placesBuilder.append(lineIn);
}
}
}
catch (Exception e){
e.printStackTrace();
}
}
return placesBuilder.toString();
}
protected void onPostExecute(String result){
//parse place data returned from Google Places
if(placeMarkers!=null){
for(int pm=0; pm<placeMarkers.length; pm++){
if(placeMarkers[pm]!=null)
placeMarkers[pm].remove();
}
}
try{
//parse JSON
JSONObject resultObject = new JSONObject(result);
JSONArray placesArray = resultObject.getJSONArray("results");
places = new MarkerOptions[placesArray.length()];
//loop through places
for(int p=0; p<placesArray.length();p++){
//parse each place
boolean missingValue = false;
LatLng placeLL = null;
String placeName = "";
String vicinity = "";
// int currIcon = othericon;
try{
//attempt to retrieve place data values
missingValue=false;
JSONObject placeObject = placesArray.getJSONObject(p);
JSONObject loc = placeObject.getJSONObject("geometry").getJSONObject("location");
placeLL = new LatLng(
Double.valueOf(loc.getString("lat")),
Double.valueOf(loc.getString("lng"))
);
JSONArray types = placeObject.getJSONArray("types");
for(int t=0; t<types.length();t++){
//what type is it
String thisType = types.get(t).toString();
if(thisType.contains("food")){
// currIcon = foodIcon;
System.out.println("HELLO JAMAL THIS IS FOOD");
break;
}
else if(thisType.contains("bar")){
// currIcon = drinkIcon;
System.out.println("HELLO JAMAL THIS IS BAR");
break;
}
else if(thisType.contains("store")){
System.out.println("HELLO JAMAL THIS IS store");
// currIcon = shopIcon;
break;
}
}
vicinity = placeObject.getString("vicinity");
placeName = placeObject.getString("name");
}
catch (JSONException jse){
missingValue=true;
jse.printStackTrace();
}
if(missingValue) {
places[p] = null;
Log.e("<Jamal>", "Places is missing!");
}
else{
places[p]=new MarkerOptions()
.position(placeLL)
.title(placeName)
// .icon(BitmapDescriptorFactory.fromResource(currIcon))
.snippet(vicinity);
Log.e("<Jamal>", "Places is HERE BITCH!");
}
}
}
catch (Exception e){
e.printStackTrace();
}
if(places!=null && placeMarkers!=null){
for(int p=0; p<places.length && p<placeMarkers.length;p++){
//will be null if a value was missing
if(places[p]!=null)
placeMarkers[p]=mMap.addMarker(places[p]);
}
}
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="indabutt.com.indabuttalpha" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but are recommended.
-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
请回复任何可能的解决方案!
谢谢
谢谢bjiang,但是我在设置我的API Key时犯了一个错误,为了使用Places API,你需要一个Browser Key 以获得接受的 JSON 响应。我正在使用我的 API 密钥,它给了我一个拒绝响应。
我通过将这行代码放入
来捕获有关 JSON 响应的一些日志 while ((lineIn = placesReader.readLine()) != null) {
placesBuilder.append(lineIn);
Log.e("<Five>", lineIn);
}
现在一切正常:)