精华内容
下载资源
问答
  • 当用户单击城市名称或输入城市名称时,他们会看到当前的天气状况以及5天气预报。 链接 挑战性 正在为UV索引创建颜色值,以及更便于用户使用的日期显示。 未来功能 根据低湿度,高温和大风向城市添加火灾危险...
  • 这将是一个网站,显示给定城市的五天天气预报。 有一个按钮将清除本地存储。 当您单击按钮时,下次单击重新加载按钮时,将不会加载新城市,并且屏幕将重置。 如果您单击浏览器的“重新加载”按钮,则仍会显示上次...
  • 稳定高效的天气API接口是很少有的,本站前一段时间开发了一个万年历,需要带天气预报,花了几功夫,集成和容错处理好对外开放的天气接口。天气接口支持返回 JSON 和 XML 结果。并且可以获取到昨天,以及今天和未来...

    序言

    稳定高效的天气API接口是很少有的,本站前一段时间开发了一个万年历,需要带天气预报,花了几天功夫,集成和容错处理好对外开放的天气接口。天气接口支持返回 JSON 和 XML 结果。并且可以获取到昨天,以及今天和未来4 天的天气预报。那么下面直接介绍天气预报的接口吧。

    天气API详情介绍 在 API 中心:http://www.sojson.com/api/weather.html ,下面只介绍下调用方式,然后 用 Java 语言调用演示一下。
    天气接口答疑
    1、接口能不能 ajax jsonp 的方式调用?

    答:不能,必须后端语言,或者移动端语言调用,比如 Java 、PHP、C#,PY等,或者 Android,iOS 之类。
    2、接口每天的更新时间是什么时候?

    答:这个接口每天更新一次,时间大概是在凌晨的1~4点这样子。有的时候也有意外情况。
    3、接口稳定吗?

    答:应该,也许、如果的话,是稳定的。如果不明白的话,你摸着良心觉得您问的是不是废话。
    4、天气有哪些状态?天气图片哪里获取?

    答:这里有所有状态列表,并且所有状态矢量图都是有的,加群,需要付费5元,QQ 群:259217951,进去后回复“天气图片”,群机器人会告诉你的。如果 QQ 钱包没钱,请去 赞助链接 微信或者支付扫码支付5元,联系群主加入。
    5、提示超过2000次是什么意思?

    答:这个天气接口每天就更新一次,请你自己做缓存,一天可以请求2000次完全够了,多次提示超过2000,就会封 IP 段。
    6、提示有恶意调用是什么意思?

    答:因为你一直循环调用,没有做缓存,对服务器造成了很大的压力,请参照第五点。
    7、我没有使用2000次,为什么提示超过2000次?

    答:因为是采用 IP 段检测,假如你的 IP 是200.148.88.99,那么对于的 IP 段就是200.148.88.* ,也就是这个IP 段下使用的资源是共享的。另外也可能是 CDN 缓存,刷新即可。
    7、请求返回状态301?

    答:请采用 HTTPS 请求,下面有对应的代码,如果是是 Java 请参考下面的代码,如果是其他语言,请自行百度“语言 + HTTPS”相关关键词。
    9、能不能一次性返回多个城市?一次性返回一个组合?能不能一次性返回7天、15天天气?能不能及时更新?能不能不限制3秒一次?能不能… … ?

    答:能!!!不过是收费。

    PS:不要对我要求过多,我对你保证不了什么。理论上你不付费,我不能给你提供什么承诺。都是要成本的。虽说现在接口很稳定。但是我还是不会提供保证。另外,接口不是我求着你用,你爱用不用。虽然你使用本站,是我的上帝,但是技术面前,都是平等的,别一副高高在上的口吻和我说话。谢谢。
    API最新消息

    使用此接口的同学,请务必加QQ群(608222884)【免费的】,最近的变动会在群里提醒并通知。

    最近 API 会变化,目前 API 从免费开放以来到现在,还是很稳定,最高一天达到1.4亿次调用,响应成功率达到98%。还是很赞的。
    目前我新购置了集群服务器,把 API 独立出去,涉及到的变化,域名从(www.sojson.com)改成了(api.sojson.com),支持 HTTPS 调用,字段稍微有变化,另外开放了及时天气和15天天气详细数据,不过是收费的,毕竟我也需要维护成本,不过比聚合API肯定便宜。

    接口为什么最近有缓存

    因为免费接口触及到了部分商家的奶酪,接口基本每天都会被攻击。 下面是被攻击的截图。不得已开启缓存模式,另外,好消息是新的接口,这些问题都没有,不会有缓存,因为每个人的接口 URL 地址都是不一样的。

    部分 CC 攻击识别是接口调用太频繁造成的,你说你们的对我的伤害基本是爆击。
    天气接口免费额度

    1.每天每个IP段拥有2000次免费额度,每次请求间隔为3秒一次,如果没有间隔3秒去请求,永远都不会通过,因为每次请求都是重新计时。

    2.请求频繁或者日请求量过大,会直接停封,比如秒并发达到100,比如日请求到达几万,服务器会自动屏蔽。也是禁用IP段。
    天气接口调用注意事项

    忠告:别把免费资源不当资源,能不能自己稍微做下缓存,或者全局变量方式缓存,要这样的用量,90%以上是无用的请求,那我怎么坚持下去?敬请理解,如果确实需要这么大的量,先联系,说清楚。

    天气预报 API 接口 JSON返回

    public static void json() throws Exception{
    //参数url化
    String city = java.net.URLEncoder.encode("北京", "utf-8");
    //拼地址
    String apiUrl = String.format("https://www.sojson.com/open/api/weather/json.shtml?city=%s",city);
    //开始请求
    URL url= new URL(apiUrl);
    URLConnection open = url.openConnection();
    InputStream input = open.getInputStream();
    //这里转换为String,带上包名,怕你们引错包
    String result = org.apache.commons.io.IOUtils.toString(input,"utf-8");
    //输出
    System.out.println(result);
    }
    

    如果 HTTPS 报错,Java请参考:https://www.sojson.com/blog/195.html,如果其他语言,请自行百度“语言 + HTTPS”相关关键词。
    天气预报 JSON 返回值:

    {
    "data": {
    "yesterday": {
    "date": "26日星期五",
    "high": "高温 31℃",
    "fx": "南风",
    "low": "低温 17℃",
    "fl": "微风",
    "type": "晴"
    },
    "city": "北京",
    "aqi": "83",
    "forecast": [
    {
    "date": "27日星期六",
    "high": "高温 34℃",
    "fengli": "微风级",
    "low": "低温 21℃",
    "fengxiang": "西南风",
    "type": "晴"
    },
    {
    "date": "28日星期天",
    "high": "高温 36℃",
    "fengli": "3-4级",
    "low": "低温 22℃",
    "fengxiang": "北风",
    "type": "多云"
    },
    {
    "date": "29日星期一",
    "high": "高温 29℃",
    "fengli": "微风级",
    "low": "低温 18℃",
    "fengxiang": "东风",
    "type": "阴"
    },
    {
    "date": "30日星期二",
    "high": "高温 30℃",
    "fengli": "微风级",
    "low": "低温 18℃",
    "fengxiang": "南风",
    "type": "阴"
    },
    {
    "date": "31日星期三",
    "high": "高温 32℃",
    "fengli": "3-4级",
    "low": "低温 20℃",
    "fengxiang": "南风",
    "type": "多云"
    }
    ],
    "ganmao": "各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。",
    "wendu": "27"
    },
    "status": 200,
    "message": "OK"
    }
    

    天气预报 API XML返回方式

    public static void xml() throws Exception{
    //参数url化
    String city = java.net.URLEncoder.encode("北京", "utf-8");
    //拼地址
    String apiUrl = String.format("https://www.sojson.com/open/api/weather/xml.shtml?city=%s",city);
    //开始请求
    URL url= new URL(apiUrl);
    URLConnection open = url.openConnection();
    InputStream input = open.getInputStream();
    //这里转换为String,带上包名,怕你们引错包
    String result = org.apache.commons.io.IOUtils.toString(input,"utf-8");
    //输出
    System.out.println(result);
    }
    

    如果 HTTPS 报错,Java请参考:https://www.sojson.com/blog/195.html,如果其他语言,请自行百度“语言 + HTTPS”相关关键词。
    天气预报 XML返回值:

    <?xml version="1.0" encoding="UTF-8"?>
    <resp>
    <city>北京</city>
    <updatetime>13:45</updatetime>
    <wendu>27</wendu>
    <fengli>3级</fengli>
    <shidu>38%</shidu>
    <fengxiang>东风</fengxiang>
    <sunrise_1>04:51</sunrise_1>
    <sunset_1>19:33</sunset_1>
    <sunrise_2></sunrise_2>
    <sunset_2></sunset_2>
    <environment>
    <aqi>83</aqi>
    <pm25>61</pm25>
    <suggest>极少数敏感人群应减少户外活动</suggest>
    <quality>良</quality>
    <MajorPollutants>颗粒物(PM2.5)</MajorPollutants>
    <o3>148</o3>
    <co>1</co>
    <pm10>106</pm10>
    <so2>27</so2>
    <no2>47</no2>
    <time>13:00:00</time>
    </environment>
    <yesterday>
    <date_1>26日星期五</date_1>
    <high_1>高温 31℃</high_1>
    <low_1>低温 17℃</low_1>
    <day_1>
    <type_1>晴</type_1>
    <fx_1>南风</fx_1>
    <fl_1>微风</fl_1>
    </day_1>
    <night_1>
    <type_1>晴</type_1>
    <fx_1>北风</fx_1>
    <fl_1>微风</fl_1>
    </night_1>
    </yesterday>
    <forecast>
    <weather>
    <date>27日星期六</date>
    <high>高温 34℃</high>
    <low>低温 21℃</low>
    <day>
    <type>晴</type>
    <fengxiang>西南风</fengxiang>
    <fengli>微风级</fengli>
    </day>
    <night>
    <type>晴</type>
    <fengxiang>北风</fengxiang>
    <fengli>微风级</fengli>
    </night>
    </weather>
    <weather>
    <date>28日星期天</date>
    <high>高温 36℃</high>
    <low>低温 22℃</low>
    <day>
    <type>多云</type>
    <fengxiang>北风</fengxiang>
    <fengli>3-4级</fengli>
    </day>
    <night>
    <type>阴</type>
    <fengxiang>东北风</fengxiang>
    <fengli>微风级</fengli>
    </night>
    </weather>
    <weather>
    <date>29日星期一</date>
    <high>高温 29℃</high>
    <low>低温 18℃</low>
    <day>
    <type>阴</type>
    <fengxiang>东风</fengxiang>
    <fengli>微风级</fengli>
    </day>
    <night>
    <type>阵雨</type>
    <fengxiang>南风</fengxiang>
    <fengli>微风级</fengli>
    </night>
    </weather>
    <weather>
    <date>30日星期二</date>
    <high>高温 30℃</high>
    <low>低温 18℃</low>
    <day>
    <type>阴</type>
    <fengxiang>南风</fengxiang>
    <fengli>微风级</fengli>
    </day>
    <night>
    <type>多云</type>
    <fengxiang>北风</fengxiang>
    <fengli>微风级</fengli>
    </night>
    </weather>
    <weather>
    <date>31日星期三</date>
    <high>高温 32℃</high>
    <low>低温 20℃</low>
    <day>
    <type>多云</type>
    <fengxiang>南风</fengxiang>
    <fengli>3-4级</fengli>
    </day>
    <night>
    <type>多云</type>
    <fengxiang>南风</fengxiang>
    <fengli>3-4级</fengli>
    </night>
    </weather>
    </forecast>
    <zhishus>
    <zhishu>
    <name>晨练指数</name>
    <value>适宜</value>
    <detail>天气不错,空气清新,是您晨练的大好时机,建议不同年龄段的人们积极参加户外健身活动。</detail>
    </zhishu>
    <zhishu>
    <name>舒适度</name>
    <value>很不舒适</value>
    <detail>白天天气晴好,但烈日炎炎会使您会感到很热,很不舒适。</detail>
    </zhishu>
    <zhishu>
    <name>穿衣指数</name>
    <value>炎热</value>
    <detail>天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。</detail>
    </zhishu>
    <zhishu>
    <name>感冒指数</name>
    <value>少发</value>
    <detail>各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。</detail>
    </zhishu>
    <zhishu>
    <name>晾晒指数</name>
    <value>极适宜</value>
    <detail>天气不错,极适宜晾晒。抓紧时机把久未见阳光的衣物搬出来晒晒太阳吧!</detail>
    </zhishu>
    <zhishu>
    <name>旅游指数</name>
    <value>较适宜</value>
    <detail>天气较好,感觉有点热,不过有微风伴您一路同行,还是较适宜旅游的,外出请注意防晒哦!</detail>
    </zhishu>
    <zhishu>
    <name>紫外线强度</name>
    <value>很强</value>
    <detail>紫外线辐射极强,建议涂擦SPF20以上、PA++的防晒护肤品,尽量避免暴露于日光下。</detail>
    </zhishu>
    <zhishu>
    <name>洗车指数</name>
    <value>较适宜</value>
    <detail>较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。</detail>
    </zhishu>
    <zhishu>
    <name>运动指数</name>
    <value>较适宜</value>
    <detail>天气较好,户外运动请注意防晒。推荐您进行室内运动。</detail>
    </zhishu>
    <zhishu>
    <name>约会指数</name>
    <value>较不适宜</value>
    <detail>天气较热,建议尽量不要去室外约会,如果外出,请您挑选荫凉的地点。</detail>
    </zhishu>
    <zhishu>
    <name>雨伞指数</name>
    <value>不带伞</value>
    <detail>天气较好,您在出门的时候无须带雨伞。</detail>
    </zhishu>
    </zhishus>
    </resp>
    <!-- 10.10.162.42(10.10.162.42):38553 ; 10.10.156.163:8080 -->
    

    注意的一点就是,参数中文要转码。要url转码。 Java 如下:

    //参数url化
    String city = java.net.URLEncoder.encode("北京", "utf-8");
    

    还有一点就是,编码为UTF-8

    展开全文
  • 此程序集成了 根据IP显示天气预报 有三种调用格式,全面符合你的网页调用 搜索任意一个城市的 未来5天天气预报显示风力状况:污染指数:体感指数:中暑指数:穿衣指数:钓鱼指数:空气质量状况:防晒措施:舒适度...
  • 此程序集成了 根据IP显示天气预报 有三种调用格式,全面符合你的网页调用 搜索 任意一个城市的 未来5天天气预报 显示风力状况:污染指数:体感指数:中暑指数:穿衣指数:钓鱼指数:空气质量状况:...
  • 主要特点:实时显示最新气温,五天天气预报,托盘显示温度,可自定义背景图片和托盘温度图标 使用说明: 1、Vista不支持程序内置的单色托盘图标,需要托盘显示温度的话请使用外部图标 2、城市列表中没有的城市,请...
  • 天气预报是一个小型应用程序,可以显示用户输入的城市的今天和未来五天的天气状况。 目录 技术使用 jQuery,AJAX 关联 用法 在输入框中输入城市名称,然后按其旁边的搜索图标。 问题 有关项目的问题,请联系...
  • 天气预报 欢迎使用Weatherfor宝石! 该Gem的目的是向OpenWeatherAPI发出API请求,以查询气象数据以处理未来五天的平均温度。 安装 将此行添加到您的应用程序的Gemfile中: gem 'weatherfor' 然后执行: $ bundle...
  • 推荐个来自【万年历】的天气预报查询接口: http://wthrcdn.etouch.cn/weather_mini?city=北京;

    用Java的方式封装了一个天气的接口,查询了好多,要么是要收费的,要么需要使用官方的密匙Key。

    总不能项目上线了还要告诉运维记得换个key吧,想想就就得不现实。

    1、接口介绍

    所以,小编列举了几个网站,供大家使用,不需要key,完全免费,绝无后顾之忧:

    首先,当然是【国国家气象局】中天气预报提供的接口,总共三个:

    • http://www.weather.com.cn/data/sk/101010100.html;
    • http://www.weather.com.cn/data/cityinfo/101010100.html;
    • http://m.weather.com.cn/data/101010100.html;(已停用!!)

    注意:

    上面url中的“101010100”是城市代码,这里指代“北京”的城市代码。只需要改变城市代码,就可以得到所在城市的天气信息。其中,最详细的信息来自第三个接口,但是该接口已经停用了。

    第一个,第二个目前可用,但是查询的信息并不全,也不支持未来几天的天气预报等信息。

    但是,实际业务中我们有必要检索一个天气数据既全面,有支持未来几天预告的API。

    所以,再推荐几个来自【万年历】的天气预报查询接口,总结两个:

    • http://wthrcdn.etouch.cn/weather_mini?city=北京;
    • http://www.sojson.com/open/api/weather/json.shtml?city=北京;

    这两个接口还有一个明显的优势:不需要维护城市代码,可以使用城市名称进行天气查询,非常nice。

    第二个天气API详情介绍在 API 中心http://www.sojson.com/api/weather.html ,该接口经常发生变化,若无法访问请访问官网查看最新地址。

    所以,小编写一下【万年历】的第一个接口【wthrcdn.etouch.cn】的Demo:

    2、使用方法

    天气实体类:WeatherInfo

    public class WeatherInfo {
        private String date;        //时间
        private String week;        //星期
        private String lunar;       //农历时间
        private String cityname;    //城市名
        private String weather;     //天气
        private String temp;        //当前温度
        private String highTemp;    //最低温度
        private String lowTemp;     //当前温度
        private String tips;        //小提示
    
        ... (省略get,set,toString方法)
    
    }

    天气工具类:WeatherUtil

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.zip.GZIPInputStream;
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    
    /**
     * @author :tjm
     * 通过get请求向网站:http://wthrcdn.etouch.cn/weather_mini 获取某个 城市的天气状况数据,数据格式是Json
     * @date :Created in 2020/3/9 13:55
     *
     */
    public class WeatherUtils {
        private static String weatherUrl = "http://wthrcdn.etouch.cn/weather_mini?city=";
        /**
         * 通过城市名称获取该城市的天气信息
         */
        public static String GetWeatherData(String cityname) {
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = null;
            try {
                URL url = new URL(weatherUrl + cityname);
                URLConnection conn = url.openConnection();
                InputStream is = conn.getInputStream();
                GZIPInputStream gzin = new GZIPInputStream(is);
                // 设置读取流的编码格式,自定义编码
                InputStreamReader isr = new InputStreamReader(gzin, "utf-8");
                reader = new BufferedReader(isr);
                String line = null;
                while((line = reader.readLine()) != null){
                    sb.append(line + " ");
                }
                reader.close();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return sb.toString();
        }
    
        /**
         * 将JSON格式数据进行解析 ,返回一个weather对象
         */
        public static WeatherInfo GetWeather(String weatherInfobyJson){
            JSONObject dataOfJson = JSONObject.fromObject(weatherInfobyJson);   // json天气数据
            if(dataOfJson.getInt("status") != 1000){
                return null;
            }
            // 创建WeatherInfo对象,提取所需的天气信息
            WeatherInfo weatherInfo = new WeatherInfo();
            
            // 获取当前日期:日期、星期
            Calendar cal = Calendar.getInstance();    							     // Calendar类的实例化
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日");  // 时间的格式化
            weatherInfo.setDate(sdf1.format(cal.getTime()));                // 时间
            SimpleDateFormat sdf2 = new SimpleDateFormat("EEEE");
            weatherInfo.setWeek(sdf2.format(cal.getTime()));                // 星期
    
            // 从json数据中提取数据:城市、温度、小提醒
            dataOfJson = JSONObject.fromObject(dataOfJson.getString("data"));
            weatherInfo.setCityname(dataOfJson.getString("city"));            // 城市
            weatherInfo.setTemp(dataOfJson.getString("wendu"));               // 温度
            weatherInfo.setTips(dataOfJson.getString("ganmao"));              // 小提示
    
            // 获取今天的天气预报信息:最高温度、最低温度、天气
            JSONArray forecast = dataOfJson.getJSONArray("forecast");
            JSONObject result = forecast.getJSONObject(0);
            weatherInfo.setHighTemp(result.getString("high").substring(2));   // 最高气温
            weatherInfo.setLowTemp(result.getString("low").substring(2));     // 最低气温
            weatherInfo.setWeather(result.getString("type"));                 // 天气
    
            return weatherInfo;
        }
    
    }

    测试代码:test

    public class Test {
    
        public static void main(String[] args){
            String info = WeatherUtils.GetWeatherData("天津");
            System.out.println("1.预测结果:" + info);                    // 全部天气数据,含预测
            WeatherInfo weatherinfo = WeatherUtils.GetWeather(info);
            System.out.println("2.今天天气:" + weatherinfo.toString());  // 当天天气数据
        }
    
    }

    结果:

    1.预测结果:

    {
        "data": {
            "yesterday": {
                "date": "9日星期一",
                "high": "高温 8℃",
                "fx": "东北风",
                "low": "低温 1℃",
                "fl": "<![CDATA[4-5级]]>",
                "type": "小雨"
            },
            "city": "天津",
            "forecast": [
                {
                    "date": "10日星期二",
                    "high": "高温 13℃",
                    "fengli": "<![CDATA[4-5级]]>",
                    "low": "低温 3℃",
                    "fengxiang": "西北风",
                    "type": "晴"
                },
                {
                    "date": "11日星期三",
                    "high": "高温 16℃",
                    "fengli": "<![CDATA[4-5级]]>",
                    "low": "低温 4℃",
                    "fengxiang": "西南风",
                    "type": "晴"
                },
                {
                    "date": "12日星期四",
                    "high": "高温 16℃",
                    "fengli": "<![CDATA[4-5级]]>",
                    "low": "低温 2℃",
                    "fengxiang": "东北风",
                    "type": "多云"
                },
                {
                    "date": "13日星期五",
                    "high": "高温 8℃",
                    "fengli": "<![CDATA[3-4级]]>",
                    "low": "低温 0℃",
                    "fengxiang": "北风",
                    "type": "多云"
                },
                {
                    "date": "14日星期六",
                    "high": "高温 10℃",
                    "fengli": "<![CDATA[4-5级]]>",
                    "low": "低温 2℃",
                    "fengxiang": "西北风",
                    "type": "晴"
                }
            ],
            "ganmao": "天冷风大且昼夜温差也很大,易发生感冒,请注意适当增减衣服。",
            "wendu": "9"
        },
        "status": 1000,
        "desc": "OK"
    }

    2.今天天气:

    WeatherInfo{date='2020年03月10日', week=星期二, lunar='null', cityname='天津', weather='晴', temp='9', highTemp=' 13℃', lowTemp=' 3℃', tips='天冷风大且昼夜温差也很大,易发生感冒,请注意适当增减衣服。'}

    注意:

    • 预测结果:是该API获取的全部数据,包含昨天,今天,以及未来4天的天气情况;
    • 今天天气:是从预测结果JSON数据中取出来,封装成对象的数据,在data.forecast下的第一条记录中。

     

    更多精彩,请关注我的"今日头条号":Java云笔记
    随时随地,让你拥有最新,最便捷的掌上云服务

     

     

     

    展开全文
  • 1、接口介绍所以,小编列举了几个网站,供大家使用,不需要key,完全免费,绝无后顾之忧:首先,当然是【国国家气象局】中天气预报提供的接口,总共三个:http://www.weather.com.cn/data/sk/101010100.ht...

    用Java的方式封装了一个天气的接口,查询了好多,要么是要收费的,要么需要使用官方的密匙Key。

    总不能项目上线了还要告诉运维记得换个key吧,想想就就得不现实。

    1、接口介绍

    所以,小编列举了几个网站,供大家使用,不需要key,完全免费,绝无后顾之忧:

    首先,当然是【国国家气象局】中天气预报提供的接口,总共三个:

    http://www.weather.com.cn/data/sk/101010100.html;

    http://www.weather.com.cn/data/cityinfo/101010100.html;

    http://m.weather.com.cn/data/101010100.html;(已停用!!)

    注意:

    上面url中的“101010100”是城市代码,这里指代“北京”的城市代码。只需要改变城市代码,就可以得到所在城市的天气信息。其中,最详细的信息来自第三个接口,但是该接口已经停用了。

    第一个,第二个目前可用,但是查询的信息并不全,也不支持未来几天的天气预报等信息。

    但是,实际业务中我们有必要检索一个天气数据既全面,有支持未来几天预告的API。

    所以,再推荐几个来自【万年历】的天气预报查询接口,总结两个:

    http://wthrcdn.etouch.cn/weather_mini?city=北京;

    http://www.sojson.com/open/api/weather/json.shtml?city=北京;

    这两个接口还有一个明显的优势:不需要维护城市代码,可以使用城市名称进行天气查询,非常nice。

    第二个天气API详情介绍在 API 中心:http://www.sojson.com/api/weather.html ,该接口经常发生变化,若无法访问请访问官网查看最新地址。

    所以,小编写一下【万年历】的第一个接口【wthrcdn.etouch.cn】的Demo:

    2、使用方法

    天气实体类:WeatherInfo

    public class WeatherInfo {

    private String date; //时间

    private String week; //星期

    private String lunar; //农历时间

    private String cityname; //城市名

    private String weather; //天气

    private String temp; //当前温度

    private String highTemp; //最低温度

    private String lowTemp; //当前温度

    private String tips; //小提示

    ... (省略get,set,toString方法)

    }

    天气工具类:WeatherUtil

    import java.io.BufferedReader;

    import java.io.InputStream;

    import java.io.InputStreamReader;

    import java.io.UnsupportedEncodingException;

    import java.net.MalformedURLException;

    import java.net.URL;

    import java.net.URLConnection;

    import java.text.SimpleDateFormat;

    import java.util.Calendar;

    import java.util.zip.GZIPInputStream;

    import net.sf.json.JSONArray;

    import net.sf.json.JSONObject;

    /**

    * @author :tjm

    * 通过get请求向网站:http://wthrcdn.etouch.cn/weather_mini 获取某个 城市的天气状况数据,数据格式是Json

    * @date :Created in 2020/3/9 13:55

    *

    */

    public class WeatherUtils {

    private static String weatherUrl = "http://wthrcdn.etouch.cn/weather_mini?city=";

    /**

    * 通过城市名称获取该城市的天气信息

    */

    public static String GetWeatherData(String cityname) {

    StringBuilder sb = new StringBuilder();

    BufferedReader reader = null;

    try {

    URL url = new URL(weatherUrl + cityname);

    URLConnection conn = url.openConnection();

    InputStream is = conn.getInputStream();

    GZIPInputStream gzin = new GZIPInputStream(is);

    // 设置读取流的编码格式,自定义编码

    InputStreamReader isr = new InputStreamReader(gzin, "utf-8");

    reader = new BufferedReader(isr);

    String line = null;

    while((line = reader.readLine()) != null){

    sb.append(line + " ");

    }

    reader.close();

    } catch (UnsupportedEncodingException e) {

    e.printStackTrace();

    } catch (MalformedURLException e) {

    e.printStackTrace();

    } catch (Exception e) {

    e.printStackTrace();

    }

    return sb.toString();

    }

    /**

    * 将JSON格式数据进行解析 ,返回一个weather对象

    */

    public static WeatherInfo GetWeather(String weatherInfobyJson){

    JSONObject dataOfJson = JSONObject.fromObject(weatherInfobyJson); // json天气数据

    if(dataOfJson.getInt("status") != 1000){

    return null;

    }

    // 创建WeatherInfo对象,提取所需的天气信息

    WeatherInfo weatherInfo = new WeatherInfo();

    // 获取当前日期:日期、星期

    Calendar cal = Calendar.getInstance(); // Calendar类的实例化

    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日"); // 时间的格式化

    weatherInfo.setDate(sdf1.format(cal.getTime())); // 时间

    SimpleDateFormat sdf2 = new SimpleDateFormat("EEEE");

    weatherInfo.setWeek(sdf2.format(cal.getTime())); // 星期

    // 从json数据中提取数据:城市、温度、小提醒

    dataOfJson = JSONObject.fromObject(dataOfJson.getString("data"));

    weatherInfo.setCityname(dataOfJson.getString("city")); // 城市

    weatherInfo.setTemp(dataOfJson.getString("wendu")); // 温度

    weatherInfo.setTips(dataOfJson.getString("ganmao")); // 小提示

    // 获取今天的天气预报信息:最高温度、最低温度、天气

    JSONArray forecast = dataOfJson.getJSONArray("forecast");

    JSONObject result = forecast.getJSONObject(0);

    weatherInfo.setHighTemp(result.getString("high").substring(2)); // 最高气温

    weatherInfo.setLowTemp(result.getString("low").substring(2)); // 最低气温

    weatherInfo.setWeather(result.getString("type")); // 天气

    return weatherInfo;

    }

    }

    测试代码:test

    public class Test {

    public static void main(String[] args){

    String info = WeatherUtils.GetWeatherData("天津");

    System.out.println("1.预测结果:" + info); // 全部天气数据,含预测

    WeatherInfo weatherinfo = WeatherUtils.GetWeather(info);

    System.out.println("2.今天天气:" + weatherinfo.toString()); // 当天天气数据

    }

    }

    结果:

    1.预测结果:

    {

    "data": {

    "yesterday": {

    "date": "9日星期一",

    "high": "高温 8℃",

    "fx": "东北风",

    "low": "低温 1℃",

    "fl": "",

    "type": "小雨"

    },

    "city": "天津",

    "forecast": [

    {

    "date": "10日星期二",

    "high": "高温 13℃",

    "fengli": "",

    "low": "低温 3℃",

    "fengxiang": "西北风",

    "type": "晴"

    },

    {

    "date": "11日星期三",

    "high": "高温 16℃",

    "fengli": "",

    "low": "低温 4℃",

    "fengxiang": "西南风",

    "type": "晴"

    },

    {

    "date": "12日星期四",

    "high": "高温 16℃",

    "fengli": "",

    "low": "低温 2℃",

    "fengxiang": "东北风",

    "type": "多云"

    },

    {

    "date": "13日星期五",

    "high": "高温 8℃",

    "fengli": "",

    "low": "低温 0℃",

    "fengxiang": "北风",

    "type": "多云"

    },

    {

    "date": "14日星期六",

    "high": "高温 10℃",

    "fengli": "",

    "low": "低温 2℃",

    "fengxiang": "西北风",

    "type": "晴"

    }

    ],

    "ganmao": "天冷风大且昼夜温差也很大,易发生感冒,请注意适当增减衣服。",

    "wendu": "9"

    },

    "status": 1000,

    "desc": "OK"

    }

    2.今天天气:

    WeatherInfo{date='2020年03月10日', week=星期二, lunar='null', cityname='天津', weather='晴', temp='9', highTemp=' 13℃', lowTemp=' 3℃', tips='天冷风大且昼夜温差也很大,易发生感冒,请注意适当增减衣服。'}

    注意:

    预测结果:是该API获取的全部数据,包含昨天,今天,以及未来4天的天气情况;

    今天天气:是从预测结果JSON数据中取出来,封装成对象的数据,在data.forecast下的第一条记录中。

    更多精彩,请关注我的"今日头条号":Java云笔记

    随时随地,让你拥有最新,最便捷的掌上云服务

    展开全文
  • 本工具使用C#语言开发WinFrom软件,根据国家气象局天气预报接口获取未来十五天天气预报。只用来新手学习,里边主要涉及到Url请求,Json转List,Json转model。
  • 天气预报、生活指数的数据请求与渲染6....天气预报是预测未来几的天气,常用列表显示,实现这个功能的业务逻辑是:访问API、获取返回值、列表配置、数据渲染。首先是API接口。 ① 新增API接口 根据和风天气中的文...

    上一篇:Android 天气APP(四)搭建MVP框架与使用

    6. 天气预报

    天气预报是预测未来几天的天气,常用列表显示,实现这个功能的业务逻辑是:访问API、获取返回值、列表配置、数据渲染。首先是API接口。

    ① 新增API接口

    根据和风天气中的文档,得知未来3-7天的天气预报接口为:

    https://free-api.heweather.net/s6/weather/forecast?key=3086e91d66c04ce588a7f538f917c7f4&location=福田区
    

    在网页上访问得到返回值,生成一个实体
    在这里插入图片描述
    代码如下:

    package com.llw.goodweather.bean;
    
    import java.util.List;
    
    public class WeatherForecastResponse {
    
        private List<HeWeather6Bean> HeWeather6;
    
        public List<HeWeather6Bean> getHeWeather6() {
            return HeWeather6;
        }
    
        public void setHeWeather6(List<HeWeather6Bean> HeWeather6) {
            this.HeWeather6 = HeWeather6;
        }
    
        public static class HeWeather6Bean {
            /**
             * basic : {"cid":"CN101280603","location":"福田","parent_city":"深圳","admin_area":"广东","cnty":"中国","lat":"22.5410099","lon":"114.05095673","tz":"+8.00"}
             * update : {"loc":"2019-11-19 19:57","utc":"2019-11-19 11:57"}
             * status : ok
             * daily_forecast : [{"cond_code_d":"100","cond_code_n":"101","cond_txt_d":"晴","cond_txt_n":"多云","date":"2019-11-19","hum":"50","mr":"23:52","ms":"12:27","pcpn":"0.0","pop":"20","pres":"1012","sr":"06:39","ss":"17:38","tmp_max":"22","tmp_min":"16","uv_index":"5","vis":"25","wind_deg":"31","wind_dir":"东北风","wind_sc":"3-4","wind_spd":"17"},{"cond_code_d":"101","cond_code_n":"101","cond_txt_d":"多云","cond_txt_n":"多云","date":"2019-11-20","hum":"67","mr":"00:00","ms":"13:14","pcpn":"0.0","pop":"3","pres":"1011","sr":"06:40","ss":"17:38","tmp_max":"24","tmp_min":"16","uv_index":"4","vis":"25","wind_deg":"-1","wind_dir":"无持续风向","wind_sc":"1-2","wind_spd":"5"},{"cond_code_d":"101","cond_code_n":"101","cond_txt_d":"多云","cond_txt_n":"多云","date":"2019-11-21","hum":"73","mr":"00:54","ms":"13:57","pcpn":"0.0","pop":"2","pres":"1009","sr":"06:40","ss":"17:38","tmp_max":"26","tmp_min":"19","uv_index":"3","vis":"25","wind_deg":"-1","wind_dir":"无持续风向","wind_sc":"1-2","wind_spd":"2"}]
             */
    
            private BasicBean basic;
            private UpdateBean update;
            private String status;
            private List<DailyForecastBean> daily_forecast;
    
            public BasicBean getBasic() {
                return basic;
            }
    
            public void setBasic(BasicBean basic) {
                this.basic = basic;
            }
    
            public UpdateBean getUpdate() {
                return update;
            }
    
            public void setUpdate(UpdateBean update) {
                this.update = update;
            }
    
            public String getStatus() {
                return status;
            }
    
            public void setStatus(String status) {
                this.status = status;
            }
    
            public List<DailyForecastBean> getDaily_forecast() {
                return daily_forecast;
            }
    
            public void setDaily_forecast(List<DailyForecastBean> daily_forecast) {
                this.daily_forecast = daily_forecast;
            }
    
            public static class BasicBean {
                /**
                 * cid : CN101280603
                 * location : 福田
                 * parent_city : 深圳
                 * admin_area : 广东
                 * cnty : 中国
                 * lat : 22.5410099
                 * lon : 114.05095673
                 * tz : +8.00
                 */
    
                private String cid;
                private String location;
                private String parent_city;
                private String admin_area;
                private String cnty;
                private String lat;
                private String lon;
                private String tz;
    
                public String getCid() {
                    return cid;
                }
    
                public void setCid(String cid) {
                    this.cid = cid;
                }
    
                public String getLocation() {
                    return location;
                }
    
                public void setLocation(String location) {
                    this.location = location;
                }
    
                public String getParent_city() {
                    return parent_city;
                }
    
                public void setParent_city(String parent_city) {
                    this.parent_city = parent_city;
                }
    
                public String getAdmin_area() {
                    return admin_area;
                }
    
                public void setAdmin_area(String admin_area) {
                    this.admin_area = admin_area;
                }
    
                public String getCnty() {
                    return cnty;
                }
    
                public void setCnty(String cnty) {
                    this.cnty = cnty;
                }
    
                public String getLat() {
                    return lat;
                }
    
                public void setLat(String lat) {
                    this.lat = lat;
                }
    
                public String getLon() {
                    return lon;
                }
    
                public void setLon(String lon) {
                    this.lon = lon;
                }
    
                public String getTz() {
                    return tz;
                }
    
                public void setTz(String tz) {
                    this.tz = tz;
                }
            }
    
            public static class UpdateBean {
                /**
                 * loc : 2019-11-19 19:57
                 * utc : 2019-11-19 11:57
                 */
    
                private String loc;
                private String utc;
    
                public String getLoc() {
                    return loc;
                }
    
                public void setLoc(String loc) {
                    this.loc = loc;
                }
    
                public String getUtc() {
                    return utc;
                }
    
                public void setUtc(String utc) {
                    this.utc = utc;
                }
            }
    
            public static class DailyForecastBean {
                /**
                 * cond_code_d : 100
                 * cond_code_n : 101
                 * cond_txt_d : 晴
                 * cond_txt_n : 多云
                 * date : 2019-11-19
                 * hum : 50
                 * mr : 23:52
                 * ms : 12:27
                 * pcpn : 0.0
                 * pop : 20
                 * pres : 1012
                 * sr : 06:39
                 * ss : 17:38
                 * tmp_max : 22
                 * tmp_min : 16
                 * uv_index : 5
                 * vis : 25
                 * wind_deg : 31
                 * wind_dir : 东北风
                 * wind_sc : 3-4
                 * wind_spd : 17
                 */
    
                private String cond_code_d;
                private String cond_code_n;
                private String cond_txt_d;
                private String cond_txt_n;
                private String date;
                private String hum;
                private String mr;
                private String ms;
                private String pcpn;
                private String pop;
                private String pres;
                private String sr;
                private String ss;
                private String tmp_max;
                private String tmp_min;
                private String uv_index;
                private String vis;
                private String wind_deg;
                private String wind_dir;
                private String wind_sc;
                private String wind_spd;
    
                public String getCond_code_d() {
                    return cond_code_d;
                }
    
                public void setCond_code_d(String cond_code_d) {
                    this.cond_code_d = cond_code_d;
                }
    
                public String getCond_code_n() {
                    return cond_code_n;
                }
    
                public void setCond_code_n(String cond_code_n) {
                    this.cond_code_n = cond_code_n;
                }
    
                public String getCond_txt_d() {
                    return cond_txt_d;
                }
    
                public void setCond_txt_d(String cond_txt_d) {
                    this.cond_txt_d = cond_txt_d;
                }
    
                public String getCond_txt_n() {
                    return cond_txt_n;
                }
    
                public void setCond_txt_n(String cond_txt_n) {
                    this.cond_txt_n = cond_txt_n;
                }
    
                public String getDate() {
                    return date;
                }
    
                public void setDate(String date) {
                    this.date = date;
                }
    
                public String getHum() {
                    return hum;
                }
    
                public void setHum(String hum) {
                    this.hum = hum;
                }
    
                public String getMr() {
                    return mr;
                }
    
                public void setMr(String mr) {
                    this.mr = mr;
                }
    
                public String getMs() {
                    return ms;
                }
    
                public void setMs(String ms) {
                    this.ms = ms;
                }
    
                public String getPcpn() {
                    return pcpn;
                }
    
                public void setPcpn(String pcpn) {
                    this.pcpn = pcpn;
                }
    
                public String getPop() {
                    return pop;
                }
    
                public void setPop(String pop) {
                    this.pop = pop;
                }
    
                public String getPres() {
                    return pres;
                }
    
                public void setPres(String pres) {
                    this.pres = pres;
                }
    
                public String getSr() {
                    return sr;
                }
    
                public void setSr(String sr) {
                    this.sr = sr;
                }
    
                public String getSs() {
                    return ss;
                }
    
                public void setSs(String ss) {
                    this.ss = ss;
                }
    
                public String getTmp_max() {
                    return tmp_max;
                }
    
                public void setTmp_max(String tmp_max) {
                    this.tmp_max = tmp_max;
                }
    
                public String getTmp_min() {
                    return tmp_min;
                }
    
                public void setTmp_min(String tmp_min) {
                    this.tmp_min = tmp_min;
                }
    
                public String getUv_index() {
                    return uv_index;
                }
    
                public void setUv_index(String uv_index) {
                    this.uv_index = uv_index;
                }
    
                public String getVis() {
                    return vis;
                }
    
                public void setVis(String vis) {
                    this.vis = vis;
                }
    
                public String getWind_deg() {
                    return wind_deg;
                }
    
                public void setWind_deg(String wind_deg) {
                    this.wind_deg = wind_deg;
                }
    
                public String getWind_dir() {
                    return wind_dir;
                }
    
                public void setWind_dir(String wind_dir) {
                    this.wind_dir = wind_dir;
                }
    
                public String getWind_sc() {
                    return wind_sc;
                }
    
                public void setWind_sc(String wind_sc) {
                    this.wind_sc = wind_sc;
                }
    
                public String getWind_spd() {
                    return wind_spd;
                }
    
                public void setWind_spd(String wind_spd) {
                    this.wind_spd = wind_spd;
                }
            }
        }
    }
    
    

    接下来在ApiService中添加

    在这里插入图片描述
    代码如下:

    	/**
         * 未来3 - 7天天气预报
         */
        @GET("/s6/weather/forecast?key=3086e91d66c04ce588a7f538f917c7f4")
        Call<WeatherForecastResponse> getWeatherForecast(@Query("location") String location);
    

    ② 修改订阅器

    接下来修改订阅器WeatherContract

    在这里插入图片描述
    在这里插入图片描述
    WeatherContract代码如下:

    package com.llw.goodweather.contract;
    
    import android.content.Context;
    
    import com.llw.goodweather.api.ApiService;
    import com.llw.goodweather.bean.TodayResponse;
    import com.llw.goodweather.bean.WeatherForecastResponse;
    import com.llw.mvplibrary.base.BasePresenter;
    import com.llw.mvplibrary.base.BaseView;
    import com.llw.mvplibrary.net.NetCallBack;
    import com.llw.mvplibrary.net.ServiceGenerator;
    import retrofit2.Call;
    import retrofit2.Response;
    
    /**
     * 天气订阅器
     */
    public class WeatherContract {
    
        public static class WeatherPresenter extends BasePresenter<IWeatherView> {
            /**
             * 当日天气
             * @param context
             * @param location  区/县
             */
            public void todayWeather(final Context context, String location) {
                //得到构建之后的网络请求服务,这里的地址已经拼接完成,只差一个location了
                ApiService service = ServiceGenerator.createService(ApiService.class);
                //设置请求回调  NetCallBack是重写请求回调
                service.getTodayWeather(location).enqueue(new NetCallBack<TodayResponse>() {
                    //成功回调
                    @Override
                    public void onSuccess(Call<TodayResponse> call, Response<TodayResponse> response) {
                        if (getView() != null) {//当视图不会空时返回请求数据
                            getView().getTodayWeatherResult(response);
                        }
                    }
    
                    //失败回调
                    @Override
                    public void onFailed() {
                        if (getView() != null) {//当视图不会空时获取错误信息
                            getView().getDataFailed();
                        }
                    }
                });
            }
    
    
            /**
             * 天气预报  3-7天(白嫖的就只能看到3天)
             * @param context
             * @param location
             */
            public void weatherForecast(final Context context,String location){
                ApiService service = ServiceGenerator.createService(ApiService.class);
                service.getWeatherForecast(location).enqueue(new NetCallBack<WeatherForecastResponse>() {
                    @Override
                    public void onSuccess(Call<WeatherForecastResponse> call, Response<WeatherForecastResponse> response) {
                        if(getView() != null){
                            getView().getWeatherForecastResult(response);
                        }
                    }
    
                    @Override
                    public void onFailed() {
                        if(getView() != null){
                            getView().getDataFailed();
                        }
                    }
                });
            }
        }
    
    
        public interface IWeatherView extends BaseView {
            //查询当天天气的数据返回
            void getTodayWeatherResult(Response<TodayResponse> response);
            //查询天气预报的数据返回
            void getWeatherForecastResult(Response<WeatherForecastResponse> response);
            //错误返回
            void getDataFailed();
        }
    }
    
    

    接下来修改布局,增加列表和适配器

    ③ 修改布局,增加列表和适配器

    在这里插入图片描述
    代码中
    在这里插入图片描述
    这个时候你的MainActivity.java会报错
    在这里插入图片描述
    这是因为订阅器里面的内容没有写入。鼠标点击,Alt + Enter
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    接下来创建列表的item
    在layout目录下创建item_weather_forecast_list.xml文件

    在这里插入图片描述
    代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:padding="@dimen/sp_12"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <!--日期-->
            <TextView
                android:id="@+id/tv_date"
                android:text="1234"
                android:textSize="@dimen/sp_14"
                android:textColor="#FFF"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"/>
            <!--天气描述-->
            <TextView
                android:gravity="center"
                android:id="@+id/tv_info"
                android:textSize="@dimen/sp_14"
                android:textColor="#FFF"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"/>
    
            <!--最低温、最高温-->
            <TextView
                android:gravity="right"
                android:id="@+id/tv_low_and_height"
                android:textSize="@dimen/sp_14"
                android:textColor="#FFF"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"/>
        </LinearLayout>
    </LinearLayout>
    

    接下来创建一个适配器
    com.llw.goodweather下新建一个WeatherForecastAdapter适配器
    在这里插入图片描述
    代码如下:

    package com.llw.goodweather.adapter;
    
    import androidx.annotation.Nullable;
    
    import com.chad.library.adapter.base.BaseQuickAdapter;
    import com.chad.library.adapter.base.BaseViewHolder;
    import com.llw.goodweather.R;
    import com.llw.goodweather.bean.WeatherForecastResponse;
    
    import java.util.List;
    
    /**
     * 天气预报列表展示适配器
     */
    public class WeatherForecastAdapter extends BaseQuickAdapter<WeatherForecastResponse.HeWeather6Bean.DailyForecastBean, BaseViewHolder> {
    
        public WeatherForecastAdapter(int layoutResId, @Nullable List<WeatherForecastResponse.HeWeather6Bean.DailyForecastBean> data) {
            super(layoutResId, data);
        }
    
        @Override
        protected void convert(BaseViewHolder helper, WeatherForecastResponse.HeWeather6Bean.DailyForecastBean item) {
            helper.setText(R.id.tv_date, item.getDate())//日期
                    .setText(R.id.tv_info, item.getCond_txt_d())//天气
                    .setText(R.id.tv_low_and_height, item.getTmp_min() + "/" + item.getTmp_max() + "℃");//最低温和最高温
        }
    }
    
    

    ④ 使用适配器进行数据展示

    在MainActivity.java中增加

    
    	List<WeatherForecastResponse.HeWeather6Bean.DailyForecastBean> mList;//初始化数据源
        WeatherForecastAdapter mAdapter;//初始化适配器
    	/**
         * 初始化天气预报数据列表
         */
        private void initList() {
            mList = new ArrayList<>();//声明为ArrayList
            mAdapter = new WeatherForecastAdapter(R.layout.item_weather_forecast_list, mList);//为适配器设置布局和数据源
            LinearLayoutManager manager = new LinearLayoutManager(context);//布局管理,默认是纵向
            rv.setLayoutManager(manager);//为列表配置管理器
            rv.setAdapter(mAdapter);//为列表配置适配器
        }
    

    然后在**initData()**方法中调用
    在这里插入图片描述
    在这里插入图片描述

    返回值做处理

    	//查询天气预报,请求成功后的数据返回
        @Override
        public void getWeatherForecastResult(Response<WeatherForecastResponse> response) {
            if (("ok").equals(response.body().getHeWeather6().get(0).getStatus())) {
                //最低温和最高温
                tvLowHeight.setText(response.body().getHeWeather6().get(0).getDaily_forecast().get(0).getTmp_min() + " / " +
                        response.body().getHeWeather6().get(0).getDaily_forecast().get(0).getTmp_max() + "℃");
    
                if (response.body().getHeWeather6().get(0).getDaily_forecast() != null) {
                    List<WeatherForecastResponse.HeWeather6Bean.DailyForecastBean> data
                            = response.body().getHeWeather6().get(0).getDaily_forecast();
                    mList.clear();//添加数据之前先清除
                    mList.addAll(data);//添加数据
                    mAdapter.notifyDataSetChanged();//刷新列表
                } else {
                    ToastUtils.showShortToast(context, "天气预报数据为空");
                }
            } else {
                ToastUtils.showShortToast(context, response.body().getHeWeather6().get(0).getStatus());
            }
        }
    

    运行
    在这里插入图片描述
    这样天气预报这个功能就完成了。
    接下来是生活指数。

    7. 生活指数

    生活指数就是一些生活建议,实现的不走其实和天气预报差不太多,但是比天气预报要简单一些,因为不需要列表显示,文本即可。

    ① 新增API接口

    根据和风天气中的文档,得知生活指数接口为:

    https://free-api.heweather.net/s6/weather/lifestyle?key=3086e91d66c04ce588a7f538f917c7f4&location=福田区
    

    在网页上访问得到返回值,生成一个实体
    在这里插入图片描述
    代码如下:

    package com.llw.goodweather.bean;
    
    import java.util.List;
    
    public class LifeStyleResponse {
    
        private List<HeWeather6Bean> HeWeather6;
    
        public List<HeWeather6Bean> getHeWeather6() {
            return HeWeather6;
        }
    
        public void setHeWeather6(List<HeWeather6Bean> HeWeather6) {
            this.HeWeather6 = HeWeather6;
        }
    
        public static class HeWeather6Bean {
            /**
             * basic : {"cid":"CN101280603","location":"福田","parent_city":"深圳","admin_area":"广东","cnty":"中国","lat":"22.5410099","lon":"114.05095673","tz":"+8.00"}
             * update : {"loc":"2019-11-23 09:55","utc":"2019-11-23 01:55"}
             * status : ok
             * lifestyle : [{"type":"comf","brf":"舒适","txt":"白天不太热也不太冷,风力不大,相信您在这样的天气条件下,应会感到比较清爽和舒适。"},{"type":"drsg","brf":"热","txt":"天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"},{"type":"flu","brf":"少发","txt":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。"},{"type":"sport","brf":"适宜","txt":"天气较好,赶快投身大自然参与户外运动,尽情感受运动的快乐吧。"},{"type":"trav","brf":"适宜","txt":"天气较好,温度适宜,是个好天气哦。这样的天气适宜旅游,您可以尽情地享受大自然的风光。"},{"type":"uv","brf":"强","txt":"紫外线辐射强,建议涂擦SPF20左右、PA++的防晒护肤品。避免在10点至14点暴露于日光下。"},{"type":"cw","brf":"适宜","txt":"适宜洗车,未来持续两天无雨天气较好,适合擦洗汽车,蓝天白云、风和日丽将伴您的车子连日洁净。"},{"type":"air","brf":"中","txt":"气象条件对空气污染物稀释、扩散和清除无明显影响。"}]
             */
    
            private BasicBean basic;
            private UpdateBean update;
            private String status;
            private List<LifestyleBean> lifestyle;
    
            public BasicBean getBasic() {
                return basic;
            }
    
            public void setBasic(BasicBean basic) {
                this.basic = basic;
            }
    
            public UpdateBean getUpdate() {
                return update;
            }
    
            public void setUpdate(UpdateBean update) {
                this.update = update;
            }
    
            public String getStatus() {
                return status;
            }
    
            public void setStatus(String status) {
                this.status = status;
            }
    
            public List<LifestyleBean> getLifestyle() {
                return lifestyle;
            }
    
            public void setLifestyle(List<LifestyleBean> lifestyle) {
                this.lifestyle = lifestyle;
            }
    
            public static class BasicBean {
                /**
                 * cid : CN101280603
                 * location : 福田
                 * parent_city : 深圳
                 * admin_area : 广东
                 * cnty : 中国
                 * lat : 22.5410099
                 * lon : 114.05095673
                 * tz : +8.00
                 */
    
                private String cid;
                private String location;
                private String parent_city;
                private String admin_area;
                private String cnty;
                private String lat;
                private String lon;
                private String tz;
    
                public String getCid() {
                    return cid;
                }
    
                public void setCid(String cid) {
                    this.cid = cid;
                }
    
                public String getLocation() {
                    return location;
                }
    
                public void setLocation(String location) {
                    this.location = location;
                }
    
                public String getParent_city() {
                    return parent_city;
                }
    
                public void setParent_city(String parent_city) {
                    this.parent_city = parent_city;
                }
    
                public String getAdmin_area() {
                    return admin_area;
                }
    
                public void setAdmin_area(String admin_area) {
                    this.admin_area = admin_area;
                }
    
                public String getCnty() {
                    return cnty;
                }
    
                public void setCnty(String cnty) {
                    this.cnty = cnty;
                }
    
                public String getLat() {
                    return lat;
                }
    
                public void setLat(String lat) {
                    this.lat = lat;
                }
    
                public String getLon() {
                    return lon;
                }
    
                public void setLon(String lon) {
                    this.lon = lon;
                }
    
                public String getTz() {
                    return tz;
                }
    
                public void setTz(String tz) {
                    this.tz = tz;
                }
            }
    
            public static class UpdateBean {
                /**
                 * loc : 2019-11-23 09:55
                 * utc : 2019-11-23 01:55
                 */
    
                private String loc;
                private String utc;
    
                public String getLoc() {
                    return loc;
                }
    
                public void setLoc(String loc) {
                    this.loc = loc;
                }
    
                public String getUtc() {
                    return utc;
                }
    
                public void setUtc(String utc) {
                    this.utc = utc;
                }
            }
    
            public static class LifestyleBean {
                /**
                 * type : comf
                 * brf : 舒适
                 * txt : 白天不太热也不太冷,风力不大,相信您在这样的天气条件下,应会感到比较清爽和舒适。
                 */
    
                private String type;
                private String brf;
                private String txt;
    
                public String getType() {
                    return type;
                }
    
                public void setType(String type) {
                    this.type = type;
                }
    
                public String getBrf() {
                    return brf;
                }
    
                public void setBrf(String brf) {
                    this.brf = brf;
                }
    
                public String getTxt() {
                    return txt;
                }
    
                public void setTxt(String txt) {
                    this.txt = txt;
                }
            }
        }
    }
    
    

    在ApiService中增加
    在这里插入图片描述
    代码如下:

    	/**
         * 生活指数
         */
        @GET("/s6/weather/lifestyle?key=3086e91d66c04ce588a7f538f917c7f4")
        Call<LifeStyleResponse> getLifestyle(@Query("location") String location);
    

    记得将key的值修改为自己的Key

    ② 修改订阅器

    WeatherContract新增生活指数订阅
    在这里插入图片描述
    在这里插入图片描述

    		/**
             * 生活指数
             * @param context
             * @param location
             */
            public void lifeStyle(final Context context,String location){
                ApiService service = ServiceGenerator.createService(ApiService.class);
                service.getLifestyle(location).enqueue(new NetCallBack<LifeStyleResponse>() {
                    @Override
                    public void onSuccess(Call<LifeStyleResponse> call, Response<LifeStyleResponse> response) {
                        if(getView() != null){
                            getView().getLifeStyleResult(response);
                        }
                    }
    
                    @Override
                    public void onFailed() {
                        if(getView() != null){
                            getView().getDataFailed();
                        }
                    }
                });
            }
    
    		//查询生活指数的数据返回
            void getLifeStyleResult(Response<LifeStyleResponse> response);
    

    ③ 修改布局

    这次要展示的数据会比较多,所以布局的整体要用NestedScrollView包裹起来,变成一个·可以上下滑动的布局,布局修改后的代码如下(PS:为了不出现问题,这里我贴上全部的布局代码):

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:gravity="center"
        android:fitsSystemWindows="true"
        android:background="@drawable/pic_bg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <!--相对布局-->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <!--透明度为0.3的黑色背景-->
            <LinearLayout
                android:background="#000"
                android:alpha="0.3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
            <!--主要的布局文件-->
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <!--标题 沉浸式-->
                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:contentInsetLeft="16dp"
                    app:popupTheme="@style/AppTheme.PopupOverlay">
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:textSize="16sp"
                        android:textColor="#FFF"
                        android:text="城市天气" />
                </androidx.appcompat.widget.Toolbar>
    
                <!--NestedScrollView 里面只能包裹一个大的布局,
                当这个布局长度超出手机展示的部分就可以滚动,其中overScrollMode="never"
                的意思是隐藏掉滚动条到顶部和底部时的水波纹-->
                <androidx.core.widget.NestedScrollView
                    android:overScrollMode="never"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
                    <!--天气和所在城市 -->
                    <LinearLayout
                        android:gravity="center_horizontal"
                        android:orientation="vertical"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent">
                        <!--天气状况-->
                        <TextView
                            android:paddingLeft="16dp"
                            android:paddingTop="12dp"
                            android:id="@+id/tv_info"
                            android:textColor="#FFF"
                            android:textSize="18sp"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"/>
                        <!--温度-->
                        <LinearLayout
                            android:gravity="top|center_horizontal"
                            android:layout_marginTop="20dp"
                            android:orientation="horizontal"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content">
                            <TextView
                                android:id="@+id/tv_temperature"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="0"
                                android:textColor="#FFF"
                                android:textSize="60sp" />
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="match_parent"
                                android:text="℃"
                                android:textColor="#FFF"
                                android:textSize="24sp" />
                        </LinearLayout>
    
                        <!--最高温和最低温-->
                        <TextView
                            android:layout_marginTop="12dp"
                            android:id="@+id/tv_low_height"
                            android:textColor="#FFF"
                            android:textSize="@dimen/sp_14"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>
                        <!--城市-->
                        <TextView
                            android:layout_marginTop="20dp"
                            android:id="@+id/tv_city"
                            android:textColor="#FFF"
                            android:text="城市"
                            android:textSize="20sp"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>
                        <!--上一次更新时间-->
                        <TextView
                            android:layout_marginTop="8dp"
                            android:id="@+id/tv_old_time"
                            android:textColor="#FFF"
                            android:text="上次更新时间:"
                            android:textSize="@dimen/sp_12"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>
    
                        <!--用于显示天气预报数据-->
                        <androidx.recyclerview.widget.RecyclerView
                            android:layout_marginTop="20dp"
                            android:id="@+id/rv"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"/>
    
                        <!--用于展示生活指数的布局-->
                        <LinearLayout
                            android:orientation="vertical"
                            android:padding="20dp"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content">
                            <!--标题-->
                            <TextView
                                android:textSize="18sp"
                                android:textColor="#FFF"
                                android:text="生活建议"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                            <!--舒适度-->
                            <TextView
                                android:layout_marginTop="16dp"
                                android:id="@+id/tv_comf"
                                android:text="舒适度:"
                                android:textSize="@dimen/sp_14"
                                android:textColor="#FFF"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                            <!--旅游指数-->
                            <TextView
                                android:layout_marginTop="16dp"
                                android:id="@+id/tv_trav"
                                android:text="旅游指数:"
                                android:textSize="@dimen/sp_14"
                                android:textColor="#FFF"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                            <!--运动指数-->
                            <TextView
                                android:layout_marginTop="16dp"
                                android:id="@+id/tv_sport"
                                android:text="运动指数:"
                                android:textSize="@dimen/sp_14"
                                android:textColor="#FFF"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                            <!--洗车指数-->
                            <TextView
                                android:layout_marginTop="16dp"
                                android:id="@+id/tv_cw"
                                android:text="洗车指数:"
                                android:textSize="@dimen/sp_14"
                                android:textColor="#FFF"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                            <!--空气指数-->
                            <TextView
                                android:layout_marginTop="16dp"
                                android:id="@+id/tv_air"
                                android:text="空气指数:"
                                android:textSize="@dimen/sp_14"
                                android:textColor="#FFF"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                            <!--穿衣指数-->
                            <TextView
                                android:layout_marginTop="16dp"
                                android:id="@+id/tv_drsg"
                                android:text="穿衣指数:"
                                android:textSize="@dimen/sp_14"
                                android:textColor="#FFF"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                            <!--感冒指数-->
                            <TextView
                                android:layout_marginTop="16dp"
                                android:id="@+id/tv_flu"
                                android:text="感冒指数:"
                                android:textSize="@dimen/sp_14"
                                android:textColor="#FFF"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"/>
                        </LinearLayout>
                    </LinearLayout>
                </androidx.core.widget.NestedScrollView>
            </LinearLayout>
        </RelativeLayout>
    </LinearLayout>
    

    注释已经在代码中写好了,相信你看了就明白了。接下来就是数据返回的处理,和页面数据渲染显示。

    ④ 数据渲染显示

    在这里插入图片描述
    由于返回的数据可能会为空,为了使返回数据为空的时候程序不报错,这里要做判断,在模块的utils包下写一个工具类。
    在这里插入图片描述
    工具类代码如下:

    package com.llw.mvplibrary.utils;
    
    import android.os.Build;
    import android.util.SparseArray;
    import android.util.SparseBooleanArray;
    import android.util.SparseIntArray;
    import android.util.SparseLongArray;
    
    import androidx.annotation.RequiresApi;
    import androidx.collection.LongSparseArray;
    import androidx.collection.SimpleArrayMap;
    
    import java.lang.reflect.Array;
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * 空判断工具类
     */
    public final class ObjectUtils {
    
        private ObjectUtils() {
            throw new UnsupportedOperationException("u can't instantiate me...");
        }
    
        /**
         * Return whether object is empty.
         *
         * @param obj The object.
         * @return {@code true}: yes<br>{@code false}: no
         */
        public static boolean isEmpty(final Object obj) {
            if (obj == null) {
                return true;
            }
            if (obj.getClass().isArray() && Array.getLength(obj) == 0) {
                return true;
            }
            if (obj instanceof CharSequence && obj.toString().length() == 0) {
                return true;
            }
            if (obj instanceof Collection && ((Collection) obj).isEmpty()) {
                return true;
            }
            if (obj instanceof Map && ((Map) obj).isEmpty()) {
                return true;
            }
            if (obj instanceof SimpleArrayMap && ((SimpleArrayMap) obj).isEmpty()) {
                return true;
            }
            if (obj instanceof SparseArray && ((SparseArray) obj).size() == 0) {
                return true;
            }
            if (obj instanceof SparseBooleanArray && ((SparseBooleanArray) obj).size() == 0) {
                return true;
            }
            if (obj instanceof SparseIntArray && ((SparseIntArray) obj).size() == 0) {
                return true;
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                if (obj instanceof SparseLongArray && ((SparseLongArray) obj).size() == 0) {
                    return true;
                }
            }
            if (obj instanceof LongSparseArray && ((LongSparseArray) obj).size() == 0) {
                return true;
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                if (obj instanceof android.util.LongSparseArray
                        && ((android.util.LongSparseArray) obj).size() == 0) {
                    return true;
                }
            }
            return false;
        }
    
        public static boolean isEmpty(final CharSequence obj) {
            return obj == null || obj.toString().length() == 0;
        }
    
        public static boolean isEmpty(final Collection obj) {
            return obj == null || obj.isEmpty();
        }
    
        public static boolean isEmpty(final Map obj) {
            return obj == null || obj.isEmpty();
        }
    
        public static boolean isEmpty(final SimpleArrayMap obj) {
            return obj == null || obj.isEmpty();
        }
    
        public static boolean isEmpty(final SparseArray obj) {
            return obj == null || obj.size() == 0;
        }
    
        public static boolean isEmpty(final SparseBooleanArray obj) {
            return obj == null || obj.size() == 0;
        }
    
        public static boolean isEmpty(final SparseIntArray obj) {
            return obj == null || obj.size() == 0;
        }
    
        public static boolean isEmpty(final LongSparseArray obj) {
            return obj == null || obj.size() == 0;
        }
    
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        public static boolean isEmpty(final SparseLongArray obj) {
            return obj == null || obj.size() == 0;
        }
    
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        public static boolean isEmpty(final android.util.LongSparseArray obj) {
            return obj == null || obj.size() == 0;
        }
    
        /**
         * Return whether object is not empty.
         *
         * @param obj The object.
         * @return {@code true}: yes<br>{@code false}: no
         */
        public static boolean isNotEmpty(final Object obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final CharSequence obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final Collection obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final Map obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final SimpleArrayMap obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final SparseArray obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final SparseBooleanArray obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final SparseIntArray obj) {
            return !isEmpty(obj);
        }
    
        public static boolean isNotEmpty(final LongSparseArray obj) {
            return !isEmpty(obj);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        public static boolean isNotEmpty(final SparseLongArray obj) {
            return !isEmpty(obj);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        public static boolean isNotEmpty(final android.util.LongSparseArray obj) {
            return !isEmpty(obj);
        }
    
        /**
         * Return whether object1 is equals to object2.
         *
         * @param o1 The first object.
         * @param o2 The second object.
         * @return {@code true}: yes<br>{@code false}: no
         */
        public static boolean equals(final Object o1, final Object o2) {
            return o1 == o2 || (o1 != null && o1.equals(o2));
        }
    
        /**
         * Require the objects are not null.
         *
         * @param objects The object.
         * @throws NullPointerException if any object is null in objects
         */
        public static void requireNonNull(final Object... objects) {
            if (objects == null) throw new NullPointerException();
            for (Object object : objects) {
                if (object == null) throw new NullPointerException();
            }
        }
    
        /**
         * Return the nonnull object or default object.
         *
         * @param object        The object.
         * @param defaultObject The default object to use with the object is null.
         * @param <T>           The value type.
         * @return the nonnull object or default object
         */
        public static <T> T getOrDefault(final T object, final T defaultObject) {
            if (object == null) {
                return defaultObject;
            }
            return object;
        }
    
        /**
         * Return the hash code of object.
         *
         * @param o The object.
         * @return the hash code of object
         */
        public static int hashCode(final Object o) {
            return o != null ? o.hashCode() : 0;
        }
    }
    
    

    接下来调用方法请求生活指数
    在这里插入图片描述

    请求返回数据做处理:

    	//查询生活指数,请求成功后的数据返回
        @Override
        public void getLifeStyleResult(Response<LifeStyleResponse> response) {
            if(("ok").equals(response.body().getHeWeather6().get(0).getStatus())){
                List<LifeStyleResponse.HeWeather6Bean.LifestyleBean> data = response.body().getHeWeather6().get(0).getLifestyle();
                if(!ObjectUtils.isEmpty(data)){
                    for (int i = 0;i<data.size();i++){
                        if(("comf").equals(data.get(i).getType())){
                            tvComf.setText("舒适度:"+data.get(i).getTxt());
                        }else if(("drsg").equals(data.get(i).getType())){
                            tvDrsg.setText("穿衣指数:"+data.get(i).getTxt());
                        }else if(("flu").equals(data.get(i).getType())){
                            tvFlu.setText("感冒指数:"+data.get(i).getTxt());
                        }else if(("sport").equals(data.get(i).getType())){
                            tvSport.setText("运动指数:"+data.get(i).getTxt());
                        }else if(("trav").equals(data.get(i).getType())){
                            tvTrav.setText("旅游指数:"+data.get(i).getTxt());
                        }else if(("cw").equals(data.get(i).getType())){
                            tvCw.setText("洗车指数:"+data.get(i).getTxt());
                        }else if(("air").equals(data.get(i).getType())){
                            tvAir.setText("空气指数:"+data.get(i).getTxt());
                        }
                    }
    
                }else {
                    ToastUtils.showShortToast(context, "生活指数数据为空");
                }
            }else {
                ToastUtils.showShortToast(context, response.body().getHeWeather6().get(0).getStatus());
            }
        }
    

    运行一下:
    在这里插入图片描述
    很明显数据显示不完全,然后向上滑动。
    在这里插入图片描述

    这样就完成了这个生活指数的数据显示。
    但是感觉页面上好多字呀,这时候为了在视觉上舒缓,就要通过会动的东西来勾引,呸,吸引住你。比如风的数据显示,多少级的风,哪个方向,通过风车来增加页面的动。会动的风车喔。

    源码地址:Good Weather 欢迎 StarFork

    下一篇:Android 天气APP(六)旋转风车显示风力、风向

    展开全文
  • 优东南风 3级06月15日明天小雨25~32℃空气 优东南风 3级06月16日后天小雨25~32℃空气 优南风 3级06月17日星期三小雨25~33℃空气 优南风 3级06月18日星期四小雨转阴26~34℃空气 优南风 3级06月19日星期阴到小雨26~...
  • 五天预报 在本地运行应用 将仓库和CD复制到目录中 运行$ npm install 注册以获取Google和Dark Sky API,并将它们保存在.env文件中。 REACT_APP_DARK_SKY_API_KEY ='API_KEY'REACT_APP_GOOGLE_MAP_API_KEY ='AKI_KEY...
  • 微信里的励志天气预报(每日天气预报加励志)2020-05-18 14:28:25共10个回答有个天气预报+励志短语的软件吗你要是苹果手机,直接到AppStore搜"天气预报",前个有一个是Minesage的,里面有个小黄人,点击他就会说一些...
  • 天气仪表板 一个简单的天气仪表板,可为您提供温度,湿度,风速和紫外线指数以及为期五天预报
  • 该天气仪表板利用API提取数据,为用户提供天气预报,其中显示了当前天气和5天气预报。 城市,温度,湿度,风速和紫外线指数显示在每日天气预报中,温度和湿度显示在5预报中。 此外,还从天气API站点中提取了...
  • Rainmeter天气预报皮肤

    2013-01-02 18:32:49
    非常不错的一款皮肤。Rainmeter XP桌面天气预报 带五天天气预报 使用中国天气网数据 需VC2007支持
  • 日历天气预报app给用户们提供了精准的天气播报服务,用户们在这里可以查看未来十五天的天气情况,还可以详细的查看到天气的风向、风速、紫外线、空气质量等等,非常的全面,让大家做好外出或者洗晒的准备。...
  • 一、简介 ...这一篇文章将对大家每天都会关心的天气查询进行开发,例如,用户发送消息 “苏州天气”,则会返回苏州实时天气状况,以及未来两天甚至未来五天天气状况。 二、思路分析 首先要对用户...
  • php天气预报源码

    2013-03-05 14:15:06
    天气预报,php,代码,简单,直接访问,未来五天天气预报
  • labview 天气预报

    2018-08-07 10:28:21
    labview 通过 API 读取五天天气预报.......................................................................................
  • 如果在接下来的五天内温度超过给定的下限,则系统会在REST API响应中发出警告。 该应用程序集成了两个天气预报服务和 。 二手技术 NestJS 打字稿 MongoDB 码头工人 配置 .env文件中定义了应用程序配置,例如...
  • 一、简介 前面几篇文章对微信公众...这一篇文章将对大家每天都会关心的天气查询进行开发,例如,用户发送消息 “苏州天气”,则会返回苏州实时天气状况,以及未来两天甚至未来五天天气状况。 二、思路分析
  • 小生活天气预报

    2016-03-29 23:34:33
    1.实时天气详情 2.五天天气预报折现统计图 3.穿衣等指数提示 4.第三方分享 5.悬浮窗和悬浮窗特效

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 205
精华内容 82
关键字:

五天天气预报