Где я? - Получить страну - PullRequest
       2

Где я? - Получить страну

119 голосов
/ 07 сентября 2010

Мобильный андроид на самом деле довольно хорошо знает, где он находится - но есть ли способ узнать страну по что-то вроде кода страны?

Не нужно знать точное положение GPS - страны достаточно

Сначала я подумал об использовании часового пояса, но на самом деле мне нужно больше информации, чем это, поскольку это имеет значение, если местоположение - Нью-Йорк или Лима.

Справочная информация о вопросе: У меня есть приложение, которое использует значения температуры, и я хотел бы установить единицы измерения по умолчанию либо в градусах Цельсия, либо в градусах Фаренгейта, в зависимости от того, где находится США или за пределами

Ответы [ 11 ]

128 голосов
/ 17 октября 2013
/**
 * Get ISO 3166-1 alpha-2 country code for this device (or null if not available)
 * @param context Context reference to get the TelephonyManager instance from
 * @return country code or null
 */
public static String getUserCountry(Context context) {
    try {
        final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        final String simCountry = tm.getSimCountryIso();
        if (simCountry != null && simCountry.length() == 2) { // SIM country code is available
            return simCountry.toLowerCase(Locale.US);
        }
        else if (tm.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) { // device is not 3G (would be unreliable)
            String networkCountry = tm.getNetworkCountryIso();
            if (networkCountry != null && networkCountry.length() == 2) { // network country code is available
                return networkCountry.toLowerCase(Locale.US);
            }
        }
    }
    catch (Exception e) { }
    return null;
}
90 голосов
/ 07 сентября 2010

В результате вы получите код страны , установленный для телефона (язык телефона, НЕ местоположение пользователя):

 String locale = context.getResources().getConfiguration().locale.getCountry(); 

также может заменить getCountry () на getISO3Country () , чтобы получить трехбуквенный код ISO для страны. Это получит название страны :

 String locale = context.getResources().getConfiguration().locale.getDisplayCountry();

Это кажется проще, чем другие методы, и полагаться на настройки локализации на телефоне, поэтому, если пользователь из США находится за границей, он, вероятно, все еще хочет Фаренгейт, и это будет работать :)

Примечание редактора : Это решение не имеет никакого отношения к расположению телефона. Это постоянно. Когда вы путешествуете по Германии, локаль НЕ изменится. Короче говоря: локаль! = Местоположение.

58 голосов
/ 05 ноября 2014

Используйте эту ссылку http://ip -api.com / json , это предоставит всю информацию как json. Из этого JSON вы можете легко получить страну. Этот сайт работает с использованием вашего текущего IP-адреса, он автоматически определяет IP-адрес и сведения об отправке.

Документы http://ip -api.com / docs / api: json Надеюсь, это поможет.

Пример json

{
  "status": "success",
  "country": "United States",
  "countryCode": "US",
  "region": "CA",
  "regionName": "California",
  "city": "San Francisco",
  "zip": "94105",
  "lat": "37.7898",
  "lon": "-122.3942",
  "timezone": "America/Los_Angeles",
  "isp": "Wikimedia Foundation",
  "org": "Wikimedia Foundation",
  "as": "AS14907 Wikimedia US network",
  "query": "208.80.152.201"
}

note : поскольку это стороннее решение, используйте его только в том случае, если другие не работают.

58 голосов
/ 07 сентября 2010

На самом деле я только что узнал, что есть еще один способ получения кода страны, используя метод getSimCountryIso (), равный TelephoneManager:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String countryCode = tm.getSimCountryIso();

Так как это сим-код, он также долженне меняется при поездках в другие страны.

34 голосов
/ 07 сентября 2010

Сначала получите LocationManager. Затем позвоните LocationManager.getLastKnownPosition. Затем создайте GeoCoder и вызовите GeoCoder.getFromLocation. Делай это в отдельной ветке !! Это даст вам список Address объектов. Позвоните Address.getCountryName и вы его получите.

