Day 28 - WeatherLib
Software Engineer & Blogger
05 August 2014
In
สวัสดีครับ บทความนี้เป็นบทความที่ 29 แล้วนะครับ ที่ผมจะมาเขียน ในซีรีย์ Learn 30 Android Libraries in 30 days
สำหรับบทความทั้งหมด อ่านได้จากด้านล่างครับ
- Day 1 : AndroidStaggered Grid
- Day 2 : Paralloid
- Day 3 : Retrofit
- Day 4 : SwipeRefreshLayout
- Day 5 : Android GraphView
- Day 6 : Holo Color Picker
- Day 7 : Android Async Http
- Day 8 : Crashlytics
- Day 9 : Butter Knife
- Day 10 : Android Annotations
- Day 11 : DateTimePicker
- Day 12 : Circular Progress Button
- Day 13 : ViewPager
- Day 14 : ViewPagerIndicator
- Day 15 : FadingActionBar
- Day 16 : AutofitTextView
- Day 17 : SwipeListView
- Day 18 : ShowcaseView
- Day 19 : GreenDAO
- Day 20 : AndroidViewAnimation
- Day 21 : ActiveAndroid
- Day 22 : Twitter4J
- Day 23 : ListViewAnimations
- Day 24 : AndEngine
- Day 25 : EazeGraph
- Day 26 : Cardslib
- Day 27 : AdapterKit
- Day 28 : WeatherLib
- Day 29 : FlatUI
- Day 30 : Android Firebase
สำหรับวันนี้ขอนำเสนอเรื่อง WeatherLib
WeatherLib เป็น Library ที่เอาไว้ช่วยทำแอพ Weather เหมาะกับคนต้องการนำไปพัฒนาเพื่อตรวจสอบสภาพอากาศ แค่ใช้ Library ตัวนี้ เราไม่ต้องไปกังวลเรื่อง request/response หรือว่า API จาก server จากผู้ให้บริการ เราสามารถโฟกัสแค่โค๊ดของเรา ส่วนผู้ให้บริการเรื่องสภาพอากาศ ใน WeatherLib ประกอบไปด้วย
ปกติเวลาเราต้องใช้งานพวก API จากด้านบน เราต้องขอ API แล้วดู Docs ของแต่ละเจ้า แต่ถ้าใช้ Weatherlib เราใช้โค๊ดเดียวกัน โครงสร้างเดียวกัน ใช้ได้ทุก Server เลย
จุดเด่นของ WeatherLib อย่างเช่น
- HTTP Request/response จะทำคนละ thread กับ Main UI Thread
- ค้นหาสภาพอากาศตามชื่อเมือง ชื่อประเทศได้
- ค้นหาสภาพอากาศตาม Latitude, Longitude
- ค้นหาสภาพอากาศปัจจุบัน/ สภาพอากาศย้อนหลัง
Installation
ขั้นตอนการติดตั้ง เปิดไฟล์ build.gradle
ขึ้นมา แล้วเพิ่ม dependencies ลงไปดังนี้
dependencies {compile 'com.survivingwithandroid:weatherlib:1.5.2'compile 'com.survivingwithandroid:weatherlib_volleyclient:1.5.2'compile 'com.mcxiaoke.volley:library:[email protected]'}
กด Sync Gradle เป็นอันเรียบร้อย
Usage
การใช้งาน WeatherLib มีคลาสที่จำเป็นดังนี้
WeatherClient.ClientBuilder
: เป็นเหมือนตัว Builder เอาไว้สร้าง instance ของ WeatherLib ที่ใช้ภายในแอพWeatherConfig
: ตัว config เช่น พวก API_KEY (บาง Provider จะต้องทำการขอ API ด้วย)WeatherClient
: เป็นเหมือนคลาสหลัก ที่เอาไวจัดการทุกๆอย่างของ WeatherLib เช่นค้นหาสภาพอากาศปัจจุบัน ค้นหาเมือง ดูสภาพอากาศย้อนหลัง
สเตปการสร้าง เริ่มต้นด้วยการสร้าง
WeatherClient.ClientBuilder builder = new WeatherClient.ClientBuilder();WeatherClient mClient = new WeatherClient.ClientBuilder().attach(this).provider(new OpenweathermapProviderType()).httpClient(WeatherClientDefault.class).config(new WeatherConfig()).build();
ทำการสร้าง WeatherClient
จากตัว ClientBuilder
ส่วน pamameter แต่ละตัวมีดังนี้ครับ ตัวที่ 1 : .attach()
คือ Context ตัวที่ 2 provider()
คือชื่อของ Provider ที่ให้บริการ มีทั้งหมด 4 ชนิด
- Openweathermap -> OpenweathermapProviderType
- Yahoo! Weather -> YahooWeatherProviderType
- Weatherundergroung -> WeatherundergroundProviderType
- Forecast.io -> ForecastIOProviderType
ตัวที่ 3 httpClient()
เป็น HTTP Client ที่ WeatherLibs ใช้ระหว่าง Volley กับ OkHttp แต่ว่าตอนแรก เราใส่ dependencies ของ Volley ไป ฉะนั้นตัวนี้ก็จะใช้ WeatherDefaultClient ของ Volley ตัวที่ 4 เป็น WeatherConfig()
ส่วนเมธอดภายใน WeatherClient
ที่สามารถใช้ได้มีดังนี้
getCurrentCondition()
getForecastWeather()
getHistoricalWeather()
getHourForecastWeather()
getDefaultProviderImage()
getWeatherImage()
มาลองสร้างโปรเจ็คลองดูดีกว่าครับ
Create Project
เริ่มแรกผมทำการสร้างคลาส Activity ขึ้นมา 1 คลาส ทำการ extends ListActivity
เพื่อจะใช้ built-in ListView เลย ฉะนั้น ก็ไม่จำเป็นต้องใช้ Layout ตัวคลาสมีดังนี้
package com.devahoy.learn30androidlibraries.day28;import android.app.ListActivity;import android.os.Bundle;import android.util.Log;import android.widget.ArrayAdapter;import com.survivingwithandroid.weather.lib.WeatherClient;import com.survivingwithandroid.weather.lib.WeatherConfig;import com.survivingwithandroid.weather.lib.client.volley.WeatherClientDefault;import com.survivingwithandroid.weather.lib.provider.openweathermap.OpenweathermapProviderType;import com.survivingwithandroid.weather.lib.request.WeatherRequest;public class WeatherActivity extends ListActivity {private String TAG = WeatherActivity.class.getSimpleName();private WeatherClient mClient;private ArrayAdapter<String> mAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);/* WeatherConfig config = new WeatherConfig();// config.ApiKey = "YOUR_API_KEY";*/try {mClient = new WeatherClient.ClientBuilder().attach(this).provider(new OpenweathermapProviderType()).httpClient(WeatherClientDefault.class).config(new WeatherConfig()).build();} catch (Exception e) {// Some errorLog.i(TAG, e.getMessage());}// YAHOO : Bangkok = 1225448// OpenWeatherMap : Bangkok = 1609350final WeatherRequest request = new WeatherRequest("1609350");}}
โค๊ดด้านบนเป็นการสร้าง WeatherClient
ขึ้นมา โดยขั้นแรก ผมจะทำการดึงข้อมูล พยากรณ์อากาศล่วงหน้า ในกรุงเทพ ฉะนั้นก็จะใช้เมธอด getForecastWeather()
โดยมีโครงสร้างการใช้ดังนี้
mClient.getForecastWeather(WeatherRequest, ForecastWeatherEventListener);
ตัวแรกคือ WeatherRequest
ระบุ cityId ของเมืองนั้นๆ ในส่วนนี้หาได้จากเมธอด searchCity
หรือ searchCityByLocation
ส่วนอีกอันคือ Listener ที่จะส่งค่ากลับมา เมื่อมีการทำงานเสร็จสิ้น สุดท้าย จะได้โครงสร้างสมบูรณ์แบบนี้
mClient.getForecastWeather(request, new WeatherClient.ForecastWeatherEventListener() {@Overridepublic void onWeatherRetrieved(WeatherForecast weatherForecast) {List<String> dataset = new ArrayList<String>();List<DayForecast> forecases = weatherForecast.getForecast();for (DayForecast forecast : forecases) {String result = forecast.weather.location.getCity() + " : Max: " +Math.round(forecast.forecastTemp.max) + " Min: " +Math.round(forecast.forecastTemp.min) + " Detail: " +forecast.weather.currentCondition.getDescr();dataset.add(result);}getListView().setBackgroundColor(Color.parseColor("#26B895"));getListView().setDividerHeight(2);mAdapter = new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_list_item_1, dataset);setListAdapter(mAdapter);}@Overridepublic void onWeatherError(WeatherLibException e) {Log.e(TAG, e.getMessage());}@Overridepublic void onConnectionError(Throwable throwable) {}});
โค๊ดด้านบน เมื่อ เรารีเควสขอ สภาพอากาศของกรุงเทพไป ก็จะได้ผลลัพธ์กลับมาเป็น WeatherForecast
จากนั้นก็ นำข้อมูล City และ อุณหภูมิ ใส่ใน ListView จะได้ผลลัพธ์ดังนี้
ส่วนอีกเมธอดนึง เอาไว้สำหรับดึงข้อมูลสภาพอากาศปัจจุบันเลย ด้วยเมธอด getCurrentCondition()
mClient.getCurrentCondition(request, new WeatherClient.WeatherEventListener() {@Overridepublic void onWeatherRetrieved(CurrentWeather cWeather) {Weather weather = cWeather.weather;Location location = weather.location;Weather.Temperature temperature = weather.temperature;Log.i(TAG, "City : " + location.getCity() +" Country : " + location.getCountry());Log.i(TAG, "Temp : " + temperature.getTemp());}@Overridepublic void onWeatherError(WeatherLibException t) {}@Overridepublic void onConnectionError(Throwable t) {}});
จะเห็นว่าใช้ WeatherRequest
เหมือนกับแบบแรก แต่ว่า Listener จะเปลี่ยนเป็น WeatherEventListener()
แทน ส่วนเมื่อได้ข้อมูลมาแล้ว เราจะเอาไปทำอะไรก็แล้วแต่เราเลยครับ เนื่องจากว่า WeatherLib มันเตรียมพวกคลาส Model ต่างๆมาให้เราแล้ว เช่นคลาส Weather
, Location
, Temperature
เราสามารถเข้าถึงข้อมูลพวกนี้ได้หมด สุดท้าย ก็เหลือแค่จะเอาไปใส่ในเลเอาท์ยังไง อยู่ที่การออกแบบหน้าตาเลเอาท์แล้วครับ
สำหรับบทความนี้ก็ขอจบแค่นะครับ หากสนใจอ่านรายละเอียดเพิ่มเติม หรือดูโค๊ดตัวอย่าง ก็อ่านเพิ่มได้จากต้นฉบับเลยครับ และ Tutorial เพิ่มเติม