Android手机实际上确实知道它在哪里 - 但有没有办法通过国家代码或国家/地区名称来检索国家/地区?
无需知道确切的GPS位置 - 国家代码或名称就足够了, 我正在使用这个代码:
String locale = context.getResources().getConfiguration().locale.getCountry(Locale.getDefault());
System.out.println("country = "+locale);
但它给了我代码“US”
但我的设备留在了印度;
有没有办法找到设备当前国家代码而不使用GPS或网络提供商。
因为我正在使用平板电脑
在此先感谢。
答案 0 :(得分:72)
你不应该将任何内容传递给getCountry()
,删除Locale.getDefault()
String locale = context.getResources().getConfiguration().locale.getCountry();
答案 1 :(得分:60)
您只需使用此代码
即可TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String countryCodeValue = tm.getNetworkCountryIso();
这将返回美国'如果您当前连接的网络是美国。这甚至没有SIM卡。希望这能解决你的问题。
答案 2 :(得分:42)
使用此链接http://ip-api.com/json,这将以json的形式提供所有信息。从这个json你可以很容易地到达这个国家。此站点使用您当前的IP工作,它会自动检测IP和发送回复的详细信息。
文档http://ip-api.com/docs/api:json希望它有所帮助。
这就是我得到的。
{
"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。 - 由于这是第三方API,请不要将其用作主要解决方案。而且还不确定它是否是免费的。
答案 3 :(得分:8)
已检查的答案已弃用代码。你需要实现这个:
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();
}
答案 4 :(得分:4)
如果您希望在不征得任何许可的情况下获取国家/地区代码,则可以选择一种棘手的方法。
该方法仅使用API来获取国家/地区代码,并且没有任何依赖的第三方库。我们可以为我们创建一个。
这里我用Google Cloud Functions编写了一个API,它很轻松。
第1步:创建一个Google Cloud帐户,然后设置结算(免费套餐就足够了)
第2步:创建云功能以获取地理位置
将此基本功能复制到 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);
});
};
我们还需要复制 package.json 定义:
{
"name": "gfc-geolocation",
"version": "0.0.1",
"dependencies": {
"cors": "^2.8.4"
}
}
第3步:完成操作,并获得类似于"https://us-central1-geolocation-mods-sdde.cloudfunctions.net/geolocation"
第4步:解析JSON响应并获取国家/地区代码
响应如下:
{
"country": "IN",
"region": "kl",
"city": "kochi",
"cityLatLong": "9.9312,76.2673",
"userIP": "xx.xx.xx.xx"
}
感谢和感谢,敬请访问Medium文章:Free IP-based Geolocation with Google Cloud Functions
答案 5 :(得分:2)
我创建了一个实用程序功能(在我根据语言环境获取不正确的国家代码的设备上进行了一次测试)。希望对您有所帮助。 参考: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
}
答案 6 :(得分:2)
对于某些设备,如果将默认语言设置为其他语言(印度人可以设置英语(美国)),则
SELECT c.balance +
(
SELECT SUM(CASE WHEN movementType = 'payment' THEN - import
WHEN movementType = 'refund' THEN import
ELSE 0 END)
FROM balance_Movements bb
WHERE bb.id <= b.id and b.clientid = bb.clientid
) Total
FROM client c
JOIN balance_Movements b on c.id = b.clientid
将给出错误的值。因此此方法不可靠
此外,TelephonyManager的getNetworkCountryIso()方法在没有SIM卡(WIFI平板电脑)的设备上不起作用。
如果设备没有SIM卡,那么我们可以使用时区获取国家/地区。对于印度这样的国家/地区,这种方法将有效
用于检查国家/地区为印度的示例代码 (时区ID:亚洲/ Calcutta)
context.getResources().getConfiguration().locale.getDisplayCountry();
答案 7 :(得分:1)
这是一个完整的示例。尝试从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;
}
另一个想法是尝试使用answer中的API请求。
答案 8 :(得分:0)
无需调用任何api。您只需使用此功能,即可从设备所在的国家/地区获取国家/地区代码
render() {
return <>
{this.state.items.map(el => (
<div
key={el.id}
onClick={() => this.handleToggle(el.id)}
className={el.expanded ? "faq__columns--item--active faq__columns--item" : "faq__columns--item"}
>
<div className="faq__content">
<p className="mb-0">{el.answer}</p>
{el.email ? <div>show link</div> : <div>no link</div>}
</div>
</div>
));}
</>
}
答案 9 :(得分:0)
获取国家代码
<uses-permission android:name="android.permission.INTERNET" />
public String makeServiceCall() {
String response = null;
String reqUrl = "https://ipinfo.io/country";
try {
URL url = new URL(reqUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// read the response
InputStream in = new BufferedInputStream(conn.getInputStream());
response = convertStreamToString(in);
} catch (MalformedURLException e) {
Log.e(TAG, "MalformedURLException: " + e.getMessage());
} catch (ProtocolException e) {
Log.e(TAG, "ProtocolException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
return response;
}
答案 10 :(得分:-3)
不确定是否仍在搜索解决方案,但这是我的:
private void getCountryCode(final Location location) {
Helper.log(TAG, "getCountryCode");
AsyncTask<Void, Void, String> countryCodeTask = new AsyncTask<Void, Void, String>() {
final float latitude = (float) location.getLatitude();
final float longitude = (float) location.getLongitude();
// Helper.log(TAG, "latitude: " +latitude);
List<Address> addresses = null;
Geocoder gcd = new Geocoder(mContext);
String code = null;
@Override
protected String doInBackground(Void... params) {
try {
addresses = gcd.getFromLocation(latitude, longitude, 1);
code = addresses.get(0).getCountryCode();
} catch (IOException e) {
e.printStackTrace();
}
return code;
}
@Override
protected void onPostExecute(String code) {
Helper.log(TAG, "onPostExecute");
mCountryCodeListener.returnCountryCode(code);
}
};
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
countryCodeTask.execute();
} else {
countryCodeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}