2014-11-29 3 views
1

나는 안드로이드에서 도시 이름과 국가 이름을 주어진 위치로 가져 오려고하는데, 그 일을하는 데 어려움이 있습니다. 모든 경우에 gps, 인터넷 연결없이 또는 모든 기능이 켜져 있어야합니다. 내가 GeoCoder 시도했다하지만 난이 오류 :도시명 및 국가 이름을 위치로 가져 오기

Log.v("--", "got location ="+location.getLatitude()+" | "+location.getLongitude()); 
try { 
    Geocoder gcd = new Geocoder(Main.this, Locale.getDefault()); 
    List<Address> addresses; 

    //im getting an error in this line and checked location values are OK 
    addresses = gcd.getFromLocation(location.getLatitude(), location.getLongitude(), 1); 
    Log.v("--", addresses.size()+" got location address size"); 
    if (addresses.size() > 0) { 
     city = addresses.get(0).getLocality(); 
     country = addresses.get(0).getCountryName(); 
     prefs.edit().putString(Constants.COUNTRY, country).commit(); 
     prefs.edit().putString(Constants.CITY, city).commit(); 
    } else { 
     city = a.getString(R.string.app_name); 
     country = "France"; 
    } 

    Log.v("--", "got location"+city+" | "+country); 
}catch(Exception e){ 
    Log.v("--", "got location failed"); 
    e.printStackTrace(); 
} 

그리고 MyLocation :

지오 코더가 내 MainActivity 여기

에 위치하고 gotLocation에 내부에 위치한

11-29 11:54:01.718: W/System.err(32200): at com.myapp.Main$4.gotLocation(Main.java:282) 
11-29 11:54:01.718: W/System.err(32200): at com.myapp.services.MyLocation$GetLastLocation.run(MyLocation.java:124) 

내 코드입니다 수업 코드 :

public class MyLocation { 
    Timer timer1; 
    LocationManager lm; 
    LocationResult locationResult; 
    boolean gps_enabled = false; 
    boolean network_enabled = false; 
    private Context context; 

    public boolean getLocation(Context context, LocationResult result) { 
     // I use LocationResult callback class to pass location value from 
     // MyLocation to user code. 
     locationResult = result; 
     this.context = context; 
     if (lm == null) 
      lm = (LocationManager) context 
        .getSystemService(Context.LOCATION_SERVICE); 

     // exceptions will be thrown if provider is not permitted. 
     try { 
      gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     } catch (Exception ex) { 
     } 
     try { 
      network_enabled = lm 
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     } catch (Exception ex) { 
     } 

     // don't start listeners if no provider is enabled 
     if (!gps_enabled && !network_enabled) 
      return false; 

     if (gps_enabled) 
      lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, 
        locationListenerGps); 
     if (network_enabled) 
      lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, 
        locationListenerNetwork); 
     timer1 = new Timer(); 
     timer1.schedule(new GetLastLocation(), 20000); 
     return true; 
    } 

    LocationListener locationListenerGps = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      timer1.cancel(); 
      locationResult.gotLocation(location); 
      lm.removeUpdates(this); 
      lm.removeUpdates(locationListenerNetwork); 
     } 

     public void onProviderDisabled(String provider) { 
     } 

     public void onProviderEnabled(String provider) { 
     } 

     public void onStatusChanged(String provider, int status, Bundle extras) { 
     } 
    }; 

    LocationListener locationListenerNetwork = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      timer1.cancel(); 
      locationResult.gotLocation(location); 
      lm.removeUpdates(this); 
      lm.removeUpdates(locationListenerGps); 
     } 

     public void onProviderDisabled(String provider) { 
     } 

     public void onProviderEnabled(String provider) { 
     } 

     public void onStatusChanged(String provider, int status, Bundle extras) { 
     } 
    }; 

    class GetLastLocation extends TimerTask { 
     private Handler mHandler = new Handler(Looper.getMainLooper()); 
     Location net_loc,gps_loc; 
     @Override 
     public void run() { 
      mHandler.post(new Runnable() { 
       public void run() { 
      lm.removeUpdates(locationListenerGps); 
      lm.removeUpdates(locationListenerNetwork); 

      net_loc = null; gps_loc = null; 
      if (gps_enabled) 
       gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      if (network_enabled) 
       net_loc = lm 
         .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

      // if there are both values use the latest one 
      if (gps_loc != null && net_loc != null) { 
       if (gps_loc.getTime() > net_loc.getTime()) 
        locationResult.gotLocation(gps_loc); 
       else 
        locationResult.gotLocation(net_loc); 
       return; 
      } 

      if (gps_loc != null) { 
       locationResult.gotLocation(gps_loc); 
       timer1.notifyAll(); 

       return; 
      } 
      if (net_loc != null) { 
       locationResult.gotLocation(net_loc); 
       return; 

      } 

        locationResult.gotLocation(null); 
       } 
      }); 
     } 

    } 

    public void cancelTimer() { 
     timer1.cancel(); 
     lm.removeUpdates(locationListenerGps); 
     lm.removeUpdates(locationListenerNetwork); 
    } 

    public static abstract class LocationResult { 

     public abstract void gotLocation(Location location); 

    } 
} 

