目录

  • 第1章 Android UI设计
    • ● 版本与程序
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章讲解
    • ● 例1-1 线性布局应用示例
    • ● 例1-2 帧布局应用示例
    • ● 例1-3 表格布局应用示例
    • ● 例1-4 相对布局应用示例
    • ● 例1-5 网格布局应用示例
    • ● 例1-6 约束布局应用示例
    • ● 例1-7 文本标签组件示例
    • ● 例1-8 制作登陆界面
    • ● 例1-9 进度条ProgressBar应用示例
    • ● 例1-10 单选按钮与复选按钮
    • ● 例1-11 简单列表示例
    • ● 例1-12 ListActivity示例
    • ● 例1-13 带有图片的列表
    • ● 例1-14 没有数据的ListView
    • ● 例1-15 改进的列表
    • ● 实战演练——生肖背后的故事
  • 第2章 Activity与多个用户界面
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章讲解
    • ● 例2-1 从Activity启动另一个Activity示例
    • ● 例2-2 传递数据到第二个Activity示例
    • ● 例2-3 消息提示Toast示例
    • ● 例2-4 消息对话框示例
    • ● 例2-5 选项菜单应用示例
    • ● 例2-6 上下文菜单应用示例
    • ● 实战演练——BMI体质指数计算器
  • 第3章 多媒体播放与录制
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章讲解
    • ● 例3-1 音乐播放器, 播放项目资源中的音乐
    • ● 例3-2 音乐播放器, 播放SD卡中的音乐
    • ● 例3-3 应用MediaPlayer设计视频播放器
    • ● 例3-4 应用VidioView设计视频播放器
    • ● 例3-5 录音示例
    • ● 例3-6 拍照示例
    • ● 实战演练——音乐播放器
  • 第4章    广播与服务
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章讲解
    • ● 例4-1 消息广播程序示例
    • ● 例4-2 系统通知服务示例
    • ● 例4-3 广播和时钟服务示例
    • ● 例4-4 调用系统功能拨打电话
    • ● 例4-5 后台音乐服务示例
    • ● 实战演练——播放后台音乐
  • 第5章    数据存储
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章讲解
    • ● 例5-1 内部存储文件示例
    • ● 例5-2 SD文件示例
    • ● 例5-3 JSON数据示例
    • ● 例5-4 SharedPreferences示例
    • ● 例5-5 创建与删除数据库示例
    • ● 例5-6 数据库记录的操作示例
    • ● 实战演练——掌上日记本
  • 第6章    图像和动画
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章讲解
    • ● 例6-1 绘制几何图形示例
    • ● 例6-2 补间动画示例
    • ● 例6-3 属性动画示例
    • ● 例6-4 ImageView图像浏览示例
    • ● 例6-5 ImageSwitcher展示相册示例
    • ● 例6-6 GridView展示相册示例
    • ● 例6-7 游戏中触屏事件示例
    • ● 实战演练——图片与动画
  • 第7章    网络编程
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章讲解
    • ● 例7-1 应用WebView的对象浏览网页
    • ● 例7-2 从Web服务器读取图像文件
    • ● 例7-3 读取JSON数据
    • ● 例7-4 解析JSON数据
    • ● 实战演练——城市天气预报
  • 第8章    分享美食
    • ● 学习目标和本章素材
    • ● 本章PPT
    • ● 本章知识点讲解
    • ● 项目制作流程演示
    • ● 示范1 图标SVG
    • ● 示范2 卡片视图
    • ● 示范3 导航视图
  • 课程资源
    • ● 学生资源包
    • ● 网站地址
实战演练——城市天气预报

实战演练—城市天气预报

请设计一个城市天气查询的应用程序,数据来源选门户网站中国天气网,应用程序的运行效果如图7-8所示。该网站需要使用城市编号才能获得气候数据,城市编号是一个9位数字,按照长度分为4部分:101(国家代号)、01(省)、01(二级地区)、00(三级地区)。城市编号的JSON数据来源如下:

(1)省/直辖市的编码 http://www.weather.com.cn/data/city3jdata/china.html,得到的数据需要程序解析,将Volley默认的ISO-8859-1编码格式转换为utf-8,程序解析后的内容如下:

{"10101":"北京","10102":"上海"......"10128":"广东"......}

(2)市的编码 http://www.weather.com.cn/data/city3jdata/provshi/10128.html,得到的数据需要程序解析为utf-8编码格式,程序解析后的内容如下:

 {"01":"广州","02":"韶关",......"06":"深圳"......}

3要想获得深圳天气,按查询得到的1012806后面再加上三级地区01即可:https://m.weather.com.cn/mweather/101280601.shtml。中国天气网返回的是一个包含多项气候数据的网页,可以使用视图WebView直接显示输出网页。

请在应用程序中建立一个数组,关联城市ID和城市名称,用户只需输入城市的中文名称即可得到该城市天气信息。

运行演示


解析:

(1)为避免输入错误,可以将省及直辖市和城市设为下拉列表,供用户选择 。

(2)初始化省及直辖市的下拉列表。

(3)用户选择第一个列表后,程序从网络获取市的编码。

(4)用户点击“查询”按钮,程序从网络获取该市天气数据

(5)用案例7-1的WebView显示天气网页。


关键参考代码:


