安卓获取设备国家代码

8

我希望获取设备的国家代码,而不使用sim卡。

例如:如果国家是斯里兰卡,则国家代码为LK。

我的最终目标是获取拨打代码(斯里兰卡为+94)。

我尝试使用以下方法:

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

但是这返回一个空字符串。

1
使用这些可能对您有帮助:--TelephonyManager.getNetworkCountryIso() - Ravindra Kushwaha
以下链接可能会对您有所帮助:https://dev59.com/yG035IYBdhLWcg3weP3f - Damodhar
看一下这个:https://dev59.com/dWct5IYBdhLWcg3wuPu6#11872569 - camelCaseCoder
我尝试使用tm.getNetworkCountryIso(); 但它返回空字符串。因为我的设备没有SIM卡,只有WiFi。 - ayesh don
您可以使用此链接 http://maps.googleapis.com/maps/api/geocode/json?latlng=7.0000,81.0000&sensor=false 获取国家代码。短名称将提供给您国家代码。但是,您需要获取当前的纬度和经度。 - Sunil Sunny
5个回答

4
它返回一个空字符串,因为设备没有sim卡。您可以尝试使用设备的当前语言环境: 参考此链接
Locale current = getResources().getConfiguration().locale;

但这并不一定与查看运营商iso得到的结果相同,用户可以在设置中随时更新到任何他们想要的内容。正如所指出的那样,您还可以向位置管理器请求用户的坐标。但请记住,用户会移动,他们当前的位置可能并不总是对应其运营商的iso


1
谢谢朋友。我也尝试了这个,但它总是返回"US"。 - ayesh don
1
@ayeshdon,那是因为该地区设置为美国。我再强调一遍,没有SIM卡是无法获取运营商的“iso”信息的。 - dcow
1
这将返回用户配置的Locale的国家/地区。如果用户将设备配置为印度,然后搭乘飞机前往德国,您仍将获得印度的国家代码。只是想澄清一下。 - Sunil Sunny

4

以下是一个完整的例子。尝试从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请求,或使用精确定位

为了获取国家前缀,您可以使用Google的LibPhoneNumber库。

参考资料在这里在这里


0

您可以使用此http://maps.googleapis.com/maps/api/geocode/json?latlng=7.0000,81.0000&sensor=false来获取国家代码。缩写将为您提供国家代码。

 public void getAddress(double lat,double lng) {
    Address1 = "";
    Address2 = "";
    City = "";
    State = "";
    Country = "";
    County = "";
    PIN = "";

    try {

        JSONObject jsonObj = JsonParser.getJSONfromURL("http://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + ","
                +lng + "&sensor=false");
        String Status = jsonObj.getString("status");
        if (Status.equalsIgnoreCase("OK")) {
            JSONArray Results = jsonObj.getJSONArray("results");
            JSONObject zero = Results.getJSONObject(0);
            JSONArray address_components = zero.getJSONArray("address_components");

            for (int i = 0; i < address_components.length(); i++) {
                JSONObject zero2 = address_components.getJSONObject(i);
                String long_name = zero2.getString("long_name");
                String short_name = zero2.getString("short_name");
                JSONArray mtypes = zero2.getJSONArray("types");
                String Type = mtypes.getString(0);

                if (TextUtils.isEmpty(long_name) == false || !long_name.equals(null) || long_name.length() > 0 || long_name != "") {
                    if (Type.equalsIgnoreCase("street_number")) {
                        Address1 = long_name + " ";
                    } else if (Type.equalsIgnoreCase("route")) {
                        Address1 = Address1 + long_name;
                    } else if (Type.equalsIgnoreCase("sublocality")) {
                        Address2 = long_name;
                    } else if (Type.equalsIgnoreCase("locality")) {
                        // Address2 = Address2 + long_name + ", ";
                        City = long_name;
                    } else if (Type.equalsIgnoreCase("administrative_area_level_2")) {
                        County = long_name;
                    } else if (Type.equalsIgnoreCase("administrative_area_level_1")) {
                        State = long_name;
                    } else if (Type.equalsIgnoreCase("country")) {
                        Country = short_name;
                    } else if (Type.equalsIgnoreCase("postal_code")) {
                        PIN = long_name;
                    }
                }

                // JSONArray mtypes = zero2.getJSONArray("types");
                // String Type = mtypes.getString(0);
                // Log.e(Type,long_name);
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

}

但是你需要获取当前的纬度和经度..

使用此链接获取当前的纬度和经度

http://gabesechansoftware.com/location-tracking/


如果我不在我的运营商所在的国家怎么办? - dcow
他要求获取设备的国家代码,但不能使用sim卡,我想这是唯一的选择。如果用户的运营商国家和当前国家不同,那么这种方法就行不通了,你说得对。 - Sunil Sunny
在那时和现在之间,Google进行了更改,要求在URL中添加API KEY。如果在末尾添加,它将类似于&key=... - Jesse Chisholm

0
在我的情况下,telephonyManager.getNetworkCountryIso() 返回为空,因为我有两个 SIM 卡插槽,如果它返回 "",你可以将插槽作为参数传递。只需更改您的代码如下:
 String iso=telephonyManager.getNetworkCountryIso();
       if(TextUtils.isEmpty(iso))
           iso=telephonyManager.getNetworkCountryIso(1);
       if(TextUtils.isEmpty(iso))
           iso=telephonyManager.getNetworkCountryIso(2);

// this code will give preference to Sim Slot 1

-6

2
请在试图提供答案之前充分理解问题。 - MarkZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接