누구나 할 수 있습니다. 이 문제를 해결하도록 도와 주시겠습니까?

+0

여기에 위치 코드를 넣을 수 있습니까? –

+0

@MoradiyaAkash가 MyLocation 클래스 코드 –

+0

을 추가했는지 확인하십시오. https://developers.google.com/places/training/basic-place-search –

답변

0

당신은 다음과 같은 코드를 사용할 수 있습니다,

public class GeocoderModel { 

    private String streetNumber; 
    private String rout; 
    private String subLocality; 
    private String political; 
    private String country; 

    // getter and setter 
    } 

사용자 정의 지오 코더 클래스 :

import android.content.Context; 
import android.content.SharedPreferences; 
import android.content.SharedPreferences.Editor; 
import android.location.Address; 
import android.util.Log; 

import org.json.JSONArray; 
import org.json.JSONObject; 

import java.io.IOException; 
import java.net.URLEncoder; 
import java.util.Locale; 

/** 
* A class for handling geocoding and reverse geocoding. Geocoding is the 
* process of transforming a street address or other description of a location 
* into a (latitude, longitude) coordinate. Reverse geocoding is the process of 
* transforming a (latitude, longitude) coordinate into a (partial) address. The 
* amount of detail in a reverse geocoded location description may vary, for 
* example one might contain the full street address of the closest building, 
* while another might contain only a city name and postal code. 
* <p/> 
* This is a replacement of built-in Geocoder which is not always available. 
* This implementation parses just a formatted address and is guaranteed to 
* work. 
*/ 
public final class Geocoder { 

    private static final String PREFERENCES_GEOCODER = Geocoder.class.getName() 
      + ".GEOCODER"; 
    private static final String KEY_ALLOW = Geocoder.class.getName() 
      + ".KEY_ALLOW"; 

    /* 
    * Status codes which we handle 
    */ 

    /** 
    * Indicates that no errors occurred; the address was successfully parsed 
    * and at least one geocode was returned. 
    */ 
    private static final String STATUS_OK = "OK"; 

    /** 
    * Indicates that you are over your quota. 
    */ 
    private static final String STATUS_OVER_QUERY_LIMIT = "OVER_QUERY_LIMIT"; 

    private final Context context; 

    /** 
    * Constructs a Geocoder whose responses will be localized for the default 
    * system Locale. 
    * 
    * @param context the Context of the calling Activity 
    */ 
    public Geocoder(Context context) { 
     this.context = context; 
    } 