(1)为避免输入错误,可以将省及直辖市和城市设为下拉列表供用户选择 。

    Spinner spinner1,spinner2;

    Button btn;

    WebView webView;

    //(1)省及直辖市的编码  (2)市的编码   (3)区县编码: 直辖市返回参数00,其它返回01

    String url01="http://www.weather.com.cn/data/city3jdata/china.html";

    String url02="http://www.weather.com.cn/data/city3jdata/provshi/";


    String[] priv_name,priv_code; //解析后将地区名存入priv_name[],地区的城市代码放入priv_code[]

    String[] city_name,city_code;  

    final int[] pidselect = new int[1]; //选中的省或直辖市的编码

    final int[] cityidselect = new int[1];

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.btn);

        webView = (WebView)findViewById(R.id.webView1);

        spinner1 = (Spinner) findViewById(R.id.spinner1);

        spinner2 = (Spinner) findViewById(R.id.spinner2);

        btn.setOnClickListener(new btng());

        getprovshidata();

    }


(2)初始化省及直辖市的下拉列表。

public void getprovshidata() {

        RequestQueue mQueue = Volley.newRequestQueue(this);

        StringRequest stringRequest = new StringRequest(

                url01,

                new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response)

                    {

                        provshidata(response);  //解析编码

                    }

                },

                new Response.ErrorListener() {

                   ......

        };

        mQueue.add(stringRequest);

    }

    public void provshidata(String response) {   //解析编码

        try {

            JSONObject provshi = new JSONObject(response);

            final Iterator<String> privshi;

            privshi = provshi.keys();

            int datalen=provshi.length();

            priv_name=new String[datalen];

            priv_code=new String[datalen];

            int i=0;

            

            while(privshi.hasNext())  //遍历 provshi的 key-value

            {

                String pid = privshi.next();

                priv_code[i] = pid;

                priv_name[i] = provshi.getString(pid);

                i=i+1;

            }

        } catch (JSONException jsonException) {

            jsonException.printStackTrace();

        }


        ArrayAdapter<String> adapter;//数组配置器,给下拉菜单赋值用,将可选内容与ArrayAdapter连接起来

        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,priv_name);

        adapter.setDropDownViewResource(android.R.layout.simple_gallery_item); //设置下拉列表的风格

        spinner1.setAdapter(adapter);

        spinner1.setVisibility(View.VISIBLE); 


        spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){

            @Override

            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                pidselect[0] =position;

                provshi2city(priv_code[pidselect[0]]); //获取下一级数据,市的编码

            }

            @Override

            public void onNothingSelected(AdapterView<?> parent) {

            }

        });

    }


(3)用户选择第一个列表后,程序从网络获取市的编码。

public void provshi2city(String priv_id) { 

        RequestQueue mQueue = Volley.newRequestQueue(this);

        StringRequest stringRequest = new StringRequest(

                //第 1个参数,目标服务器的URL地址

                url02+priv_id+".html",

                //第2个参数,服务器响应成功的回调

                new Response.Listener<String>() {  //Volley的监听器

                    @Override

                    public void onResponse(String response)

                    {

                        getcityidname(response);  //解析编码

                    }//onResponse()方法获取接收到的数据值

                },

                //第3个参数,服务器响应失败的回调

                new Response.ErrorListener() {      

            ......

        };

        mQueue.add(stringRequest);

    } 


    public void getcityidname(String response) {  //解析编码

        try {

            JSONObject citys = new JSONObject(response);

            final Iterator<String> citykey;

            citykey = citys.keys();

            int datalen=citys.length();

            city_name=new String[datalen];

            city_code=new String[datalen];

            int i=0;

         

            while(citykey.hasNext())     //遍历 city

            {

                String cid = citykey.next();

                city_code[i] = cid;

                city_name[i] = citys.getString(cid);

                i=i+1;

            }


        } catch (JSONException jsonException) {

            jsonException.printStackTrace();

        }

 

        ArrayAdapter<String> adapter2; //数组配置器,给下拉菜单赋值用,将可选内容与ArrayAdapter连接起来

        adapter2 = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,city_name);

        adapter2.setDropDownViewResource(android.R.layout.simple_gallery_item); //设置下拉列表的风格

        spinner2.setAdapter(adapter2);

        spinner2.setVisibility(View.VISIBLE);  


        spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){

            @Override

            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                cityidselect[0] =position;

                Log.i("priv",priv_code[pidselect[0]]);  //查看数据

                Log.i("priv",priv_name[pidselect[0]]);

                Log.i("priv",city_code[cityidselect[0]]);

                Log.i("priv",city_name[cityidselect[0]]);

            }

            @Override

            public void onNothingSelected(AdapterView<?> parent) {

            }

        });

    } 



(4)用户点击“查询”按钮,程序从网络获取该市天气数据

    //String url01 = "http://www.weather.com.cn/data/cityinfo/101010100.html";//北京 10101+01+00

    //String url02 = "http://www.weather.com.cn/data/cityinfo/101280601.html";//深圳 10128+06+01

    class btng implements View.OnClickListener{

            public void onClick(View v){

                String wcode;

                String pid= priv_code[pidselect[0]];

                switch(pid) {  //(3)区县编码: 直辖市返回参数00,其它返回01

                    case "10101":

                    case "10102":

                    case "10103":

                    case "10104":

                        wcode=priv_code[pidselect[0]]+"0100";

                        break;

                    default:

                        wcode=priv_code[pidselect[0]]+city_code[cityidselect[0]]+"01";

                        break;

                }


(5)用案例7-1的WebView显示天气网页。

                Log.i("tag",wcode);

                webView.getSettings().setJavaScriptEnabled(true);

            ......

                String url="https://m.weather.com.cn/mweather/"+wcode+".shtml";

                webView.loadUrl(url);  //显示天气网页

            }

    }

本题目重点是网络JSON数据的解析。