我正在开发一个Android应用程序,在其中我可以获取用户的当前位置并显示该位置周围的某些位置。对于我的应用,我正在寻找的地方是医院,所以搜索网址是:
String placesSearchStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/" +
"json?location="+lat+","+lng+
"&radius=1000&sensor=true" +
"&types=hospital|health"+
"My_API_KEY_HERE";
我面临的问题是显示地点,我在手机上运行应用程序,它可以工作并显示我的位置,但没有别的(我为每个位置使用不同的标记)。
我尝试使用文本搜索请求,我得到了相同的结果。
这是MainActivity类:
package com.location.test;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
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.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
public class MyMapActivity extends Activity implements LocationListener {
//instance variables for Marker icon drawable resources
private int userIcon, foodIcon, drinkIcon, shopIcon, otherIcon;
//the map
private GoogleMap theMap;
//location manager
private LocationManager locMan;
//user marker
private Marker userMarker;
//places of interest
private Marker[] placeMarkers;
//max
private final int MAX_PLACES = 20;//most returned from google
//marker options
private MarkerOptions[] places;
@SuppressLint("NewApi") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_map);
//get drawable IDs
userIcon = R.drawable.yellow_point;
foodIcon = R.drawable.red_point;
drinkIcon = R.drawable.blue_point;
shopIcon = R.drawable.green_point;
otherIcon = R.drawable.purple_point;
//find out if we already have it
if(theMap==null){
//get the map
theMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.the_map)).getMap();
//check in case map/ Google Play services not available
if(theMap!=null){
//ok - proceed
theMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//create marker array
placeMarkers = new Marker[MAX_PLACES];
//update location
updatePlaces();
}
}
}
//location listener functions
@Override
public void onLocationChanged(Location location) {
Log.v("MyMapActivity", "location changed");
updatePlaces();
}
@Override
public void onProviderDisabled(String provider){
Log.v("MyMapActivity", "provider disabled");
}
@Override
public void onProviderEnabled(String provider) {
Log.v("MyMapActivity", "provider enabled");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.v("MyMapActivity", "status changed");
}
/*
* update the place markers
*/
private void updatePlaces(){
//get location manager
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
//get last location
Location lastLoc = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
double lat = lastLoc.getLatitude();
double lng = lastLoc.getLongitude();
//create LatLng
LatLng lastLatLng = new LatLng(lat, lng);
//remove any existing marker
if(userMarker!=null) userMarker.remove();
//create and set marker properties
userMarker = theMap.addMarker(new MarkerOptions()
.position(lastLatLng)
.title("You are here")
.icon(BitmapDescriptorFactory.fromResource(userIcon))
.snippet("Your last recorded location"));
//move to location
theMap.animateCamera(CameraUpdateFactory.newLatLng(lastLatLng), 3000, null);
//build places query string
String placesSearchStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/" +
"json?location="+lat+","+lng+
"&radius=1000&sensor=true" +
"&types=hospital|health"+
"API_KEY";//ADD KEY
//execute query
new GetPlaces().execute(placesSearchStr);
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 100, this);
}
private class GetPlaces extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... placesURL) {
//fetch places
//build result as string
StringBuilder placesBuilder = new StringBuilder();
//process search parameter string(s)
for (String placeSearchURL : placesURL) {
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();
}
//process data retrieved from doInBackground
protected void onPostExecute(String result) {
//parse place data returned from Google Places
//remove existing markers
if(placeMarkers!=null){
for(int pm=0; pm<placeMarkers.length; pm++){
if(placeMarkers[pm]!=null)
placeMarkers[pm].remove();
}
}
try {
//parse JSON
//create JSONObject, pass stinrg returned from doInBackground
JSONObject resultObject = new JSONObject(result);
//get "results" array
JSONArray placesArray = resultObject.getJSONArray("results");
//marker options for each place returned
places = new MarkerOptions[placesArray.length()];
//loop through places
for (int p=0; p<placesArray.length(); p++) {
//parse each place
//if any values are missing we won't show the marker
boolean missingValue=false;
LatLng placeLL=null;
String placeName="";
String vicinity="";
int currIcon = otherIcon;
try{
//attempt to retrieve place data values
missingValue=false;
//get place at this index
JSONObject placeObject = placesArray.getJSONObject(p);
//get location section
JSONObject loc = placeObject.getJSONObject("geometry")
.getJSONObject("location");
//read lat lng
placeLL = new LatLng(Double.valueOf(loc.getString("lat")),
Double.valueOf(loc.getString("lng")));
//get types
JSONArray types = placeObject.getJSONArray("types");
//loop through types
for(int t=0; t<types.length(); t++){
//what type is it
String thisType=types.get(t).toString();
//check for particular types - set icons
if(thisType.contains("hospital")){
currIcon = foodIcon;
break;
}
else if(thisType.contains("health")){
currIcon = drinkIcon;
break;
}
else if(thisType.contains("doctor")){
currIcon = shopIcon;
break;
}
}
//vicinity
vicinity = placeObject.getString("vicinity");
//name
placeName = placeObject.getString("name");
}
catch(JSONException jse){
Log.v("PLACES", "missing value");
missingValue=true;
jse.printStackTrace();
}
//if values missing we don't display
if(missingValue) places[p]=null;
else
places[p]=new MarkerOptions()
.position(placeLL)
.title(placeName)
.icon(BitmapDescriptorFactory.fromResource(currIcon))
.snippet(vicinity);
}
}
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]=theMap.addMarker(places[p]);
}
}
}
}
@Override
protected void onResume() {
super.onResume();
if(theMap!=null){
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 100, this);
}
}
@Override
protected void onPause() {
super.onPause();
if(theMap!=null){
locMan.removeUpdates(this);
}
}
}
布局:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/the_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment"
map:cameraTilt="45"
map:cameraZoom="14"
/>
Manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.location.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<permission
android:name="com.location.test.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.location.test.permission.MAPS_RECEIVE"/>
<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" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MyMapActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<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="API_KEY" />
</application>
</manifest>
对于标记,它们只是drawble文件夹中的4个标记。 谁知道如何解决这个问题?
答案 0 :(得分:3)
我认为可以使用Google Places API网络服务而不是Android SDK,因为Android SDK中的PlaceFilter只能按openNow
和placeID
进行过滤。 Web Service的优势在于它还可以按radius
,minPrice
和maxPrice
等过滤结果。
您的代码中存在多个问题。
首先,您的请求网址错过了&key=
,因此它应该是
String placesSearchStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/" +
"json?location="+lat+","+lng+
"&radius=1000&sensor=true" +
"&types=hospital|health"+
"&key=YOUR_API_KEY";
其次,你应该使用HTTPURLConnection
课程而不是旧的HttpGet
课程,所以你应该修改你的doInBackground
方法,如下所示:
@Override
protected String doInBackground(String... placesURL) {
//fetch places
StringBuilder placesBuilder = new StringBuilder();
for (String placeSearchURL : placesURL) {
try {
URL requestUrl = new URL(placeSearchURL);
HttpURLConnection connection = (HttpURLConnection)requestUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = null;
InputStream inputStream = connection.getInputStream();
if (inputStream == null) {
return "";
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
placesBuilder.append(line + "\n");
}
if (placesBuilder.length() == 0) {
return "";
}
Log.d("test", placesBuilder.toString());
}
else {
Log.i("test", "Unsuccessful HTTP Response Code: " + responseCode);
}
} catch (MalformedURLException e) {
Log.e("test", "Error processing Places API URL", e);
} catch (IOException e) {
Log.e("test", "Error connecting to Places API", e);
}
}
return placesBuilder.toString();
}
第三,您将locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 100, this);
放在updatePlaces()
方法中,您应将其删除,因为它会循环使用updatePlaces()
方法,对您的应用和API配额限制不利。同时删除updatePlaces()
方法中的onCreate()
方法,并改为使用这两行:
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 100, this);
因此,您更新的onCreate()
和updatePlaces()
应该是这样的:
的onCreate():
@SuppressLint("NewApi") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_map);
//get drawable IDs
userIcon = R.drawable.yellow_point;
foodIcon = R.drawable.red_point;
drinkIcon = R.drawable.blue_point;
shopIcon = R.drawable.green_point;
otherIcon = R.drawable.purple_point;
//find out if we already have it
if(theMap==null){
//get the map
theMap = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.the_map)).getMap();
//check in case map/ Google Play services not available
if(theMap!=null){
//ok - proceed
theMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//create marker array
placeMarkers = new Marker[MAX_PLACES];
//update location
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 100, this);
}
}
}
updatePlaces():
private void updatePlaces(){
//get location manager
//get last location
Location lastLoc = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
double lat = lastLoc.getLatitude();
double lng = lastLoc.getLongitude();
//create LatLng
LatLng lastLatLng = new LatLng(lat, lng);
//remove any existing marker
if(userMarker!=null) userMarker.remove();
//create and set marker properties
userMarker = theMap.addMarker(new MarkerOptions()
.position(lastLatLng)
.title("You are here")
.snippet("Your last recorded location"));
//move to location
theMap.animateCamera(CameraUpdateFactory.newLatLng(lastLatLng), 3000, null);
//build places query string
String placesSearchStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/" +
"json?location="+lat+","+lng+
"&radius=1000&sensor=true" +
"&types=hospital|health"+
"&key=YOUR_API_KEY";//ADD KEY
//execute query
new GetPlaces().execute(placesSearchStr);
}
您还可以看到updated code snippet。 (我在这里扩展FragmentActivity
,因为我使用SupportMapFragment
代替
您还可以在此处查看带标记的图像。 (我没有你的标记图像,所以我只使用这里的默认标记图像)