水云天气APP项目回顾

图标

1.注册登录界面

 

2.搜索天气的功能界面

3.天气视频界面(直接button转中国天气网的链接)

http://www.weather.com.cn/video/yubao.shtml

4.小日历安排日程

新闻联播天气预报_中国天气网 (weather.com.cn)http://www.weather.com.cn/video/yubao.shtml

1.环境

使用Android Studio工具栏上的AVD Manager工具创建模拟器使用Android Studio工具栏上的AVD Manager工具创建模拟器(Google Pixel5)

 

更改图标的方法

将你准备好的 图标放入res目录下的drawable,在AndroidManifest.xml文件中,找到android:icon以及android:roundIcon这两个属性,设置为你放入的图标文件。

2.简单的布局管理器和控件

视图组件View类,是用户界面组件的共同父类。几乎所有的高级UI组件都继承自View类。例如:TextView、Button、List、EditText、RadioButton、CheckBox等

 

 

 3.事件处理

ØAndroid提供两套了事件处理机制
a. 基于监听器的的事件处理: 主要做法就是为 Android 界面组件绑定特定的事件监听器。
b. 基于回调的事件处理: 主要做法是重写 Android 组件特定的回调方法,或者重写 Activity 的回调方法。 Android 为绝大部分组件都提供了事件响应的回调方法。

基于回调的事件处理

 

4.activity的概念

 关闭Activity

Android中,如果想要关闭当前的Activity,可以使用Activity类提供的finish()方法

 5.Intent和IntentFilter进行通信

我们在这里给Activity设置了一个IntentFilter,但是值得注意的是,一个组件可以有多个IntentFilter,在过滤的时候只要有一个符合要求的,就会被视为过滤通过。

那我们就看看是怎样过滤的吧,首先我们应该明白一个大的思路:当我们隐式的启动一个组件的时候,就会一个一个的去过滤对应组件的全部,(比如你是隐式的启动一个Activity,就会一个一个的在全部Activity中筛选),然后根据Intent的所设置的actioncategorydata去比较IntentFilter所设置的这三个属性,相同的话就过滤留下来了。

action的匹配##### 

action的匹配要求Intent中的action存在且必须和过滤规则中的其中一个action相同

category的匹配#####

category 要求Intent中可以没有category,但是你一旦有category,不管几个,每个都要和IntentFilter中的category相同

data的匹配#####

如果IntentFilter中有定义data,那么Intent中也必须也要定义可以的date

6.Android应用的资源

7.Android的数据存储和IO

 1.使用shared Preferences读取

 SharedPreferences不仅能够保存数据,还能够实现不同应用程序间的数据共享(private、readable、writeable)

2.file存储

3.SQLite数据库

 

ØUri通用资源标志符(Uniform Resource Identifier),用来定位远程或本地的可用资源

Android开发和风天气API解析天气数据

1.申请和风天气开发者,账号密码申请

2.在应用管理中新建一个应用

3.添加key名,key的类型为Android SDK,package Name为自己创建的Android studio项目的包名,填写完毕后点击创建

4.在Android studio中新建一个project项目,包名要和和风天气新建应用中添加的key里面的包名一样。

5.在app目录下的build.gradle里的dependencies{}花括号里面添加依赖 

    implementation 'com.squareup.okhttp3:okhttp:3.9.0'
	implementation 'com.google.code.gson:gson:2.8.6'

点击右上角的Sync Now同步保存

6.下载并引用和风天气的Android SDK

Android SDK配置 | 和风天气开发服务 (qweather.com)

 点击下载,然后把下载好的Android SDK拷贝到我们的Weather工程下的app目录里的libs文件夹中:

 接着,在这个文件上右键,选择“Add As Library…”:

获取和风天气API接口的数据

创建好布局