    /** 
    * Returns an array of Addresses that are known to describe the area 
    * immediately surrounding the given latitude and longitude. The returned 
    * addresses will be localized for the locale provided to this class's 
    * constructor. 
    * <p/> 
    * <p/> 
    * The returned values may be obtained by means of a network lookup. The 
    * results are a best guess and are not guaranteed to be meaningful or 
    * correct. It may be useful to call this method from a thread separate from 
    * your primary UI thread. 
    * 
    * @param latitude the latitude a point for the search 
    * @param longitude the longitude a point for the search 
    * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) 
    *     are recommended 
    * @return a list of Address objects. Returns null or empty list if no 
    * matches were found or there is no backend service available. 
    * @throws IllegalArgumentException if latitude is less than -90 or greater than 90 
    * @throws IllegalArgumentException if longitude is less than -180 or greater than 180 
    * @throws java.io.IOException  if the network is unavailable or any other I/O problem occurs 
    */ 
    public GeocoderModel getFromLocation(double latitude, double longitude, 
             int maxResults) throws IOException, LimitExceededException { 
     if (latitude < -90.0 || latitude > 90.0) { 
      throw new IllegalArgumentException("latitude == " + latitude); 
     } 
     if (longitude < -180.0 || longitude > 180.0) { 
      throw new IllegalArgumentException("longitude == " + longitude); 
     } 

     if (isLimitExceeded(context)) { 
      throw new LimitExceededException(); 
     } 

     final GeocoderModel results = new GeocoderModel(); 

     final StringBuilder url = new StringBuilder(
       "http://maps.googleapis.com/maps/api/geocode/json?sensor=true&latlng="); 
     url.append(latitude); 
     url.append(','); 
     url.append(longitude); 
     url.append("&language="); 
     url.append(Locale.ENGLISH); 

     final byte[] data = WebserviceClient.download(url.toString()); 
     if (data != null) { 
      this.parseJson(results, maxResults, data); 
     } 
     return results; 
    } 

    /** 
    * Returns an array of Addresses that are known to describe the named 
    * location, which may be a place name such as "Dalvik, 
    * Iceland", an address such as "1600 Amphitheatre Parkway, Mountain View, 
    * CA", an airport code such as "SFO", etc.. The returned addresses will be 
    * localized for the locale provided to this class's constructor. 
    * <p/> 
    * <p/> 
    * The query will block and returned values will be obtained by means of a 
    * network lookup. The results are a best guess and are not guaranteed to be 
    * meaningful or correct. It may be useful to call this method from a thread 
    * separate from your primary UI thread. 
    * 
    * @param locationName a user-supplied description of a location 
    * @param maxResults max number of results to return. Smaller numbers (1 to 5) are 
    *      recommended 
    * @return a list of Address objects. Returns null or empty list if no 
    * matches were found or there is no backend service available. 
    * @throws IllegalArgumentException if locationName is null 
    * @throws java.io.IOException  if the network is unavailable or any other I/O problem occurs 
    */ 
    public GeocoderModel getFromLocationName(String locationName, int 
      maxResults) 
      throws IOException, LimitExceededException { 
     if (locationName == null) { 
      throw new IllegalArgumentException("locationName == null"); 
     } 

     if (isLimitExceeded(context)) { 
      throw new LimitExceededException(); 
     } 

     final GeocoderModel results = new GeocoderModel(); 

     final StringBuilder request = new StringBuilder(
       "http://maps.googleapis.com/maps/api/geocode/json?sensor=false"); 
     request.append("&language=").append(Locale.getDefault().getLanguage()); 
     request.append("&address=").append(
       URLEncoder.encode(locationName, "UTF-8")); 

     byte[] data = WebserviceClient.download(request.toString()); 
     if (data != null) { 
      try { 
       this.parseJson(results, maxResults, data); 
      } catch (LimitExceededException e) { 
       // LimitExceededException could be thrown if too many calls per 
       // second 
       // If after two seconds, it is thrown again - then it means 
       // there are too much calls per 24 hours 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException e1) { 
        return results; 
       } 
       data = WebserviceClient.download(request.toString()); 
       if (data != null) { 
        try { 
         this.parseJson(results, maxResults, data); 
        } catch (LimitExceededException lee) { 
         // available in 24 hours 
         setAllowedDate(context, 
           System.currentTimeMillis() + 86400000L); 
         throw lee; 
        } 
       } 
      } 
     } 
     return results; 
    } 

    private void parseJson(GeocoderModel geoCoderModel, int maxResults, 
          byte[] data) throws LimitExceededException { 
     try { 
      final String json = new String(data, "UTF-8"); 
      final JSONObject o = new JSONObject(json); 
      final String status = o.getString("status"); 
      if (status.equals(STATUS_OK)) { 

       final JSONArray a = o.getJSONArray("results"); 

       // for (int i = 0; i < maxResults && i < a.length(); i++) { 

       final Address current = new Address(Locale.getDefault()); 
       final JSONObject item = a.getJSONObject(0); 
       JSONArray addressComponnet = item 
         .getJSONArray("address_components"); 

       for (int i = 0; i < addressComponnet.length(); i++) { 

        JSONObject temp = addressComponnet.getJSONObject(i); 

        Log.d("temp is", temp.toString()); 

        JSONArray type = temp.getJSONArray("types"); 

        if (type.toString().contains("street_number")) { 
         geoCoderModel.setStreetNumber(temp 
           .getString("long_name")); 
        } else if (type.toString().contains("rout")) { 
         geoCoderModel.setRout(temp.getString("long_name")); 
        } else if (type.toString().contains("country")) { 
         geoCoderModel.setCountry(temp.getString("long_name")); 
        } else if (type.toString().contains("political")) { 
         if ((geoCoderModel.getPolitical().length() - geoCoderModel 
           .getPolitical().replace("|", "").length()) < 3 
           || type.toString().contains(
           "administrative_area_level_1")) 
          geoCoderModel.setPolitical(temp 
            .getString("long_name")); 
        } else if (type.toString().contains("sublocality")) { 
         geoCoderModel.setRout(geoCoderModel.getRout() + " " 
           + temp.getString("long_name")); 
        } 

       } 
      } else if (status.equals(STATUS_OVER_QUERY_LIMIT)) { 

       throw new LimitExceededException(); 

      } 
     } catch (LimitExceededException e) { 
      throw e; 
     } catch (Throwable e) { 
      e.printStackTrace(); 
     } 

    } 

    /** 
    * Returns true if limit is exceeded and next query is not allowed 
    * 
    * @param context Current context 
    * @return true if limit is exceeded and next query is not allowed; false 
    * otherwise 
    */ 
    private static boolean isLimitExceeded(Context context) { 
     return System.currentTimeMillis() <= getAllowedDate(context); 
    } 

    /** 
    * Sets date after which next geocoding query is allowed 
    * 
    * @param context Current context 
    * @param date the date after which next geocoding query is allowed 
    */ 
    private static void setAllowedDate(Context context, long date) { 
     final SharedPreferences p = context.getSharedPreferences(
       PREFERENCES_GEOCODER, Context.MODE_PRIVATE); 
     final Editor e = p.edit(); 
     e.putLong(KEY_ALLOW, date); 
     e.commit(); 
    } 

    /** 
    * Returns date after which the next geocoding query is allowed 
    * 
    * @param context Current context 
    * @return date after which the next geocoding query is allowed 
    */ 
    private static long getAllowedDate(Context context) { 
     final SharedPreferences p = context.getSharedPreferences(
       PREFERENCES_GEOCODER, Context.MODE_PRIVATE); 
     return p.getLong(KEY_ALLOW, 0); 
    } 

    /** 
    * Is thrown when the query was over limit before 24 hours 
    */ 
    public static final class LimitExceededException extends Exception { 
     private static final long serialVersionUID = -1243645207607944474L; 
    } 

} 

