1.集成聚合数据SDK
1)下载SDK
进入聚合数据官网注册账号,然后选择API->天气预报->全国天气预报和空气质量;申请数据。
申请完数据后就可以下载SDK了。有两个版本的SDK可以选择;本文使用的是版本2.6。
2)创建工程
创建工程后将SDK中的armeabi和juhe_sdk_v_2_7两个文件拷进工程下的app/libs文件下;然后打开Mo'du'le's setting
点击上图所示的按钮,然后选择刚才添加的库文件。这样工程就建完了。
2.页面布局
1)主页面
activity_weather.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="match_parent" android:background="@color/text_color"> <swiperefresh.PullToRefreshScrollView xmlns:ptr="http://schemas.android.com/apk/res-auto" android:id="@+id/pull_refresh_scrollview" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none" ptr:ptrAnimationStyle="flip" ptr:ptrMode="pullFromStart" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp" android:id="@+id/layout" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rl_city"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_city" android:textSize="25dp" android:text="北京" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/arrow" android:layout_alignTop="@id/tv_city" android:layout_alignBottom="@id/tv_city" android:layout_toRightOf="@id/tv_city" android:layout_marginLeft="6dp" android:background="#ffffffff"/> </RelativeLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_release" android:layout_marginTop="10dp" android:layout_gravity="center" android:layout_marginBottom="16dp" android:textSize="18sp"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/light_grey"/> <LinearLayout android:layout_width="match_parent" android:layout_height="35dp" android:layout_marginTop="7dp" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/iv_now_weather" android:layout_marginLeft="8dp" android:src="@drawable/d00"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="12dp" android:textSize="18dp" android:id="@+id/tv_weather"/> </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="9dp" android:layout_marginLeft="9dp" android:id="@+id/tv_today_temp" android:textSize="15dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="5dp" android:layout_marginBottom="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="9dp" android:id="@+id/tv_now_temp" android:textSize="47sp"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="right"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pm" android:textSize="19dp" android:layout_marginRight="45dp"/> <LinearLayout android:layout_width="153dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="288" android:textSize="17dp" android:id="@+id/tv_aqi"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="重度污染" android:textSize="17dp" android:ems="5" android:gravity="right" android:id="@+id/tv_quality"/> </LinearLayout> </LinearLayout> </LinearLayout> <View android:layout_width="match_parent" android:layout_marginTop="5dp" android:layout_height="1dp" android:background="@color/light_grey"/> <include layout="@layout/predict_weather"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_gravity="center" android:background="@color/light_grey" android:layout_marginTop="5dp" android:layout_marginBottom="10dp"/> <include layout="@layout/weather_specify"/> </LinearLayout> </swiperefresh.PullToRefreshScrollView> </LinearLayout>在页面中使用了PullToRefreshScrollView下拉刷新组件,该组件是第三方的组件,将其集成到工程的方式与聚合SDK的方式相同。
predict_weather.xml的内容如下
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="150dp" android:gravity="center" > <LinearLayout android:layout_width="70dp" android:layout_height="120dp" android:layout_marginTop="15dp" android:layout_marginBottom="15dp" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/iv_future_first_icon"/> <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:id="@+id/tv_future_first_word" android:layout_marginTop="5dp" android:gravity="center" android:maxWidth="60dp" android:layout_gravity="center" /> <TextView android:layout_width="wrap_content" android:layout_marginTop="5dp" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/tv_future_first_temp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_day" android:layout_marginTop="5dp" android:layout_gravity="center_horizontal" /> </LinearLayout> <View android:layout_width="1dp" android:layout_height="100dp" android:background="@color/light_grey" android:layout_gravity="center" android:layout_marginLeft="10dp"/> <LinearLayout android:layout_width="70dp" android:layout_height="120dp" android:layout_marginLeft="15dp" android:layout_marginTop="15dp" android:layout_marginBottom="15dp" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/iv_future_second_icon"/> <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:id="@+id/tv_future_second_word" android:layout_marginTop="5dp" android:gravity="center" android:maxWidth="60dp" android:layout_gravity="center" /> <TextView android:layout_width="wrap_content" android:layout_marginTop="5dp" android:layout_gravity="center" android:layout_height="wrap_content" android:id="@+id/tv_future_second_temp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_day2" android:layout_marginTop="5dp" android:layout_gravity="center"/> </LinearLayout> <View android:layout_width="1dp" android:layout_height="100dp" android:background="@color/light_grey" android:layout_gravity="center" android:layout_marginLeft="10dp"/> <LinearLayout android:layout_width="70dp" android:layout_height="120dp" android:layout_marginLeft="15dp" android:layout_marginTop="15dp" android:layout_marginBottom="15dp" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/iv_future_third_icon"/> <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:id="@+id/tv_future_third_word" android:layout_marginTop="5dp" android:gravity="center" android:maxWidth="60dp" android:layout_gravity="center" /> <TextView android:layout_width="wrap_content" android:layout_marginTop="5dp" android:layout_height="wrap_content" android:id="@+id/tv_future_third_temp" android:layout_gravity="center" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_day3" android:layout_marginTop="5dp" android:layout_gravity="center"/> </LinearLayout> <View android:layout_width="1dp" android:layout_height="100dp" android:background="@color/light_grey" android:layout_gravity="center" android:layout_marginLeft="10dp"/> <LinearLayout android:layout_width="70dp" android:layout_height="120dp" android:layout_marginLeft="15dp" android:layout_marginTop="15dp" android:layout_marginBottom="15dp" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/iv_future_fourth_icon"/> <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:id="@+id/tv_future_fourth_word" android:layout_marginTop="5dp" android:gravity="center" android:maxWidth="60dp" android:layout_gravity="center" /> <TextView android:layout_width="wrap_content" android:layout_marginTop="5dp" android:layout_height="wrap_content" android:id="@+id/tv_future_fourth_temp" android:layout_gravity="center" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_day4" android:layout_marginTop="5dp" android:layout_gravity="center"/> </LinearLayout> </LinearLayout>weather_specify.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="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/information" android:layout_marginLeft="15dp" android:layout_marginTop="10dp"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/light_grey" android:layout_marginTop="4dp" android:layout_marginLeft="12dp" android:layout_gravity="center"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/dressing_index" android:layout_marginLeft="15dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_dressing_index" android:layout_marginLeft="215dp" android:text="15"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/light_grey" android:layout_marginTop="4dp" android:layout_marginLeft="12dp" android:layout_gravity="center"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/humidity" android:layout_marginLeft="15dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_humidity" android:layout_marginLeft="243dp" android:text="15"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_marginLeft="12dp" android:layout_height="1dp" android:background="@color/light_grey" android:layout_marginTop="4dp" android:layout_gravity="center"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/wind" android:layout_marginLeft="15dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_wind" android:layout_marginLeft="216dp" android:text="15"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/light_grey" android:layout_marginTop="4dp" android:layout_marginLeft="12dp" android:layout_gravity="center"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/uv_index" android:layout_marginLeft="15dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_uv_index" android:layout_marginLeft="202dp" android:text="15"/> </LinearLayout> </LinearLayout>
pull_to_refresh_heather_vertival.xml
<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" > <FrameLayout android:id="@+id/fl_inner" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:paddingBottom="@dimen/header_footer_top_bottom_padding" android:paddingLeft="@dimen/header_footer_left_right_padding" android:paddingRight="@dimen/header_footer_left_right_padding" android:paddingTop="@dimen/header_footer_top_bottom_padding" > <ProgressBar android:id="@+id/pull_to_refresh_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:indeterminateDrawable="@drawable/progressbar" android:indeterminate="true" android:visibility="visible" /> <!-- --> <TextView android:id="@+id/pull_to_refresh_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:singleLine="true" android:textAppearance="?android:attr/textAppearance" android:textStyle="bold" /> </FrameLayout> </merge>上面用到的View用于在页面中添加一条横线或竖线。
下面是主页面的逻辑代码。
先写一个javaBean
public class WeatherBean { private String city; private String release; private String weather_id; private String weather; private String temp; private String temperature; private String humidity; private String uv_index; private String wind; private String dressing_index; private List<FutureWeather> futurelist;
。。。。在这里省略了set和get方法}
public class FutureWeather { private String week; private String weather; private String temp; private String weather_id;
。。。。。}
private void findWeatherData() { Parameters params = new Parameters(); if (city != null) { params.add("cityname", city); } else { params.add("cityname", tv_city.getText().toString()); } params.add("dtype", "json"); params.add("key", "c917d0ada4474d64371ce1e56fdb5dfe"); params.add("format", 1); String url = "http://v.juhe.cn/weather/index"; JuheData.executeWithAPI(WeatherActivity.this, 39, url, JuheData.GET, params, new DataCallBack() {//39是请求的数据ID @Override public void onSuccess(int i, String s) { try { parseWeather(s); } catch (ParseException e) { e.printStackTrace(); } } @Override public void onFinish() { } @Override public void onFailure(int i, String s, Throwable throwable) { } }); }findWeatherData()方法用于向聚合数据获取天气的信息。返回的数据有JSON格式和XML格式两种。其数据的具体格式可以在聚合的官网上看到范例。
解析JSON数据
private void parseWeather(String response) throws ParseException { try { weatherBean = new WeatherBean(); futureWeatherList = new ArrayList<FutureWeather>(); JSONObject result = new JSONObject(response).getJSONObject("result"); JSONObject today = result.getJSONObject("today"); JSONObject sk = result.getJSONObject("sk"); weatherBean.setRelease(sk.getString("time")); weatherBean.setHumidity(sk.getString("humidity")); weatherBean.setTemp(sk.getString("temp") + "°C"); weatherBean.setWeather(today.getString("weather")); weatherBean.setUv_index(today.getString("uv_index")); weatherBean.setDressing_index(today.getString("dressing_index")); weatherBean.setTemperature(today.getString("temperature")); weatherBean.setWind(today.getString("wind")); weatherBean.setWeather_id(today.getJSONObject("weather_id").getString("fa")); JSONObject future = result.getJSONObject("future"); Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); for (int i = 1; i < 5; i++) { calendar.add(Calendar.DAY_OF_MONTH, 1); Date date = calendar.getTime(); JSONObject jsondata = future.getJSONObject("day_" + sdf.format(date)); FutureWeather futureWeather = new FutureWeather(); futureWeather.setWeather(jsondata.getString("weather")); futureWeather.setWeather_id(jsondata.getJSONObject("weather_id").getString("fa")); futureWeather.setTemp(jsondata.getString("temperature")); futureWeather.setWeek(jsondata.getString("week")); futureWeatherList.add(futureWeather); } weatherBean.setFuturelist(futureWeatherList); if (weatherBean != null) { flag = true; } else { flag = false; } setView(); } catch (JSONException e) { e.printStackTrace(); } }下面填充数据中:
private void setView() { if (weatherBean != null) { tv_release.setText(weatherBean.getRelease() + "发布"); tv_weather.setText(weatherBean.getWeather()); tv_temp.setText(weatherBean.getTemp()); tv_tempeture.setText(weatherBean.getTemperature()); tv_first_word.setText(weatherBean.getFuturelist().get(0).getWeather()); tv_first_day.setText(weatherBean.getFuturelist().get(0).getWeek()); tv_first_temp.setText(weatherBean.getFuturelist().get(0).getTemp()); tv_second_word.setText(weatherBean.getFuturelist().get(1).getWeather()); tv_second_day.setText(weatherBean.getFuturelist().get(1).getWeek()); tv_second_temp.setText(weatherBean.getFuturelist().get(1).getTemp()); tv_third_day.setText(weatherBean.getFuturelist().get(2).getWeek()); tv_third_word.setText(weatherBean.getFuturelist().get(2).getWeather()); tv_third_temp.setText(weatherBean.getFuturelist().get(2).getTemp()); tv_fourth_day.setText(weatherBean.getFuturelist().get(3).getWeek()); tv_fourth_word.setText(weatherBean.getFuturelist().get(3).getWeather()); tv_fourth_temp.setText(weatherBean.getFuturelist().get(3).getTemp()); tv_dressing_index.setText(weatherBean.getDressing_index()); tv_humidity.setText(weatherBean.getHumidity()); tv_uv_index.setText(weatherBean.getUv_index()); tv_wind.setText(weatherBean.getWind()); iv_now_weather.setImageResource(getResources().getIdentifier("d" + weatherBean.getWeather_id(), "drawable", "com.example.tangj.myweather")); iv_future_first_icon.setImageResource(getResources().getIdentifier("d" + weatherBean.getFuturelist().get(0).getWeather_id(), "drawable", "com.example.tangj.myweather")); iv_future_second_icon.setImageResource(getResources().getIdentifier("d" + weatherBean.getFuturelist().get(1).getWeather_id(), "drawable", "com.example.tangj.myweather")); iv_future_third_icon.setImageResource(getResources().getIdentifier("d" + weatherBean.getFuturelist().get(2).getWeather_id(), "drawable", "com.example.tangj.myweather")); iv_future_fourth_icon.setImageResource(getResources().getIdentifier("d" + weatherBean.getFuturelist().get(3).getWeather_id(), "drawable", "com.example.tangj.myweather")); } }此APP可以通过最上面显示城市名称的组件跳转到城市选择界面选择要查询的城市
citylist.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@color/text_color"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="right"> <EditText android:id="@+id/content" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="right" android:layout_weight="1" android:hint="@string/search_city"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/search" android:id="@+id/search" android:onClick="onClick" android:layout_gravity="center" android:textSize="18dp" android:background="#efd8d8"/> </LinearLayout> <ListView android:id="@+id/citylist" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> </LinearLayout>该界面最上面有一个输入框可以查询城市,EditText下面显示城市的列表,刚开始显示的是流行城市的列表。当在EditText中输入城市名称点击“搜索”按钮以后下面的ListView会显示你要查询的城市。如果只输入了城市名称的其中一个或几个字符,ListView会将包含该字符的所有城市都罗列出来。
cityActivity.java
public class CityActivity extends Activity { private List<String> cityList; private ListView citylistView; private EditText content; private List<String> list; private List<String> listtemp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.citylist); content = (EditText) findViewById(R.id.content); citylistView = (ListView) findViewById(R.id.citylist); getCity(); setPopCity(); } //设置常见城市列表 public void setPopCity() { listtemp = new ArrayList<String>(); String[] str = {"北京", "上海", "成都", "武汉", "杭州", "苏州", "天津", "重庆", "长沙", "深圳", "南京", "广州"}; for (int i = 0; i < str.length; i++) { listtemp.add(str[i]); } if(listtemp.size()>=0){ citylistView.setAdapter(new CityAdapter(CityActivity.this, listtemp)); citylistView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Intent intent = new Intent(); intent.putExtra("city", listtemp.get(i)); setResult(1, intent); finish(); } }); } } public void onClick(View view) { String str = content.getText().toString(); list = new ArrayList<String>(); String str2 = null; if (!TextUtils.isEmpty(str)) { for (int i = 0; i < cityList.size(); i++) { str2 = cityList.get(i); if (str2.indexOf(str) >= 0) { list.add(str2); } } citylistView.setAdapter(new CityAdapter(CityActivity.this, list)); citylistView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Intent intent = new Intent(); intent.putExtra("city", list.get(i)); setResult(1, intent); finish(); } }); } } public void getCity() { Parameters params = new Parameters(); params.add("dtype", "json"); JuheData.executeWithAPI(CityActivity.this, 39, "http://v.juhe.cn/weather/citys", JuheData.GET, params, new DataCallBack() { @Override public void onSuccess(int i, String response) { getCityData(response); } @Override public void onFinish() { } @Override public void onFailure(int i, String s, Throwable throwable) { } }); } private void getCityData(String response) { try { JSONObject jsonCity = new JSONObject(response); String resultcode = jsonCity.getString("resultcode"); JSONArray result = jsonCity.getJSONArray("result"); if (result != null && resultcode.equals("200")) { cityList = new ArrayList<String>(); for (int i = 0; i < result.length(); i++) { String city = result.getJSONObject(i).getString("city"); if (!cityList.contains(city)) { cityList.add(city); } } } } catch (JSONException e) { e.printStackTrace(); } } }查询空气质量的代码可参考查询天气的代码,二者类似,这里不再赘述。下图是效果图:
具体源代码我会上传在优快云上。