it-swarm.com.de

Wo bin ich? - Land holen

Ein Android-Handy weiß eigentlich ganz genau, wo es ist - aber gibt es eine Möglichkeit, das Land durch eine Art Ländercode abzurufen?

Es ist nicht notwendig, die genaue GPS-Position zu kennen - das Land ist ausreichend 

Ich dachte zuerst an die Zeitzone, aber eigentlich brauche ich mehr Informationen, da es einen Unterschied macht, wenn es sich um einen Standort in New York oder Lima handelt.

Der Hintergrund der Frage: Ich habe eine Anwendung, die Temperaturwerte verwendet, und ich möchte die Standardeinheit entweder auf Celsius oder Fahrenheit setzen, abhängig davon, ob der Standort in den USA oder außerhalb liegt

111
DonGru

Dies wird den Ländercode erhalten :

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

kann auch getCountry () durch getISO3Country () ersetzen, um einen 3-stelligen ISO-Code für das Land zu erhalten. Dies wird den Ländernamen erhalten :

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

Dies scheint einfacher zu sein als die anderen Methoden und verlassen sich auf die Lokalisierungseinstellungen des Telefons. Wenn sich ein US-Benutzer im Ausland befindet, möchte er wahrscheinlich immer noch Fahrenheit und dies wird funktionieren :) 

89
stealthcopter
/**
 * 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;
}
122
caw

Ich habe gerade herausgefunden, dass es noch eine weitere Möglichkeit gibt, einen Ländercode zu erhalten, indem Sie die getSimCountryIso () - Methode von TelephoneManager verwenden:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String countryCode = tm.getSimCountryIso();

Da es sich um den Sim-Code handelt, sollte er sich auch nicht ändern, wenn Sie in andere Länder reisen.

57
DonGru

Verwenden Sie diesen Link http://ip-api.com/json , um alle Informationen als json bereitzustellen. Von diesem Json können Sie das Land leicht bekommen. Diese Site arbeitet mit Ihrer aktuellen IP-Adresse und erkennt automatisch die IP- und Rücksendedetails.

Docs http://ip-api.com/docs/api:json Ich hoffe es hilft.

Beispiel 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: Da dies eine Drittanbieterlösung ist, sollten Sie sie nur verwenden, wenn andere nicht funktionieren.

56
shine_joseph

Holen Sie sich zuerst den LocationManager. Rufen Sie dann LocationManager.getLastKnownPosition auf. Dann erstellen Sie einen GeoCoder und rufen Sie GeoCoder.getFromLocation auf. Tun Sie dies in einem separaten Thread !! Dadurch erhalten Sie eine Liste von Address-Objekten. Rufen Sie Address.getCountryName an und Sie haben es bekommen.

Denken Sie daran, dass die letzte bekannte Position etwas veraltet sein kann. Wenn der Benutzer also nur die Grenze überschritten hat, wissen Sie möglicherweise eine Weile nicht darüber.

34
EboMike

Hier ist eine Komplettlösung, die auf dem LocationManager basiert und als Rückfall den TelefonieManager und die Standorte des Netzwerkanbieters. Ich habe die obige Antwort von @Marco W. für den Fallback-Teil verwendet (tolle Antwort wie sich selbst!).

Hinweis: Der Code enthält PreferencesManager. Dies ist eine Hilfsklasse, die Daten von SharedPrefrences speichert und lädt. Ich verwende es, um das Land für S "P zu retten. Ich bekomme das Land nur, wenn es leer ist. Für mein Produkt kümmere ich mich nicht wirklich um alle Edge-Fälle (Benutzer reisen im Ausland usw.).

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

Sie können getNetworkCountryIso() VON TelephonyManager verwenden, um das Land zu ermitteln, in dem sich das Telefon derzeit befindet (auch wenn dies in CDMA-Netzwerken offensichtlich unzuverlässig ist).

12
Dave Webb
String locale = context.getResources().getConfiguration().locale.getCountry(); 

Ist veraltet. Verwenden Sie stattdessen diese:

Locale locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    locale = context.getResources().getConfiguration().getLocales().get(0);
} else {
    locale = context.getResources().getConfiguration().locale;
}
3
4gus71n

Wenn bei einigen Geräten die Standardsprache anders eingestellt ist (ein Inder kann Englisch (USA) einstellen), dann 

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

wird falschen Wert geben. Diese Methode ist daher nicht zuverlässig

Die getNetworkCountryIso () - Methode von TelephonyManager funktioniert auch nicht auf Geräten, die keine SIM-Karte haben (WIFI-Tablets).

Wenn ein Gerät über keine SIM-Karte verfügt, können Sie die Zeitzone verwenden, um das Land zu ermitteln. Für Länder wie Indien funktioniert diese Methode

beispielcode zur Überprüfung des Landes ist Indien oder nicht (Zeitzonen-ID: asia/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;

    }
}
2
MarGin

Wenn Sie GPS mit Längen- und Breitengrad verwenden, können Sie den Ländercode erhalten.

Wenn wir die Telefonie verwenden, funktioniert es nicht, wenn wir keine SIM-Karte verwenden. In der Ländereinstellung wird je nach Sprache der Ländercode falsch angezeigt.

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: Verwenden Sie Fused Location Provider , um die Breiten- und Längenänderungen für ein besseres Ergebnis zu erhalten.

1
Stephen

Ich habe GEOIP db verwendet und eine Funktion erstellt. Sie können diesen Link direkt verwenden 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"}]}

sie können autoload.php und .mmdb-Datei von https://dev.maxmind.com/geoip/geoip2/geolite2/ .__ herunterladen.

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
?>
0
arun-r