服务不可用,同时呼吁geoCoder.getFromLocation()(Service not a

2019-07-20 15:25发布

有时我知道谷歌后端服务可能无法使用。

因此,一个解决办法可能是循环,直到我得到的数据。

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

和ofcourse我添加了所有需要的权限:

<uses-permission android:name="android.permission.INTERNET" />

我想这对三星Galaxy Note的GT-N7000(4.0.4版)

我失去了任何设置? 相关设备或应用程序? 或者,这通常发生? 如果是没有更好的解决方案来解决这个?

谢谢

Answer 1:

为什么实际的原因, Geocoder不工作是因为NetworkLocator在行动被杀害。 可能是由于较少的内存或者你使用任务管理器杀死所有的服务?

我不知道,但是这是一个猜测。 我以前见过这个。 去年我写了一个重新连接机制加载NetworkLocator.apk并绑定到GeocoderService 。 我是这么认为的问题依然存在,这种变化并没有合并到豆形软糖。

它可以通过重新启动才能得以解决。 (该NetworkLocationService在引导加载)

编辑:您不会看到JBP或KK这个问题,该服务被移动到Play商店中的应用程序。



Answer 2:

解决方法使用谷歌地图直接访问:

    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;
}


Answer 3:

重新启动设备,它会解决这个问题。



Answer 4:

API将抛出一个“服务不可用异常”,如果这种服务是在设备上不可用。 使用方法isPresent()来检查服务的存在。

参见: http://developer.android.com/reference/android/location/Geocoder.html



Answer 5:

针对此问题最好的解决方法是,如果原来的地理编码器不能使用相同的像谷歌地理编码类

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;
    }
}


Answer 6:

用这一招。

只需编辑project.properties

# Project target
target=Google Inc.:Google APIs:16

其原因是,该地址解析器类是存在于核心Android框架,而是取决于代码贡献的谷歌API的正常工作。 即使你的AVD包括谷歌的API,您的项目仍然需要针对特定​​的构建目标建造的。



Answer 7:

服务不可用 - 地理编码器的Android时,我在一些熟ROM的得到这个错误,我写了这个库,我希望可能是有用的。 https://github.com/dnocode/gapis



Answer 8:

我使用的是向上(直接访问谷歌地图)“合并”与地理编码代码,如下所示的代码(要特别注意“尝试捕获”):

...
//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;
}

因为当地理编码器不工作,我使用谷歌地图直接访问这个工作非常适合我。

干杯!



Answer 9:

我有应用了上述的同一地理编码错误,但非。 它不会跑我的Android设备之一。 这时我想起,我已经accedently杀害了正在运行的服务。 解决的办法是取下电池几秒钟,然后重新安装。 和它的工作而无需修改代码:))



Answer 10:

有些设备没有询问服务的地理编码器,所以你需要做的是建立自己的地理编码器。

Basicaly你需要创建一个异步任务,要求谷歌的地址和处理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();
                        }
                }
        });        
}


Answer 11:

下面的行

Geocoder gCoder = new Geocoder(context, Locale.getDefault());

使用Context您的活动,并且不使用getApplicationContext()



Answer 12:

我也有这种错误的麻烦。 它发生了,当我最近更新我的设备棉花糖。

如果我重新启动,它工作一次,但随后会失败,并在其后的所有不起作用。

我创建像其他人一样的的AsyncTask,只返回从JSON响应的第一个结果的地址。

要使用下面的代码,把它与你的API密钥构建的,并使用一个位置对象作为输入来执行的AsyncTask。 你可以用下面的导入位置。 import android.location.Location; 你将不得不用的LocationManager来获取当前位置,通过请求更新它。

    new ReverseGeoCodeTask(GOOGLE_API_KEY).execute(location);

确保你换成你自己的API密钥,并且确保你启用它在谷歌云控制台。 这就是你管理所有用于特定项目的谷歌的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");
        }

    }
}


Answer 13:

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;
});


Answer 14:

我有同样的错误,下面添加权限来解决这个问题。

<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> 
<uses-permission android:name="android.permission.INTERNET" />


文章来源: Service not available while calling geoCoder.getFromLocation()