Thursday, April 12, 2012

Where am I?

When your mobile application requires registration quite often user's location become a relevant question. It's very convenient when registration form contains your location (at least country) preselected. I know at least 3 ways to do this in Android (each with its own advantages and disadvantages):
  1. using Locale:
  2.      Locale myLocale = Locale.getDefault();      
    
    This is the easiest and probably most incorrect way. Actually, locale represents not current user's language/country combination, but values selected in Android Settings. For example, when selected locale is English (South Africa) your locale object will tell you, that your country code (Locale#getCountry) is ZA and your country name (Locale#getDisplayCountry) is South Africa. In principle, all is correct. But it's possible to select not your current locale. Moreover, your locale may not be available on your device. In this case it's not possible to determine your country using this approach. So that the only advantage of this approach is ease of implementation. Also no need for internet connection in this case but it is unlikely that this is a great advantage.
  3. using TelephonyManager:
  4.      TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);  
         String iso = telephonyManager.getNetworkCountryIso();   
    
    TelephonyManager#getNetworkCountryIso due to documentation:
    Returns the ISO country code equivalent of the current registered operator's MCC (Mobile Country Code). Availability: Only when user is registered to a network. Result may be unreliable on CDMA networks (use getPhoneType() to determine if on a CDMA network).
    So, it's good technique, but requirement to be registered in the mobile network is a very serious limitation especially for tablets.
  5. using LocationManager:
  6. Imho, the most accurate solution which based on real geographical location. It's requires internet connection and permission to collect your location data:


    It also requires permission in manifest:
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>  
    

    And finally:
         LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);  
         LocationListener mlocListener = new LocationListener() {  
           @Override  
           public void onLocationChanged(Location location) {  
             final Geocoder geocoder = new Geocoder(GApp.sInstance.getApplicationContext());  
             try {  
               List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);  
               if (addresses != null) {  
                 Address address = addresses.get(0);  
               }  
             } catch (Exception e) {  
               e.printStackTrace();  
             }  
           }  
           @Override  
           public void onStatusChanged(String s, int i, Bundle bundle) {  
           }  
           @Override  
           public void onProviderEnabled(String s) {  
           }  
           @Override  
           public void onProviderDisabled(String s) {  
           }  
         };  
         mlocManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 0, 0, mlocListener);  
    
    It is a little bit more complicated than the previous two methods, but using Address we are able to identify not just current country, but also city (Address#getLocality) and even some thoroughfare (Address#getThoroughfare).

No comments:

Post a Comment