web-dev-qa-db-fra.com

Comment puis-je obtenir mon Android de l'appareil sans utiliser le GPS?

Un Android mobile sait en fait très bien où il se trouve - mais existe-t-il un moyen de récupérer le pays à l'aide d'un code de pays ou d'un nom de pays?

Pas besoin de connaître la position GPS exacte - le code de pays ou le nom suffit, et j'utilise le code pour cela:

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

mais ça me donne le code "US"
mais mon appareil a été conservé en Inde; existe-t-il un moyen de rechercher le code de pays actuel du périphérique sans utiliser le GPS ou le fournisseur de réseau? parce que j'utilise une tablette. Merci d'avance.

47
Vikas Goyal

Vous ne devriez rien transmettre à getCountry(), supprimez Locale.getDefault()

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

75
Rawkode

Vous pouvez simplement utiliser ce code,

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

Cela retournera "US" si votre réseau connecté actuel est États-Unis. Cela fonctionne même sans carte SIM. J'espère que cela résoudra votre problème.

63
Kishath

Utilisez ce lien http://ip-api.com/json , cela fournira toutes les informations en json. De ce JSON, vous pouvez obtenir le pays facilement. Ce site fonctionne avec votre adresse IP actuelle, il détecte automatiquement l’adresse IP et les détails de renvoi.

Docs http://ip-api.com/docs/api:json J'espère que cela vous aidera.

C'est ce que j'ai eu.

{
"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": ""
}

N.B. - Comme il s'agit d'une API tierce, ne l'utilisez pas comme solution principale. Et aussi pas sûr que ce soit gratuit ou non.

42
shine_joseph

La réponse cochée a du code obsolète. Vous devez implémenter ceci:

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();
}
8
Egemen Hamutçu

Pour certains appareils, si la langue par défaut est différente (un Indien peut définir Anglais (US)), puis

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

va donner une valeur fausse. Alors cette méthode n'est pas fiable

De plus, la méthode getNetworkCountryIso () de TelephonyManager ne fonctionnera pas sur les appareils sans carte SIM (tablettes WIFI).

Si un appareil ne possède pas de carte SIM, nous pouvons utiliser le fuseau horaire pour obtenir le pays. Pour des pays comme l'Inde, cette méthode fonctionnera

exemple de code utilisé pour vérifier que le pays est indien ou non (ID du fuseau horaire: asie/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;

    }
}
4
MarGin

Voici un exemple complet. Essayez d’obtenir le code de pays auprès de TelephonyManager (des appareils SIM ou CDMA) et, s’il n’est pas disponible, essayez de l’obtenir à partir de la configuration locale.

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;
}

Une autre idée est également d'essayer une requête d'API comme dans ceci réponse .

Références ici et ici

3
radu_paun

J'ai créé une fonction utilitaire (testée une fois sur un périphérique sur lequel le code de pays incorrect était basé sur les paramètres régionaux). J'espère que cette aide. Référence : 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
    }
2
Killer