我知道有时google后端服务可能无法使用。
因此,解决方案可能是循环,直到我获得数据。
private class getLocationDetails extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
Log.d("looping", "" + count + "");
count++;
double lat = Double.parseDouble(params[0]);
double lng = Double.parseDouble(params[1]);
List<Address> addresses = null;
try {
Geocoder gCoder = new Geocoder(ImageAndLocationActivity.this,
Locale.getDefault());
addresses = gCoder.getFromLocation(lat, lng, 1);
Address addr = addresses.get(0);
user_country = addr.getCountryName();
user_city = addr.getLocality();
user_district = addr.getSubAdminArea();
if (user_city == null) {
user_city = user_district;
}
} catch (Exception e) {
Log.e("Exception in getLocationDetails - ", e.getMessage());
return null;
}
return "";
}
@Override
protected void onPostExecute(String result) {
if (result != null) {
Log.d("user_city = ", "" + user_city);
} else {
new getLocationDetails().execute(CurrentLat + "", CurrentLng
+ "");
}
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
但我根本无法获得该位置:
logcat的:
02-27 16:29:49.568: D/looping(10966): 110355
02-27 16:29:49.568: E/Exception in getLocationDetails -(10966): Service not Available
02-27 16:29:49.573: D/looping(10966): 110356
02-27 16:29:49.573: E/Exception in getLocationDetails -(10966): Service not Available
02-27 16:29:49.573: D/looping(10966): 110357
02-27 16:29:49.573: E/Exception in getLocationDetails -(10966): Service not Available
并且当然我添加了所有必需的权限:
<uses-permission android:name="android.permission.INTERNET" />
我在三星Galaxy Note GT-N7000(4.0.4版本)上试用
我错过了任何设置吗?与设备或应用程序有关?或者这通常会发生?如果是这样,任何更好的解决方案来解决这个问题?
谢谢
答案 0 :(得分:60)
Geocoder
无效的实际原因是因为NetworkLocator
在行动中被杀死了。可能是由于内存较少或者您使用任务管理器来杀死所有服务?
我不确定,但这是猜测。我以前见过这个。去年我编写了一个重新连接机制来加载NetworkLocator.apk并绑定到GeocoderService
。我认为这个变化还没有合并到JellyBean中,所以这个问题仍然存在。
只能通过重启来解决。 (NetworkLocationService
在启动时加载
编辑:您不会在JBP或KK中看到此问题,此服务将移至Playstore应用程序中。
答案 1 :(得分:22)
使用直接访问谷歌地图的解决方法:
public static LatLng getLocationFromString(String address)
throws JSONException {
HttpGet httpGet = new HttpGet(
"http://maps.google.com/maps/api/geocode/json?address="
+ URLEncoder.encode(address, "UTF-8") + "&ka&sensor=false");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
StringBuilder stringBuilder = new StringBuilder();
try {
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
double lng = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
.getJSONObject("geometry").getJSONObject("location")
.getDouble("lng");
double lat = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
.getJSONObject("geometry").getJSONObject("location")
.getDouble("lat");
return new LatLng(lat, lng);
}
public static List<Address> getStringFromLocation(double lat, double lng)
throws ClientProtocolException, IOException, JSONException {
String address = String
.format(Locale.ENGLISH, "http://maps.googleapis.com/maps/api/geocode/json?latlng=%1$f,%2$f&sensor=true&language="
+ Locale.getDefault().getCountry(), lat, lng);
HttpGet httpGet = new HttpGet(address);
HttpClient client = new DefaultHttpClient();
HttpResponse response;
StringBuilder stringBuilder = new StringBuilder();
List<Address> retList = null;
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
retList = new ArrayList<Address>();
if ("OK".equalsIgnoreCase(jsonObject.getString("status"))) {
JSONArray results = jsonObject.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
String indiStr = result.getString("formatted_address");
Address addr = new Address(Locale.getDefault());
addr.setAddressLine(0, indiStr);
retList.add(addr);
}
}
return retList;
}
答案 2 :(得分:8)
重启设备,它将解决问题。
答案 3 :(得分:3)
此问题的最佳解决方法是使用相同的Google Geocoder类,如果原始地理编码器失败
List<Address> addresses = null;
Geocoder geocoder = new Geocoder(this);
addresses = geocoder.getFromLocation(...);
if (addresses == null || addresses.isEmpty())
addresses = MyGeocoder.getFromLocation(...);
import android.location.Address;
import android.util.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.AllClientPNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class MyGeocoder {
public static List<Address> getFromLocation(double lat, double lng, int maxResult) {
String address = String.format(Locale.ENGLISH, "http://maps.googleapis.com/maps/api/geocode/json?latlng=%1$f,%2$f&sensor=false&language=" + Locale.getDefault().getCountry(), lat, lng);
HttpGet httpGet = new HttpGet(address);
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(AllClientPNames.USER_AGENT, "Mozilla/5.0 (Java) Gecko/20081007 java-geocoder");
client.getParams().setIntParameter(AllClientPNames.CONNECTION_TIMEOUT, 5 * 1000);
client.getParams().setIntParameter(AllClientPNames.SO_TIMEOUT, 25 * 1000);
HttpResponse response;
List<Address> retList = null;
try {
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
String json = EntityUtils.toString(entity, "UTF-8");
JSONObject jsonObject = new JSONObject(json);
retList = new ArrayList<Address>();
if ("OK".equalsIgnoreCase(jsonObject.getString("status"))) {
JSONArray results = jsonObject.getJSONArray("results");
if (results.length() > 0) {
for (int i = 0; i < results.length() && i < maxResult; i++) {
JSONObject result = results.getJSONObject(i);
//Log.e(MyGeocoder.class.getName(), result.toString());
Address addr = new Address(Locale.getDefault());
// addr.setAddressLine(0, result.getString("formatted_address"));
JSONArray components = result.getJSONArray("address_components");
String streetNumber = "";
String route = "";
for (int a = 0; a < components.length(); a++) {
JSONObject component = components.getJSONObject(a);
JSONArray types = component.getJSONArray("types");
for (int j = 0; j < types.length(); j++) {
String type = types.getString(j);
if (type.equals("locality")) {
addr.setLocality(component.getString("long_name"));
} else if (type.equals("street_number")) {
streetNumber = component.getString("long_name");
} else if (type.equals("route")) {
route = component.getString("long_name");
}
}
}
addr.setAddressLine(0, route + " " + streetNumber);
addr.setLatitude(result.getJSONObject("geometry").getJSONObject("location").getDouble("lat"));
addr.setLongitude(result.getJSONObject("geometry").getJSONObject("location").getDouble("lng"));
retList.add(addr);
}
}
}
} catch (ClientProtocolException e) {
Log.e(MyGeocoder.class.getName(), "Error calling Google geocode webservice.", e);
} catch (IOException e) {
Log.e(MyGeocoder.class.getName(), "Error calling Google geocode webservice.", e);
} catch (JSONException e) {
Log.e(MyGeocoder.class.getName(), "Error parsing Google geocode webservice response.", e);
}
return retList;
}
}
答案 4 :(得分:3)
isPresent()
检查服务是否存在。
另请参阅:http://developer.android.com/reference/android/location/Geocoder.html
答案 5 :(得分:1)
使用这个技巧。
只需编辑project.properties
即可# Project target
target=Google Inc.:Google APIs:16
原因是Geocoder类存在于核心Android框架中,但依赖于Google API提供的代码才能正常运行。即使您的AVD包含Google API,您的项目仍需要针对特定的构建目标进行构建。
答案 6 :(得分:1)
服务不可用 - Geocoder Android当我在一些煮熟的roms中出现此错误时我写了这个库我希望可能有用。 https://github.com/dnocode/gapis
答案 7 :(得分:1)
我正在使用已启动的代码(直接访问Google地图)&#34;合并&#34;使用Geocoder代码,如下所示(特别注意&#34;尝试捕捉&#34;):
...
//address is String
if (address != null) {
new GeocoderTask().execute(address);
}
...
// An AsyncTask class for accessing the GeoCoding Web Service
private class GeocoderTask extends AsyncTask<String, Void, List<Address>> {
private LatLng latLng;
private MarkerOptions markerOptions;
@Override
protected List<Address> doInBackground(String... locationName) {
// Creating an instance of Geocoder class
Geocoder geocoder = new Geocoder(getBaseContext());
List<Address> addresses = null;
try {
// Getting a maximum of 3 Address that matches the input text
addresses = geocoder.getFromLocationName(locationName[0], 3);
} catch (IOException e) {
e.printStackTrace();
try {
addresses = getLocationFromString(locationName[0]);
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (JSONException e1) {
e1.printStackTrace();
}
}
return addresses;
}
@Override
protected void onPostExecute(List<Address> addresses) {
if (addresses == null || addresses.size() == 0) {
Toast.makeText(getBaseContext(), "No Location found",
Toast.LENGTH_SHORT).show();
return;
}
// Clears all the existing markers on the map
googleMap.clear();
// Adding Markers on Google Map for each matching address
for (int i = 0; i < addresses.size(); i++) {
Address address = (Address) addresses.get(i);
// Creating an instance of GeoPoint, to display in Google Map
latLng = new LatLng(address.getLatitude(),
address.getLongitude());
String addressText = String.format(
"%s, %s",
address.getMaxAddressLineIndex() > 0 ? address
.getAddressLine(0) : "", address
.getCountryName());
markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title(addressText);
googleMap.addMarker(markerOptions);
// Locate the first location
if (i == 0) {
CameraUpdate center = CameraUpdateFactory.newLatLng(latLng);
CameraUpdate zoom = CameraUpdateFactory.zoomTo(13);
googleMap.moveCamera(center);
googleMap.animateCamera(zoom);
}
}
}
}
public static LatLng getLocationFromString(String address)
throws JSONException {
HttpGet httpGet = new HttpGet(
"http://maps.google.com/maps/api/geocode/json?address="
+ URLEncoder.encode(address, "UTF-8") + "&ka&sensor=false");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
StringBuilder stringBuilder = new StringBuilder();
try {
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
double lng = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
.getJSONObject("geometry").getJSONObject("location")
.getDouble("lng");
double lat = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
.getJSONObject("geometry").getJSONObject("location")
.getDouble("lat");
return new LatLng(lat, lng);
}
public static List<Address> getStringFromLocation(double lat, double lng)
throws ClientProtocolException, IOException, JSONException {
String address = String
.format(Locale.ENGLISH, "http://maps.googleapis.com/maps/api/geocode/json?latlng=%1$f,%2$f&sensor=true&language="
+ Locale.getDefault().getCountry(), lat, lng);
HttpGet httpGet = new HttpGet(address);
HttpClient client = new DefaultHttpClient();
HttpResponse response;
StringBuilder stringBuilder = new StringBuilder();
List<Address> retList = null;
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
retList = new ArrayList<Address>();
if ("OK".equalsIgnoreCase(jsonObject.getString("status"))) {
JSONArray results = jsonObject.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
String indiStr = result.getString("formatted_address");
Address addr = new Address(Locale.getDefault());
addr.setAddressLine(0, indiStr);
retList.add(addr);
}
}
return retList;
}
这对我来说非常有用,因为当Geocoder无法正常工作时,我会直接访问Google地图。
干杯!
答案 8 :(得分:0)
我遇到了相同的地理编码器错误但未应用上述错误。它不会运行我的某个Android设备。然后我记得我已经加入了一些正在运行的服务。 解决方案是将电池取出几秒钟并重新安装。 它可以在不改变代码的情况下工作:))
答案 9 :(得分:0)
有些设备没有Geocoder支持,所以您需要创建自己的地理编码器。
基本上你需要创建一个异步任务来请求google获取地址并处理json响应。
使用aquery,我做这样的事情:
public void asyncJson(String address){
address = address.replace(" ", "+");
String url = "http://maps.googleapis.com/maps/api/geocode/json?address="+ address +"&sensor=true";
aq.ajax(url, JSONObject.class, new AjaxCallback<JSONObject>() {
@Override
public void callback(String url, JSONObject json, AjaxStatus status) {
if(json != null){
//here you work with the response json
JSONArray results = json.getJSONArray("results");
Toast.makeText(context, results.getJSONObject(1).getString("formatted_address"));
}else{
//ajax error, show error code
Toast.makeText(aq.getContext(), "Error:" + status.getCode(), Toast.LENGTH_LONG).show();
}
}
});
}
答案 10 :(得分:0)
对于以下行
Geocoder gCoder = new Geocoder(context, Locale.getDefault());
使用您的活动
Context
,不要使用getApplicationContext()
答案 11 :(得分:0)
我也遇到过这个错误。最近我将设备更新到Marshmallow时发生了这种情况。
如果我重新启动,它会工作一次,但之后会失败,之后根本不会工作。
我像其他人一样创建了AsyncTask,只返回json响应的第一个结果中的地址。
要使用下面的代码,使用api键调用它构造,并使用Location对象作为输入来执行AsyncTask。您可以使用以下内容导入位置。 import android.location.Location;
您必须通过请求更新它来获取LocationManager的当前位置。
new ReverseGeoCodeTask(GOOGLE_API_KEY).execute(location);
确保将api密钥替换为您自己的密钥,并确保在Google云端控制台中启用它。这是您管理特定项目的所有Google API的地方。
将此类复制为您需要反向地理编码地址的活动中的内部类。
/**
* Reverse geocode request - takes a Location in as parameters,
* and does a network request in the background to get the first address in
* json response. The address is returned in the onPostExecute so you
* can update the UI with it
*/
private class ReverseGeoCodeTask extends AsyncTask<Location, Void, String>{
private final static String GEOCODE_API_ENDPOINT_BASE = "https://maps.googleapis.com/maps/api/geocode/json?latlng=";
private final static String JSON_PROPERTY_RESULTS = "results";
private final static String JSON_PROPERTY_FORMATTED_ADDRESS = "formatted_address";
private final static String JSON_PROPERTY_REQUEST_STATUS = "status";
private final static String STATUS_OK = "OK";
private String apiKey;
public ReverseGeoCodeTask(final String apiKey){
this.apiKey = apiKey;
}
@Override
protected String doInBackground(Location... params) {
if(apiKey == null){
throw new IllegalStateException("Pass in a geocode api key in the ReverseGeoCoder constructor");
}
Location location = params[0];
String googleGeocodeEndpoint = GEOCODE_API_ENDPOINT_BASE + location.getLatitude() + "," + location.getLongitude() + "&key=" + apiKey;
Log.d(TAG, "Requesting gecoding endpoint : " + googleGeocodeEndpoint);
try {
URL url = new URL(googleGeocodeEndpoint);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
JSONObject json = new JSONObject(result.toString());
String requestStatus = json.getString(JSON_PROPERTY_REQUEST_STATUS);
if(requestStatus.equals(STATUS_OK)){
JSONArray results = json.getJSONArray(JSON_PROPERTY_RESULTS);
if(results.length() > 0){
JSONObject result1 = results.getJSONObject(0);
String address = result1.getString(JSON_PROPERTY_FORMATTED_ADDRESS);
Log.d(TAG, "First result's address : " + address );
return address;
}
else{
Log.d(TAG, "There were no results.");
}
}
else{
Log.w(TAG, "Geocode request status not " + STATUS_OK + ", it was " + requestStatus );
Log.w(TAG, "Did you enable the geocode in the google cloud api console? Is it the right api key?");
}
}catch ( IOException | JSONException e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String address) {
super.onPostExecute(address);
if(address != null){
// update the UI here with the address, if its not null
originEditText.setText(address);
}
else{
Log.d(TAG, "Did not find an address, UI not being updated");
}
}
}
答案 12 :(得分:0)
new Volly_Services(map, "https://maps.googleapis.com/maps/api/place/textsearch/json?query=" + mBinding.loc.getText().toString().trim() + "&key=Ap", getActivity()).vollyPostService().continueWithTask(task - > {
mBinding.progressBaar.setVisibility(View.GONE);
if (task.getResult() != null) {
Log.e("<<<", "" + task.getResult());
JSONObject jsonObject = new JSONObject("" + task.getResult());
if ("OK".equalsIgnoreCase(jsonObject.getString("status"))) {
JSONArray results = jsonObject.getJSONArray("results");
if (results.length() > 0) {
mBinding.loc.setVisibility(View.GONE);
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
String indiStr = result.getString("formatted_address");
Address addr = new Address(Locale.getDefault());
addr.setAddressLine(0, indiStr);
addr.setLocality(result.getString("name"));
JSONObject geometry = result.getJSONObject("geometry").getJSONObject("location");
addr.setLatitude(geometry.getDouble("lat"));
addr.setLongitude(geometry.getDouble("lng"));
addresses.add(addr);
}
adapter = new SerchLocationAdapter(getActivity(), addresses);
mBinding.serchreg.setAdapter(adapter);
} else {
Toast.makeText(getActivity(), "No result found", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getActivity(), "No result found", Toast.LENGTH_LONG).show();
}
} else {
Log.e("<<<<<<", "" + task.getError().getMessage());
Toast.makeText(getActivity(), task.getError().getMessage(), Toast.LENGTH_LONG).show();
}
return null;
});
答案 13 :(得分:0)
在 Android 6 上存在相同的问题。 问题出在应用权限中。 即使地图正常运行,您也必须在应用权限中允许“获取位置”权限。
最好的情况是始终检查允许的权限 当您期望获得结果的时候。
我使用这种方法从地方获取完整地址:
public Address getFullAddress(Place place){
Address address;
Locale aLocale = new Locale.Builder().setLanguage("en").build();
Geocoder geocoder = new Geocoder(this, aLocale);
try {
List<Address> addresses = geocoder.getFromLocation(place.getLatLng().latitude,place.getLatLng().longitude, 1);
address = addresses.get(0);
return address;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
答案 14 :(得分:0)
您可以转到手机中的地图应用并清除缓存,然后发现该地址可以正常工作。
答案 15 :(得分:0)
我使用Volley,它工作正常
private void callAppFromUrl(final String strAddress, final String app, final boolean isGeo) {
try {
Volley.newRequestQueue(this).add(new StringRequest(0, String.format("https://www.google.com/maps?q=%s", URLEncoder.encode(strAddress, "UTF-8")), new Response.Listener<String>() {
public void onResponse(String response) {
try {
try {
Matcher m = Pattern.compile("null,null,(\\d+.\\d+),(\\d+.\\d+)").matcher(response);
String strLatLong = "";
if (m.find()) {
strLatLong = m.group(0).replace("null,null,", "");
}
String[] latlong = strLatLong.split(",");
LatLng latLng = new LatLng(Double.parseDouble(latlong[0]), Double.parseDouble(latlong[1]));
Log.d("OsK",String.valueOf(latLng));
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Không tìm thấy địa chỉ", Toast.LENGTH_LONG).show();
}
} catch (Exception e2) {
Toast.makeText(getApplicationContext(), "Không tìm thấy địa chỉ", Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
/* class com.cantho.roadtech.MainActivity.AnonymousClass5 */
@Override // com.android.volley.Response.ErrorListener
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("User-Agent", "Mozilla");
params.put("Accept-Language", "en-US,en;q=0.8");
params.put("Referer", "google.com");
return params;
}
});
} catch (Exception ex) {
}
}
答案 16 :(得分:-1)
我遇到了同样的错误,添加以下权限来解决它。
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />