Подтвердить что ты не робот

Как я могу получить код страны Android Android без использования GPS?

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

Не нужно знать точное местоположение GPS - достаточно кода страны или названия, и я использую код для этого:

 String locale = context.getResources().getConfiguration().locale.getCountry(Locale.getDefault());      
 System.out.println("country = "+locale);

но он дает мне код "США"
но мое устройство хранилось в Индии; есть ли способ найти текущий код страны, не используя GPS или Network Provider. потому что я использую планшет. Спасибо в Advance.

4b9b3361

Ответ 1

Вы не должны передавать ничего в getCountry(), удалите Locale.getDefault()

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

Ответ 2

Вы можете просто использовать этот код,

TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String countryCodeValue = tm.getNetworkCountryIso();

Это вернет "США", если ваша текущая подключенная сеть - Соединенные Штаты. Это работает без SIM-карты. Надеюсь, это решит вашу проблему.

Ответ 3

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

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

Это то, что я получил.

{
"as": "AS55410 C48 Okhla Industrial Estate, New Delhi-110020",
"city": "Kochi",
"country": "India",
"countryCode": "IN",
"isp": "Vodafone India",
"lat": 9.9667,
"lon": 76.2333,
"org": "Vodafone India",
"query": "123.63.81.162",
"region": "KL",
"regionName": "Kerala",
"status": "success",
"timezone": "Asia/Kolkata",
"zip": ""
}

NB. Поскольку это API сторонних производителей, не используйте его в качестве основного решения. А также не уверен, свободна ли она или нет.

Ответ 4

Проверенный ответ имеет устаревший код. Вам необходимо реализовать это:

String locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    locale = context.getResources().getConfiguration().getLocales().get(0).getCountry();
} else {
    locale = context.getResources().getConfiguration().locale.getCountry();
}

Ответ 5

Я создал служебную функцию (протестирован один раз на устройстве, где я получал неправильный код страны в зависимости от локали). Надеюсь, что это поможет. Ссылка: https://github.com/hbb20/CountryCodePickerProject/blob/master/ccp/src/main/java/com/hbb20/CountryCodePicker.java#L1965

fun getDetectedCountry(context: Context, defaultCountryIsoCode: String): String {
        detectSIMCountry(context)?.let {
            return it
        }

        detectNetworkCountry(context)?.let {
            return it
        }

        detectLocaleCountry(context)?.let {
            return it
        }

        return defaultCountryIsoCode
    }

private fun detectSIMCountry(context: Context): String? {
        try {
            val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            Log.d(TAG, "detectSIMCountry: ${telephonyManager.simCountryIso}")
            return telephonyManager.simCountryIso
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

private fun detectNetworkCountry(context: Context): String? {
        try {
            val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            Log.d(TAG, "detectNetworkCountry: ${telephonyManager.simCountryIso}")
            return telephonyManager.networkCountryIso
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

private fun detectLocaleCountry(context: Context): String? {
        try {
            val localeCountryISO = context.getResources().getConfiguration().locale.getCountry()
            Log.d(TAG, "detectNetworkCountry: $localeCountryISO")
            return localeCountryISO
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

Ответ 6

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

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

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

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

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

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

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:


            if (telMgr != 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;

    }
}

Ответ 7

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

private static String getDeviceCountryCode(Context context) {
    String countryCode;

    // try to get country code from TelephonyManager service
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    if(tm != null) {
        // query first getSimCountryIso()
        countryCode = tm.getSimCountryIso();
        if (countryCode != null && countryCode.length() == 2)
            return countryCode.toLowerCase();

        if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
            // special case for CDMA Devices
            countryCode = getCDMACountryIso();
        } else {
            // for 3G devices (with SIM) query getNetworkCountryIso()
            countryCode = tm.getNetworkCountryIso();
        }

        if (countryCode != null && countryCode.length() == 2)
            return countryCode.toLowerCase();
    }

    // if network country not available (tablets maybe), get country code from Locale class
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        countryCode = context.getResources().getConfiguration().getLocales().get(0).getCountry();
    } else {
        countryCode = context.getResources().getConfiguration().locale.getCountry();
    }

    if (countryCode != null && countryCode.length() == 2)
        return  countryCode.toLowerCase();

    // general fallback to "us"
    return "us";
}

@SuppressLint("PrivateApi")
private static String getCDMACountryIso() {
    try {
        // try to get country code from SystemProperties private class
        Class<?> systemProperties = Class.forName("android.os.SystemProperties");
        Method get = systemProperties.getMethod("get", String.class);

        // get homeOperator that contain MCC + MNC
        String homeOperator = ((String) get.invoke(systemProperties,
                "ro.cdma.home.operator.numeric"));

        // first 3 chars (MCC) from homeOperator represents the country code
        int mcc = Integer.parseInt(homeOperator.substring(0, 3));

        // mapping just countries that actually use CDMA networks
        switch (mcc) {
            case 330: return "PR";
            case 310: return "US";
            case 311: return "US";
            case 312: return "US";
            case 316: return "US";
            case 283: return "AM";
            case 460: return "CN";
            case 455: return "MO";
            case 414: return "MM";
            case 619: return "SL";
            case 450: return "KR";
            case 634: return "SD";
            case 434: return "UZ";
            case 232: return "AT";
            case 204: return "NL";
            case 262: return "DE";
            case 247: return "LV";
            case 255: return "UA";
        }
    } catch (ClassNotFoundException ignored) {
    } catch (NoSuchMethodException ignored) {
    } catch (IllegalAccessException ignored) {
    } catch (InvocationTargetException ignored) {
    } catch (NullPointerException ignored) {
    }

    return null;
}

Также другая идея состоит в том, чтобы попробовать запрос API, как в этом ответе.

Ссылки здесь и здесь

Ответ 8

Не уверен, что решение все еще выполняется, но вот мой:

        private void getCountryCode(final Location location) {
    Helper.log(TAG, "getCountryCode");

    AsyncTask<Void, Void, String> countryCodeTask = new AsyncTask<Void, Void, String>() {

        final float latitude = (float) location.getLatitude();
        final float longitude = (float) location.getLongitude();
        // Helper.log(TAG, "latitude: " +latitude);
        List<Address> addresses = null;
        Geocoder gcd = new Geocoder(mContext);
        String code = null;

        @Override
        protected String doInBackground(Void... params) {
            try {
                addresses = gcd.getFromLocation(latitude, longitude, 1);
                code = addresses.get(0).getCountryCode();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return code;
        }

        @Override
        protected void onPostExecute(String code) {
            Helper.log(TAG, "onPostExecute");
            mCountryCodeListener.returnCountryCode(code);
        }

    };
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
        countryCodeTask.execute();
    } else {
        countryCodeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }
}