Ein Android-Handy weiß eigentlich ganz genau, wo es sich befindet - aber gibt es eine Möglichkeit, das Land anhand eines Ländercodes oder eines Ländernamens abzurufen?
Es ist nicht erforderlich, die genaue GPS-Position zu kennen - der Ländercode oder Name ist ausreichend, und ich verwende diesen Code:
String locale = context.getResources().getConfiguration().locale.getCountry(Locale.getDefault());
System.out.println("country = "+locale);
Es gibt mir den Code "US", aber mein Gerät wird in Indien aufbewahrt. Gibt es eine Möglichkeit, den aktuellen Ländercode des Geräts zu finden, ohne GPS oder einen Netzwerkanbieter zu verwenden?
Weil ich ein Tablet benutze.
Sie können einfach diesen Code verwenden,
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); String countryCodeValue = tm.getNetworkCountryIso();
Dies gibt "US" zurück, wenn sich Ihr derzeit verbundenes Netzwerk in den USA befindet. Dies funktioniert auch ohne SIM-Karte.
quelle
getNetworkCountryIso()
erfordert keine zusätzliche Erlaubnis.Verwenden Sie den Link http://ip-api.com/json . Dadurch werden alle Informationen als JSON bereitgestellt. Mit diesem JSON-Inhalt können Sie das Land leicht abrufen. Diese Seite funktioniert mit Ihrer aktuellen IP-Adresse. Es erkennt automatisch die IP-Adresse und die Sendback-Details.
Dokumentation
Das habe ich bekommen:
{ "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": "" }
Hinweis: Da es sich um eine Drittanbieter-API handelt, verwenden Sie sie nicht als primäre Lösung. Und ich bin mir auch nicht sicher, ob es kostenlos ist oder nicht.
quelle
Die überprüfte Antwort hat veralteten Code. Sie müssen dies implementieren:
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(); }
quelle
Hier ist ein vollständiges Beispiel. Es wird versucht, den Ländercode von TelephonyManager (von SIM- oder CDMA-Geräten) abzurufen. Wenn er nicht verfügbar ist, wird versucht, ihn von der lokalen Konfiguration abzurufen.
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 three characters (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; }
Eine andere Idee ist es, eine API-Anfrage wie in dieser Antwort zu versuchen .
Referenzen sind hier und hier .
quelle
Wenn für einige Geräte die Standardsprache anders eingestellt ist (ein Inder kann dann Englisch (US) einstellen)
context.getResources().getConfiguration().locale.getDisplayCountry();
wird den falschen Wert geben. Diese Methode ist also nicht zuverlässig.
Die Methode getNetworkCountryIso () von TelephonyManager funktioniert auch nicht auf Geräten ohne SIM-Karte (Wi-Fi-Tablets).
Wenn ein Gerät keine SIM-Karte hat, können wir die Zeitzone verwenden, um das Land zu erhalten. Für Länder wie Indien wird diese Methode funktionieren.
Beispielcode zur Überprüfung des Landes ist Indien oder nicht.
Verwenden Sie die folgenden Werte in Ihrer Konstantendatei
(Constants.INDIA_TIME_ZONE_ID: "asia / calcutta", Constants.NETWORK_INDIA_CODE: "in")
Fügen Sie in Ihrer Aktivität den folgenden Code hinzu:
private void checkCountry() { TelephonyManager telMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); if (telMgr == null) return; int simState = telMgr.getSimState(); switch (simState) { // If a SIM card is not available then the // country is found using the 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 a SIM card is available then the telephony // manager network country information 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; } }
quelle
Ich habe eine Dienstprogrammfunktion erstellt (einmal auf einem Gerät getestet, auf dem ich einen falschen Ländercode basierend auf dem Gebietsschema erhalten habe).
Referenz : CountryCodePicker.java
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 }
quelle
Wenn Sie die Landesvorwahl erhalten möchten, ohne um Erlaubnis zu bitten, können Sie einen schwierigen Weg wählen.
Die Methode verwendet einfach eine API, um den Ländercode abzurufen, und es gibt keine Bibliotheken von Drittanbietern, auf die Sie sich verlassen können. Wir können eine für uns erstellen.
Hier habe ich Google Cloud-Funktionen verwendet , um eine API zu schreiben, und es ist so mühelos.
Schritt 1: Erstellen Sie ein Google Cloud-Konto und richten Sie die Abrechnung ein (die kostenlose Stufe reicht aus).
Schritt 2: Erstellen Sie eine Cloud-Funktion, um den geografischen Standort abzurufen
Kopieren Sie diese Grundfunktion in den Code-Editor von index.js :
const cors = require('cors') function _geolocation(req, res) { const data = { country_code: req.headers["x-appengine-country"], region: req.headers["x-appengine-region"], city: req.headers["x-appengine-city"], cityLatLong: req.headers["x-appengine-citylatlong"], userIP: req.headers["x-appengine-user-ip"] } res.json(data) }; exports.geolocation = (req, res) => { const corsHandler = cors({ origin: true }) return corsHandler(req, res, function() { return _geolocation(req, res); }); };
Außerdem müssen wir die package.json- Definition kopieren :
{ "name": "gfc-geolocation", "version": "0.0.1", "dependencies": { "cors": "^2.8.4" } }
Schritt 3: Beenden Sie und erhalten Sie die URL ähnlich wie:
"https://us-central1-geolocation-mods-sdde.cloudfunctions.net/geolocation"
Schritt 4: Analysieren Sie die JSON-Antwort und rufen Sie den Ländercode ab
Die Antwort sieht folgendermaßen aus:
{ "country": "IN", "region": "kl", "city": "kochi", "cityLatLong": "9.9312,76.2673", "userIP": "xx.xx.xx.xx" }
Dank und Dank geht an den Artikel " Mittel ": Kostenlose IP-basierte Geolokalisierung mit Google Cloud-Funktionen
quelle
Es ist nicht erforderlich, eine API aufzurufen. Sie können den Ländercode von Ihrem Gerät abrufen, auf dem er sich befindet. Verwenden Sie einfach diese Funktion:
fun getUserCountry(context: Context): String? { try { val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager val simCountry = tm.simCountryIso if (simCountry != null && simCountry.length == 2) { // SIM country code is available return simCountry.toLowerCase(Locale.US) } else if (tm.phoneType != TelephonyManager.PHONE_TYPE_CDMA) { // Device is not 3G (would be unreliable) val networkCountry = tm.networkCountryIso if (networkCountry != null && networkCountry.length == 2) { // network country code is available return networkCountry.toLowerCase(Locale.US) } } } catch (e: Exception) { } return null }
quelle