activity._main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:text="天气"
        android:textColor="@android:color/white"
        android:textStyle="bold"
        android:textSize="24sp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"/>

    <LinearLayout
        android:layout_margin="20dp"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RelativeLayout
            android:layout_margin="10dp"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="50dp">

            <TextView
                android:id="@+id/province_tv"
                android:text="省份:"
                android:gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>
            <EditText
                android:id="@+id/province_edit"
                android:layout_toRightOf="@+id/province_tv"
                android:hint="请输入要查询的天气的省份"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </RelativeLayout>

        <RelativeLayout
            android:layout_margin="10dp"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="50dp">

            <TextView
                android:id="@+id/city_tv"
                android:text="城市:"
                android:gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>
            <EditText
                android:id="@+id/city_edit"
                android:layout_toRightOf="@+id/city_tv"
                android:hint="请输入该省份的城市"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </RelativeLayout>

        <Button
            android:id="@+id/search"
            android:text="查询"
            android:layout_alignParentRight="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <TextView
        android:id="@+id/city_weather"
        android:text="城市的天气"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:visibility="gone"/>

    <LinearLayout
        android:id="@+id/weather_info"
        android:layout_margin="10dp"
        android:orientation="vertical"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:text="天气:"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
            <TextView
                android:id="@+id/weather"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:text="湿度:"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
            <TextView
                android:id="@+id/shidu"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:text="生活建议:"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
            <TextView
                android:id="@+id/suggestion"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

创建2个实体类:Province, City

在包名com.example.weather路径右键,新建一个package,命名为“bean”。再在bean上右键创建2个java类,分别命名为Province和City。
具体代码如下:

Province.java

package com.example.weather.bean;

public class Province {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

City.java

package com.example.weather.bean;

public class City {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

具体的MainActivity.java中的代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private String weatherCountry = "http://guolin.tech/api/china/";//中国的省份城市api
    private String weatherProvince, weatherCity;//获取到的省份id和城市id
    private ArrayList<Province> provinceList;//中国的省份集合
    private ArrayList<City> cityList;//具体省份的城市集合

    private String weatherUrl = "https://free-api.heweather.net/s6/weather/now?location=%s&key=%s";//和风天气 免费的api接口
    private String cityId;//具体城市天气id,如湛江,"weather_id"=CN101281001

    //注册和风天气开发者https://dev.heweather.com/
    //创建的apk 的 用户id 以及 该apk的key(包名要一致)
    private String userName = "HE1912282028221196";
    private String key = "55337274dc904af8a135d9ac9d3c80cc";//自己申请的key

    /**
     * 请输入该省份的城市
     */
    private EditText mCityEdit;
    /**
     * 查询
     */
    private Button mSearch;
    /**
     * 城市的天气
     */
    private TextView mCityWeather;
    private TextView mWeather;
    private TextView mShidu;
    /**
     * 省份:
     */
    private TextView mProvinceTv;
    /**
     * 请输入要查询的天气的省份
     */
    private EditText mProvinceEdit;

    String province, city;//接收输入的省份和城市收用的字符串
    private LinearLayout mWeatherInfo;
    private TextView mSuggestion;

    private String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
//        使用 SDK 时,需提前进行账户初始化(全局执行一次即可)
        HeConfig.init(userName, key);
//        个人开发者、企业开发者、普通用户等所有使用免费数据的用户需要切换到免费服务域名 即 https://free-api.heweather.net/s6/sdk/
        HeConfig.switchToFreeServerNode();
    }

