1.直接利用三方API获取:
1.1 利用bilibili的api 【未知稳定性】
public void Awake() { StartCoroutine(GetLocationInfoNew()); } /// <summary> /// 利用bilibili的接口通过ip直接获取城市信息 /// </summary> IEnumerator GetLocationInfoNew() { //UnityWebRequest publicIpReq = UnityWebRequest.Get(@"https://api.live.bilibili.com/client/v1/Ip/getInfoNew"); var publicIpReq = new UnityWebRequest("https://api.live.bilibili.com/client/v1/Ip/getInfoNew", UnityWebRequest.kHttpVerbGET); publicIpReq.downloadHandler = new DownloadHandlerBuffer(); yield return publicIpReq.SendWebRequest(); if (!string.IsNullOrEmpty(publicIpReq.error)) { Debug.Log($"获取城市信息失败:{publicIpReq.error}"); yield break; } var info = publicIpReq.downloadHandler.text; Debug.Log(info); //将json解析为object var resData = JsonUtility.FromJson<ResponseRootData>(info); Debug.Log($"address:{resData.data.addr}|province:{resData.data.province}|city:{resData.data.city}"); } #region 用于接收返回值json的反序列化数据 [System.Serializable] public class ResponseRootData { public int code; public string message; public ResponseData data; } [System.Serializable] public class ResponseData { public string addr; public string country; public string province; public string city; public string isp; public string latitude; public string longitude; } #endregion
1.2 利用baidu api 【配额超限,需要扩充配额,需要联系官方】
string url = "http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll"; void Start() { StartCoroutine(Request()); } IEnumerator Request() { WWW www = new WWW(url); yield return www; if (string.IsNullOrEmpty(www.error)) { //TODO:结果为:{"status":302,"message":"天配额超限,限制访问"} , Debug.Log(www.text); ResponseBody req = JsonConvert.DeserializeObject<ResponseBody>(www.text); if (req.content != null) { Debug.Log(req.content.address_detail.city + " X: " + req.content.point.x + " Y: " + req.content.point.x); } } else { Debug.Log(www.error); } } public class ResponseBody { public string address; public Content content; public int status; } public class Content { public string address; public Address_Detail address_detail; public Point point; } public class Address_Detail { public string city; public int city_code; public string district; public string province; public string street; public string street_number; public Address_Detail(string city, int city_code, string district, string province, string street, string street_number) { this.city = city; this.city_code = city_code; this.district = district; this.province = province; this.street = street; this.street_number = street_number; } } public class Point { public string x; public string y; public Point(string x, string y) { this.x = x; this.y = y; } }
2.获取IP地址,根据IP位置映射表计算地理位置
2.1 API: "https://api.ipify.org" 和 心知天气官网“心知天气 - 高精度气象数据 - 天气数据API接口 - 行业气象解决方案”
获取公网IP
//ipv6:http://icanhazip.com //ipv4:https://api.ipify.org (推荐用ipv4,ipv6返回的results里面的[]可能为空) IEnumerator GetPublicIP() { var ipv4Api = @"https://api.ipify.org"; UnityWebRequest publicIpReq = UnityWebRequest.Get(ipv4Api); yield return publicIpReq.SendWebRequest(); if (!string.IsNullOrEmpty(publicIpReq.error)) { Debug.Log($"查询公网ip报错:{publicIpReq.error}"); yield break; } Debug.Log("公网ip:" + publicIpReq.downloadHandler.text); }
根据IP获取地理信息和天气信息,json反解析的数据结构自行定义
IEnumerator GetWeatherInfos() { var ipv4Api = @"https://api.ipify.org"; UnityWebRequest publicIpReq = UnityWebRequest.Get(ipv4Api); yield return publicIpReq.SendWebRequest(); if (!string.IsNullOrEmpty(publicIpReq.error)) { Debug.Log($"查询公网ip报错:{publicIpReq.error}"); yield break; } //"https://www.seniverse.com/" var privateKey = "去心知天气官网购买免费版把私钥填写在这里~"; string cityUri = "https://api.seniverse.com/v3/location/search.json?key=" + privateKey + "&q=" + publicIpReq.downloadHandler.text; UnityWebRequest cityReq = UnityWebRequest.Get(cityUri); yield return cityReq.SendWebRequest(); if (!string.IsNullOrEmpty(cityReq.error)) { Debug.Log($"根据公网ip得到城市信息报错:{publicIpReq.error}"); yield break; } Debug.Log(cityReq.downloadHandler.text); //城市信息范例: // { // "results": [{ // "id": "WT3Q0FW9ZJ3Q", // "name": "武汉", // "country": "CN", // "path": "武汉,武汉,湖北,中国", // "timezone": "Asia/Shanghai", // "timezone_offset": "+08:00" // }] // } JSONNode cityDataNode = JSON.Parse(cityReq.downloadHandler.text); string cityId = cityDataNode["results"][0]["id"]; string weatherUri = "https://api.seniverse.com/v3/weather/now.json?key=" + privateKey + "&location=" + cityId + "&language=zh-Hans&unit=c"; UnityWebRequest weatherReq = UnityWebRequest.Get(weatherUri); yield return weatherReq.SendWebRequest(); if (!string.IsNullOrEmpty(weatherReq.error)) { Debug.Log($"获取城市天气信息报错:{weatherReq.error}"); yield break; } // 天气信息范例: // { // "results": [{ // "location": { // "id": "WT3Q0FW9ZJ3Q", // "name": "武汉", // "country": "CN", // "path": "武汉,武汉,湖北,中国", // "timezone": "Asia/Shanghai", // "timezone_offset": "+08:00" // }, // "now": { // "text": "晴", // "code": "0", // "temperature": "35" // }, // "last_update": "2022-08-17T11:20:04+08:00" // }] // } JSONNode weatherDataNode = JSON.Parse(weatherReq.downloadHandler.text); cityNameText.text = weatherDataNode["results"][0]["location"]["name"]; cityTemperatureText.text = weatherDataNode["results"][0]["now"]["temperature"] + "°"; }
2.2 API:"http://icanhazip.com/"
void Start() { GetInIp(); StartCoroutine(GetOutIp()); } /// <summary> /// 获取本机的内网ip地址 /// </summary> public void GetInIp() { var ip = ""; IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); for (int i = 0; i < ips.Length; i++) { IPAddress address = ips[i]; if (address.AddressFamily == AddressFamily.InterNetwork) { ip = address.ToString();//返回ipv4的地址的字符串 } //else if (address.AddressFamily == AddressFamily.InterNetworkV6) //{ // return address.ToString();//返回ipv6的地址的字符串 //} } //找不到就返回本地 ip = "127.0.0.1"; Debug.Log("in ip:" + ip); } /// <summary> /// 借助第三方库获取本机的外网ip地址 /// ip查询库:http://icanhazip.com/ /// pv4: http://ipv4.icanhazip.com/ /// ipv6: http://ipv6.icanhazip.com/ /// </summary> IEnumerator GetOutIp() { var ipApi = @"http://icanhazip.com/"; ipApi = "http://ipv4.icanhazip.com/"; UnityWebRequest request = UnityWebRequest.Get(ipApi); yield return request.SendWebRequest(); //if (request.isHttpError || request.isNetworkError) { // Debug.LogError(request.error); // yield break; //} if (request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.ConnectionError) { Debug.LogError(request.error); yield break; } var ip = request.downloadHandler.text; Debug.Log("out ip:" + ip); }