Имейте в виду, что последняя известная позиция может быть немного устаревшей, поэтому, если пользователь только что пересек границу, вы можете некоторое время не знать об этом.

13 голосов
/ 22 мая 2016

Вот полное решение, основанное на LocationManager и в качестве запасного варианта TelephonyManager и местоположения сетевого провайдера. Я использовал приведенный выше ответ @Marco W. для запасной части (отличный ответ как таковой!).

Примечание: код содержит PreferencesManager, это вспомогательный класс, который сохраняет и загружает данные из SharedPrefferences. Я использую его, чтобы сохранить страну в S "P, я получаю страну только в том случае, если она пуста. Что касается моего продукта, мне не особо важны все крайние случаи (пользователь ездит за границу и т. Д.) 1003 *

public static String getCountry(Context context) {
    String country = PreferencesManager.getInstance(context).getString(COUNTRY);
    if (country != null) {
        return country;
    }

    LocationManager locationManager = (LocationManager) PiplApp.getInstance().getSystemService(Context.LOCATION_SERVICE);
    if (locationManager != null) {
        Location location = locationManager
                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (location == null) {
            location = locationManager
                    .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }
        else {
            Geocoder gcd = new Geocoder(context, Locale.getDefault());
            List<Address> addresses;
            try {
                addresses = gcd.getFromLocation(location.getLatitude(),
                        location.getLongitude(), 1);

                if (addresses != null && !addresses.isEmpty()) {
                    country = addresses.get(0).getCountryName();
                    if (country != null) {
                        PreferencesManager.getInstance(context).putString(COUNTRY, country);
                        return country;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    country = getCountryBasedOnSimCardOrNetwork(context);
    if (country != null) {
        PreferencesManager.getInstance(context).putString(COUNTRY, country);
        return country;
    }
    return null;
}


/**
 * Get ISO 3166-1 alpha-2 country code for this device (or null if not available)
 *
 * @param context Context reference to get the TelephonyManager instance from
 * @return country code or null
 */
private static String getCountryBasedOnSimCardOrNetwork(Context context) {
    try {
        final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        final String simCountry = tm.getSimCountryIso();
        if (simCountry != null && simCountry.length() == 2) { // SIM country code is available
            return simCountry.toLowerCase(Locale.US);
        } else if (tm.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) { // device is not 3G (would be unreliable)
            String networkCountry = tm.getNetworkCountryIso();
            if (networkCountry != null && networkCountry.length() == 2) { // network country code is available
                return networkCountry.toLowerCase(Locale.US);
            }
        }
    } catch (Exception e) {
    }
    return null;
}
13 голосов
/ 07 сентября 2010

Вы можете использовать getNetworkCountryIso() из TelephonyManager, чтобы узнать страну, в которой находится телефон (хотя, очевидно, это ненадежно в сетях CDMA).

3 голосов
/ 26 октября 2018

Для некоторых устройств, если язык по умолчанию установлен разным (индиец может установить английский (США)), тогда

context.getResources().getConfiguration().locale.getDisplayCountry();

даст неправильное значение. Так что этот метод ненадежен

Кроме того, метод getNetworkCountryIso () в TelephonyManager не будет работать на устройствах без SIM-карты (планшеты WIFI).

Если на устройстве нет SIM-карты, мы можем использовать часовой пояс, чтобы узнать страну. Для таких стран, как Индия, этот метод будет работать

пример кода, используемого для проверки, является Индия или нет (Идентификатор часового пояса: Азия / Калькутта)

private void checkCountry() {


    TelephonyManager telMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    if (telMgr == null)
        return;

    int simState = telMgr.getSimState();

    switch (simState) {
        //if sim is not available then country is find out using timezone id
        case TelephonyManager.SIM_STATE_ABSENT:
            TimeZone tz = TimeZone.getDefault();
            String timeZoneId = tz.getID();
            if (timeZoneId.equalsIgnoreCase(Constants.INDIA_TIME_ZONE_ID)) {
               //do something
            } else {
               //do something
            }
            break;

            //if sim is available then telephony manager network country info is used
        case TelephonyManager.SIM_STATE_READY:

           TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
            if (tm != null) {
                String countryCodeValue = tm.getNetworkCountryIso();
                //check if the network country code is "in"
                if (countryCodeValue.equalsIgnoreCase(Constants.NETWORK_INDIA_CODE)) {
                   //do something
                }

                else {
                   //do something
                }

            }
            break;

    }
}
3 голосов
/ 22 апреля 2017
String locale = context.getResources().getConfiguration().locale.getCountry(); 

Не рекомендуется. Используйте это вместо:

Locale locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    locale = context.getResources().getConfiguration().getLocales().get(0);
} else {
    locale = context.getResources().getConfiguration().locale;
}
1 голос
/ 12 августа 2016

Используя GPS с широтой и долготой, мы можем получить код страны.

Если мы используем телефонию, она не будет работать, если мы не будем использовать сим-карту, а в локали, в зависимости от языка, отобразитсяневерный код страны.

MainActivity.java:

    GPSTracker gpsTrack;
    public static double latitude = 0;
    public static double longitude = 0;

    gpsTrack = new GPSTracker(TabHomeActivity.this);

        if (gpsTrack.canGetLocation()) {
            latitude = gpsParty.getLatitude();
            longitude = gpsParty.getLongitude();

            Log.e("GPSLat", "" + latitude);
            Log.e("GPSLong", "" + longitude);

        } else {
            gpsTrack.showSettingsAlert();

            Log.e("ShowAlert", "ShowAlert");

        }

        countryCode = getAddress(TabHomeActivity.this, latitude, longitude);

        Log.e("countryCode", ""+countryCode);

   public String getAddress(Context ctx, double latitude, double longitude) {
    String region_code = null;
    try {
        Geocoder geocoder = new Geocoder(ctx, Locale.getDefault());
        List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
        if (addresses.size() > 0) {
            Address address = addresses.get(0);


            region_code = address.getCountryCode();


        }
    } catch (IOException e) {
        Log.e("tag", e.getMessage());
    }

    return region_code;
}

GPSTracker.java:

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

public class GPSTracker extends Service implements LocationListener {

    private final Context mContext;

    // flag for GPS status
    boolean isGPSEnabled = false;

    // flag for network status
    boolean isNetworkEnabled = false;

    // flag for GPS status
    boolean canGetLocation = false;

    Location location; // location
    double latitude; // latitude
    double longitude; // longitude

    // The minimum distance to change Updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

    // Declaring a Location Manager
    protected LocationManager locationManager;

    public GPSTracker(Context context) {
        this.mContext = context;
        getLocation();
    }

    public Location getLocation() {
        try {
            locationManager = (LocationManager) mContext
                    .getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            // getting network status
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                this.canGetLocation = true;
                // First get location from Network Provider
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }

    /**
     * Stop using GPS listener
     * Calling this function will stop using GPS in your app
     * */
    public void stopUsingGPS(){
        if(locationManager != null){
            locationManager.removeUpdates(GPSTracker.this);
        }
    }

    /**
     * Function to get latitude
     * */
    public double getLatitude(){
        if(location != null){
            latitude = location.getLatitude();
        }

        // return latitude
        return latitude;
    }

    /**
     * Function to get longitude
     * */
    public double getLongitude(){
        if(location != null){
            longitude = location.getLongitude();
        }

        // return longitude
        return longitude;
    }

    /**
     * Function to check GPS/wifi enabled
     * @return boolean
     * */
    public boolean canGetLocation() {
        return this.canGetLocation;
    }



    public void showSettingsAlert() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
                .setCancelable(false)
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                        mContext.startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                        dialog.cancel();
                    }
                });
        final AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public void onLocationChanged(Location location) {
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

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

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

}

Журнал:

E / countryCode: IN

Редактировать: Использовать Объединенный провайдер местоположения чтобы получить обновление широты и долготы для лучшего результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...