    private void initView() {
        mCityEdit = (EditText) findViewById(R.id.city_edit);
        mSearch = (Button) findViewById(R.id.search);
        mSearch.setOnClickListener(this);
        mCityWeather = (TextView) findViewById(R.id.city_weather);
        mWeather = (TextView) findViewById(R.id.weather);
        mShidu = (TextView) findViewById(R.id.shidu);
        mProvinceTv = (TextView) findViewById(R.id.province_tv);
        mProvinceEdit = (EditText) findViewById(R.id.province_edit);
        mWeatherInfo = (LinearLayout) findViewById(R.id.weather_info);
        mSuggestion = (TextView) findViewById(R.id.suggestion);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                break;
            case R.id.search:
                province = mProvinceEdit.getText().toString().trim();
                city = mCityEdit.getText().toString().trim();
                queryWeather();
                break;
        }
    }

    private void queryWeather() {
        provinceList = new ArrayList<Province>();//省份集合
        cityList = new ArrayList<City>();//具体省份的城市集合
        new Thread() {
            @Override
            public void run() {
                try {
                    //weatherCountry = "http://guolin.tech/api/china/"
                    URL url = new URL(weatherCountry);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();//开启一个url的连接,用HttpURLConnection连接方式处理
                    connection.setRequestMethod("GET");//设置连接对象的请求数据的方式
                    connection.setConnectTimeout(3000);//设置连接对象的请求超时的时间

                    //将请求返回的数据流转换成字节输入流对象
                    InputStream is = connection.getInputStream();
                    //将字节输入流对象转换成字符输入流对象
                    InputStreamReader isr = new InputStreamReader(is);
                    //创建字符输入缓冲流对象
                    BufferedReader br = new BufferedReader(isr);

                    StringBuffer sb = new StringBuffer();
                    String string;

                    //读文本
                    while ((string = br.readLine()) != null) {
                        sb.append(string);
                    }

                    String result = sb.toString();

                    Log.d("MainActivity", "" + result);


                    JSONArray provinceArray = new JSONArray(result);
                    for (int i = 0; i < provinceArray.length(); i++) {
                        JSONObject provinceInfo = provinceArray.getJSONObject(i);//获取每个省份信息
                        Province provinceBean = new Province();//创建省份实体类对象
                        Gson gson = new Gson();//创建Gson解析对象

                        //反序例化,将json数据转化为实体类对象的成员变量值
                        provinceBean = gson.fromJson(provinceInfo.toString(), Province.class);
                        //添加保存好的省份对象数据进入省份集合
                        provinceList.add(provinceBean);
                    }

                    for (Province pro : provinceList) {
                        //如果该省份为用户输入的省份
                        if (pro.getName().equals(province)) {
                            //则拼接链接
                            //如:北京 weatherProvince = "http://guolin.tech/api/china/1/"
                            weatherProvince = weatherCountry + pro.getId() + "/";
                        }
                    }

                    Log.d("WeatherProvince", "" + weatherProvince);

                    //如:北京 weatherProvince = "http://guolin.tech/api/china/1/"
                    url = new URL(weatherProvince);
                    connection = (HttpURLConnection) url.openConnection();//开启一个url的连接用HttpURLConnection连接方式处理
                    connection.setRequestMethod("GET");//设置连接对象的请求数据的方式
                    connection.setConnectTimeout(3000);//设置连接对象的请求超时的时间

                    //将请求返回的数据流转换成字节输入流对象
                    is = connection.getInputStream();
                    //将字节输入流对象转换成字符输入流对象
                    isr = new InputStreamReader(is);
                    br = new BufferedReader(isr);

                    StringBuffer sb2 = new StringBuffer();
                    //读文本
                    while ((string = br.readLine()) != null) {
                        sb2.append(string);
                    }

                    String result2 = sb2.toString();

                    Log.d("MainActivity2", "" + result2);

                    JSONArray cityArray = new JSONArray(result2);
                    for (int i = 0; i < cityArray.length(); i++) {
                        JSONObject cityInfo = cityArray.getJSONObject(i);//获取具体省份城市信息
                        City cityBean = new City();//创建城市实体类对象
                        Gson gson = new Gson();//创建Gson解析对象
                        //反序例化,将json数据转化为实体类对象的成员变量值
                        cityBean = gson.fromJson(cityInfo.toString(), City.class);
                        //添加保存好的城市对象数据进入城市集合
                        cityList.add(cityBean);
                    }

                    for (City c : cityList) {
                        //如果该城市为用户输入的城市
                        if (c.getName().equals(city)) {
                            //则拼接链接
                            //如:北京 weatherCity = "http://guolin.tech/api/china/1/1/"
                            weatherCity = weatherProvince + c.getId() + "/";
                        }
                    }

                    Log.d("WeatherCity", ""+weatherCity);

                    //如:北京 weatherCity = "http://guolin.tech/api/china/1/1/"
                    url = new URL(weatherCity);
                    connection = (HttpURLConnection) url.openConnection();//开启一个url的连接用HttpURLConnection连接方式处理
                    connection.setRequestMethod("GET");//设置连接对象的请求数据的方式
                    connection.setConnectTimeout(3000);//设置连接对象的请求超时的时间

                    //将请求返回的数据流转换成字节输入流对象
                    is = connection.getInputStream();
                    //将字节输入流对象转换成字符输入流对象
                    isr = new InputStreamReader(is);
                    br = new BufferedReader(isr);

                    StringBuffer sb3 = new StringBuffer();
                    //读文本
                    while ((string = br.readLine()) != null) {
                        sb3.append(string);
                    }

                    String result3 = sb3.toString();

                    Log.d("MainActivity3", "" + result3);

                    JSONArray jsonArray = new JSONArray(result3);
                    JSONObject cityIdInfo = jsonArray.getJSONObject(0);
                    cityId=cityIdInfo.getString("weather_id");

                    //拼接字符串
                    String weatherApi = String.format(weatherUrl, cityId, key);
                    Log.d("WeatherApi", "" + weatherApi);
                    queryWeather2();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }.start();

    }

    public void queryWeather2(){
        /**
         * 实况天气
         * 实况天气即为当前时间点的天气状况以及温湿风压等气象指数,具体包含的数据:体感温度、
         * 实测温度、天气状况、风力、风速、风向、相对湿度、大气压强、降水量、能见度等。
         *
         * @param context  上下文
         * @param location 地址详解
         * @param lang     多语言,默认为简体中文,海外城市默认为英文
         * @param unit     单位选择,公制(m)或英制(i),默认为公制单位
         * @param listener 网络访问回调接口
         */
        HeWeather.getWeatherNow(MainActivity.this, cityId, Lang.CHINESE_SIMPLIFIED , Unit.METRIC , new HeWeather.OnResultWeatherNowBeanListener() {
            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "Weather Now onError: ", e);
            }

            @Override
            public void onSuccess(Now dataObject) {
                Log.i(TAG, " Weather Now onSuccess: " + new Gson().toJson(dataObject));
                //先判断返回的status是否正确,当status正确时获取数据,若status不正确,可查看status对应的Code值找到原因
                if ( Code.OK.getCode().equalsIgnoreCase(dataObject.getStatus()) ){
                    //此时返回数据

                    Basic basic=dataObject.getBasic();
                    String location=basic.getLocation();

                    mCityWeather.setText(location+"的天气");

                    NowBase now = dataObject.getNow();

                    String tmp=now.getTmp();
                    String cond_txt=now.getCond_txt();
                    String wind_dir=now.getWind_dir();

                    mWeather.setText("当前温度:"+tmp+"℃,"+cond_txt+","+wind_dir);
                    String hum=now.getHum();
                    mShidu.setText(hum+"%");
                } else {
                    //在此查看返回数据失败的原因
                    String status = dataObject.getStatus();
                    Code code = Code.toEnum(status);
                    Log.i(TAG, "failed code: " + code);
                }
            }
        });

        HeWeather.getWeatherLifeStyle(MainActivity.this,cityId, new HeWeather.OnResultWeatherLifeStyleBeanListener() {
            @Override
            public void onError(Throwable throwable) {

            }

            @Override
            public void onSuccess(Lifestyle lifestyle) {
                List<LifestyleBase> lifestyleBases=lifestyle.getLifestyle();
                String shushidu=lifestyleBases.get(0).getBrf();//舒适度指数
                String shushidu2=lifestyleBases.get(0).getTxt();//舒适度建议
                String sport=lifestyleBases.get(3).getBrf();//运动指数
                String sport2=lifestyleBases.get(3).getTxt();//运动建议
                String cw=lifestyleBases.get(6).getBrf();//洗车指数
                String cw2=lifestyleBases.get(6).getTxt();//洗车建议

                mSuggestion.setText("舒适度指数:"+shushidu+"\n" +
                        "舒适度建议:"+shushidu2+"\n" +
                        "运动指数:"+sport+"\n" +
                        "运动建议:"+sport2+"\n" +
                        "洗车指数:"+cw+"\n" +
                        "洗车建议:"+cw2+"\n");

                Message message=new Message();
                message.what=1;
                MainActivity.this.myHandler.sendMessage(message);
            }
        });

    }

    Handler myHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 1:
                    mCityWeather.setVisibility(View.VISIBLE);
                    mWeatherInfo.setVisibility(View.VISIBLE);
                    weatherProvince = "";
                    weatherCity = "";
                    break;
            }
            super.handleMessage(msg);
        }
    };

}

最后千万不要忘记在AndroidManifest.xml中添加网络权限代码:

    <uses-permission android:name="android.permission.INTERNET"/>

Gson介绍

GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。使用前记得要导入依赖。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值