En réalité, un mobile Android sait 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?
Pas besoin de connaître la position GPS exacte - le pays est suffisant
J'ai d'abord envisagé d'utiliser le fuseau horaire, mais en réalité, j'ai besoin de plus d'informations car cela fait une différence si l'emplacement est New York ou Lima.
L'arrière-plan de la question: J'ai une application qui utilise les valeurs de température et j'aimerais définir l'unité par défaut en Celsius ou en Fahrenheit, selon que l'emplacement est US ou à l'extérieur
String locale = context.getResources().getConfiguration().locale.getCountry();
pouvez également remplacer getCountry () par getISO3Country () pour obtenir un code ISO à 3 lettres pour le pays. Cela va donner le nom du pays :
String locale = context.getResources().getConfiguration().locale.getDisplayCountry();
Cela semble plus facile que les autres méthodes et repose sur les paramètres de localisation du téléphone. Par conséquent, si un utilisateur américain se trouve à l'étranger, il souhaite probablement toujours utiliser Fahrenheit et cela fonctionnera :)
/**
* 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;
}
En fait, je viens de découvrir qu'il existe un moyen supplémentaire d'obtenir un code de pays, à l'aide de la méthode getSimCountryIso () de TelephoneManager
:
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String countryCode = tm.getSimCountryIso();
Comme c'est le code de la sim, cela ne devrait pas non plus changer lorsque vous voyagez dans d'autres pays.
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.
Exemple 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: S'agissant d'une solution tierce, utilisez-la uniquement si les autres ne fonctionnent pas.
Tout d'abord, procurez-vous le LocationManager. Ensuite, appelez LocationManager.getLastKnownPosition
. Créez ensuite un GeoCoder et appelez GeoCoder.getFromLocation
. Est-ce que ceci est dans un fil séparé !! Cela vous donnera une liste d'objets Address
. Appelez Address.getCountryName
et vous l'avez.
Gardez à l'esprit que la dernière position connue peut être un peu fade, donc si l'utilisateur vient de traverser la frontière, vous ne le saurez peut-être pas pendant un moment.
Voici une solution complète basée sur LocationManager et, comme solution de secours, les emplacements de TelephonyManager et du fournisseur de réseau. J'ai utilisé la réponse ci-dessus de @Marco W. pour la partie de repli (excellente réponse en tant que telle!).
Remarque: le code contient PreferencesManager. Il s'agit d'une classe d'assistance qui enregistre et charge les données à partir de SharedPrefrences. Je l'utilise pour sauver le pays à S "P, je ne reçois le pays que s'il est vide. Pour mon produit, je ne me soucie pas vraiment de tous les cas Edge (l'utilisateur voyage à l'étranger, etc.).
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;
}
Vous pouvez utiliser getNetworkCountryIso()
&AGRAVE; PARTIR DE TelephonyManager
pour connaître le pays dans lequel se trouve le téléphone (même si apparemment cela n’est pas fiable sur les réseaux CDMA).
String locale = context.getResources().getConfiguration().locale.getCountry();
Est obsolète. Utilisez ceci à la place:
Locale locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locale = context.getResources().getConfiguration().getLocales().get(0);
} else {
locale = context.getResources().getConfiguration().locale;
}
Pour certains appareils, si la langue par défaut est différente (un indien peut définir anglais (US)),
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 n'a pas de carte SIM, nous pouvons utiliser Time Zone 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 (Identifiant 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:
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;
}
}
En utilisant le GPS avec la latitude et la longitude, nous pouvons obtenir le code de pays.
Si nous utilisons la téléphonie, cela ne fonctionnera pas si nous n'utilisons pas de carte SIM et dans les paramètres régionaux, en fonction de la langue, le code pays est affiché de manière erronée.
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;
}
}
Log:
E/countryCode: IN
Edit: Utilisez Fused Location Provider pour obtenir la mise à jour de la latitude et de la longitude pour de meilleurs résultats.
J'ai utilisé GEOIP db et créé une fonction. Vous pouvez consommer ce lien directement http://jamhubsoftware.com/geoip/getcountry.php
{"country":["India"],"isoCode":["IN"],"names":[{"de":"Indien","en":"India","es":"India","fr":"Inde","ja":"\u30a4\u30f3\u30c9","pt-BR":"\u00cdndia","ru":"\u0418\u043d\u0434\u0438\u044f","zh-CN":"\u5370\u5ea6"}]}
vous pouvez télécharger les fichiers autoload.php et .mmdb à partir de https://dev.maxmind.com/geoip/geoip2/geolite2/
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$ip_address = $_SERVER['REMOTE_ADDR'];
//$ip_address = '3.255.255.255';
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// This creates the Reader object, which should be reused across
// lookups.
$reader = new Reader('/var/www/html/geoip/GeoLite2-City.mmdb');
// Replace "city" with the appropriate method for your database, e.g.,
// "country".
$record = $reader->city($ip_address);
//print($record->country->isoCode . "\n"); // 'US'
//print($record->country->name . "\n"); // 'United States'
$rows['country'][] = $record->country->name;
$rows['isoCode'][] = $record->country->isoCode;
$rows['names'][] = $record->country->names;
print json_encode($rows);
//print($record->country->names['zh-CN'] . "\n"); // '美国'
//
//print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota'
//print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN'
//
//print($record->city->name . "\n"); // 'Minneapolis'
//
//print($record->postal->code . "\n"); // '55455'
//
//print($record->location->latitude . "\n"); // 44.9733
//print($record->location->longitude . "\n"); // -93.2323
?>