Надежный способ узнать страну, в которой находится пользователь?

Я обычно получаю страну из языка устройства. Это работает, но теперь я должен признать Бразилию. И большинство устройств имеют только португальский (pt_PT) вариант, а не португальский (Бразилия).

Я проверил эту тему: Где я? - Получить страну

Методы

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

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

Все еще только язык, не помогает.

Еще есть предложение с сим-картой, но я не уверен, что это будет надежно работать (у всех ли сим-карт такая уникальная идентификация?), это тоже немного не то, что мне нужно, потому что пользователь не может это изменить (в том случае, если это была настройка), и это исключит пользователей, использующих устройство без сим-карты (возможно, они просто используют WLAN).

Также есть предложение геолокации, но оно, вероятно, не будет работать на устройствах, на которых оно отключено. Или я ошибаюсь?

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


person User    schedule 08.08.2012    source источник
comment
Обратное геокодирование возможно, но может оказаться излишним. Я нашел Bing простым и надежным.   -  person Tony    schedule 09.08.2012
comment
Под обратным геокодированием вы имеете в виду подход, подобный EboMike в теме, на которую я дал ссылку, верно?   -  person User    schedule 09.08.2012
comment
Нет, используя широту и долготу телефонов через LocationManager, чтобы получить страну точки.   -  person Tony    schedule 09.08.2012


Ответы (5)


Вы можете получить местоположение из телефонной сети:

TelephonyManager.getNetworkCountryIso()

Или с SIM-карты:

TelephonyManager.getSimCountryIso()

Или, если у вас есть номер телефона пользователя, вы можете сопоставить его со страной с помощью этих данных.

В идеале вы могли бы использовать все три из них (в некотором порядке, возможно, SIM-карта, номер телефона, затем сеть), и если ни один из них не работает, используйте обратную геолокацию в крайнем случае.

person Eric    schedule 08.08.2012
comment
Но похоже, что getNetworkCountryIso также в основном зависит от SIM-карты или...? Только когда пользователь зарегистрирован в сети Или какие это могут быть сети? - person User; 09.08.2012
comment
Это зависит от того, к какой сети оператора вы подключены. К каждому из них прикреплен код страны (как говорится в документации, он возвращает текущий зарегистрированный код MCC (мобильный код страны)). - person Eric; 09.08.2012
comment
Хорошо, спасибо за совет. Попробую сначала с языком, если не хватит инфы, телефон/сеть, потом геолокация и если все же не хватит, покажу кастомный диалог. Это покроет все случаи. - person User; 09.08.2012
comment
Хм. Но для геолокации нужно добавить разрешение. И это, вероятно, будет негативно, если все пользователи увидят разрешение на геолокацию. Специально, если мне это нужно только для определенных бразильских пользователей..... - person User; 10.08.2012
comment
Что ж, вы можете указать это в сводке вашего приложения или просто пропустить геолокацию и сразу перейти к диалоговому окну. Бразильские пользователи, вероятно, ничего бы не подумали об этом. - person Eric; 10.08.2012

Попробуй это:

 TelephonyManager teleMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
 if (teleMgr != null){
     countryISOCode = teleMgr.getSimCountryIso();
 }

Теперь countryISOCode будет содержать один из следующих кодов стран, аналогичных коду страны ISO 3166, согласно этой записи.

person t0mm13b    schedule 08.08.2012
comment
Хорошо, спасибо за более полный код, но в принципе это то же самое, что и предложение Эрика, не так ли? - person User; 09.08.2012
comment
Ну, это более точно, так как он привязан к сим-карте из страны происхождения, но... будьте осторожны, если это планшет без сим-карты, null будет возвращен. в этом случае потребуется запасной вариант, если только вы не ориентируетесь на смартфоны с сим-картами? - person t0mm13b; 09.08.2012
comment
симкарта из страны происхождения что именно вы имеете в виду? Происхождение от чего...? TelephonyManager.getSimCountryIso() возвращает код страны поставщика SIM-карты. - person User; 09.08.2012
comment
если сим-карта куплена в Испании, она будет иметь испанский код страны, а если сим-карта куплена в Великобритании, она будет иметь код Великобритании. - person t0mm13b; 09.08.2012
comment
Ммм... ладно, значит ли это, что TelephonyManager.getSimCountryIso() вернет код, где в данный момент зарегистрирована SIM-карта? Мне нужна самая актуальная информация о местоположении пользователя, где была куплена симка не важно, разве что это единственная доступная информация. А пока +1 за полезный вклад. - person User; 09.08.2012
comment
А, и нет, я не ориентируюсь на аппараты с sim-картами. Я написал это в исходном вопросе. - person User; 09.08.2012

TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
mTelephonyManager.getNetworkCountryIso();

Как ответил Эрик, приведенный выше код является лучшим подходом. Также стоит отметить, что,

mTelephonyManager.getSimCountryIso()

не следует использовать, так как это указывает на страну проживания поставщика SIM-карты (например, SIM-карта Vodaphone UK возвращает «gb», SIM-карта Vodaphone Germany возвращает «de»), а не текущее местоположение (страну) устройства. Эта разница существенна, когда пользователь находится в роуминге.

person Shavi    schedule 18.05.2015

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

person D.A    schedule 08.08.2012
comment
Ну да, может быть, я делаю несколько шагов вниз, сначала пробую с языком, потом пробую с симкой, потом геолокацию, и использую диалог в крайнем случае, если у меня все еще есть неоднозначная информация. - person User; 09.08.2012

Это работает на меня.

String countryISOCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TelephonyManager teleMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    if (teleMgr != null){
        countryISOCode = teleMgr.getSimCountryIso();
    }

............................

person abir-cse    schedule 12.12.2017