WebserviceClient : 당신은 당신의 데이터를 얻기 위해 다음과 같은 방법을 사용할 수 있습니다

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.URL; 
import java.net.URLConnection; 

public class WebserviceClient { 

    public static byte[] download(String url) { 
     InputStream is = null; 
     ByteArrayOutputStream os = null; 

     try { 

      final URL u = new URL(url); 
      final URLConnection connection = u.openConnection(); 
      connection.connect(); 

      is = connection.getInputStream(); 
      os = new ByteArrayOutputStream(); 

      final byte[] buffer = new byte[5120]; 
      int read; 

      while (true) { 
       read = is.read(buffer, 0, buffer.length); 
       if (read == -1) 
        break; 
       os.write(buffer, 0, read); 
      } 

      return os.toByteArray(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (is != null) 
       try { 
        is.close(); 
       } catch (IOException ignored) { 
       } 
      if (os != null) 
       try { 
        os.close(); 
       } catch (IOException ignored) { 
       } 
     } 

     return null; 
    } 
} 

.

geocoderModel = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 5); 

당신은이 코드를 통해 모든 주소를 가지고 있습니다. 이 도움이 되었기를 바랍니다.

+0

인터넷 연결이 필요한가요? 그렇다면 대체 무엇이 될 것입니까? –

+0

예, 인터넷 연결이 필요합니다. –

+0

오프라인 대체 방법을 알고 계십니까? –

관련 문제