33

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" />

Samsung Galaxy Note GT-N7000(4.0.4バージョン)でこれを試しています

設定がありませんか?デバイスまたはアプリケーションに関連していますか? それとも、これは通常起こりますか?もしそうなら、これを解決するためのより良い解決策はありますか??

ありがとうございました

4

17 に答える 17

68

Geocoder動作しなかった実際の理由は、NetworkLocator戦死したためです。おそらくメモリが少ないためか、タスクマネージャを使用してすべてのサービスを強制終了したためですか?

よくわかりませんが、これは推測です。私は前にこれを見たことがあります。昨年、NetworkLocator.apkをロードしてにバインドするための再接続メカニズムを作成しましたGeocoderService。この変更はJellyBeanにマージされていないため、この問題は解決しないと思います。

再起動することでのみ解決できます。(NetworkLocationServiceは起動時にロードされます)

編集:JBPまたはKKではこの問題は発生しません。このサービスは、プレイストアアプリに移動されます。

于 2013-02-27T12:33:45.020 に答える
13

デバイスを再起動すると、問題が解決します。

于 2014-11-26T09:22:05.220 に答える
3

この問題の最善の解決策は、元の Geocoder が失敗した場合に同じような 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;
    }
}
于 2014-10-31T08:24:06.850 に答える
3

そのようなサービスがデバイスで利用できない場合、API は「Service not Available 例外」をスローします。メソッドisPresent()を使用して、サービスの存在を確認します。

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

于 2013-02-27T11:13:26.497 に答える
1

サービスが利用できません - Geocoder Android いくつかの調理済み ROM でこのエラーが発生した場合、このライブラリを作成しました。https://github.com/dnocode/gapis

于 2015-03-15T15:45:10.597 に答える
1

このトリックを使用します。

project.properties を編集するだけです

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

その理由は、Geocoder クラスが Android のコア フレームワークに存在するが、適切に機能するために Google API によって提供されるコードに依存しているためです。AVD に Google API が含まれている場合でも、プロジェクトはその特定のビルド ターゲットに対してビルドする必要があります。

于 2013-03-11T14:08:12.183 に答える
1

以下に示すように、Geocoderコードと「マージ」された(Googleマップへの直接アクセス)コードを使用しています(「try catch」に特に注意してください):

...
//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 マップに直接アクセスできるので、これは私にとって非常に効果的でした。

乾杯!

于 2015-03-27T13:21:08.873 に答える
0

同じジオコーダー エラーが発生しましたが、上記のいずれも適用されませんでした。私の Android デバイスの 1 つを実行できませんでした。そのとき、実行中のサービスをうっかり殺してしまったことを思い出しました。解決策は、バッテリーを数秒間取り外してから再インストールすることでした。そして、コードを変更せずに機能しました:))

于 2013-07-18T12:34:31.600 に答える
0

一部のデバイスはジオコーダーをサポートしていないため、独自のジオコーダーを作成する必要があります。

基本的に、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();
                        }
                }
        });        
}
于 2013-11-27T15:34:46.527 に答える
-1

同じエラーが発生しました。以下の権限を追加して解決してください。

<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> 
<uses-permission android:name="android.permission.INTERNET" />
于 2014-08-19T08:43:32.653 に答える
-1

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ỉ&quot;, Toast.LENGTH_LONG).show();
                    }
                } catch (Exception e2) {
                    Toast.makeText(getApplicationContext(), "Không tìm thấy địa chỉ&quot;, 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) {
    }
}
于 2020-10-13T09:31:02.540 に答える