Trước khi bắt tay vào lập trình bài này thì ta xem sơ qua cấu trúc JSON khi kiểm tra thời tiết của một địa điểm nào đó, ví dụ ở Thành Phố Hồ Chí Minh:http:api.openweathermap.orgdata2.5weather?q=hồ chí minhappid=be8d3e323de722ff78208a7dbb2dcd6fhay dùng kinh độ vĩ độ (để áp dụng cho chức năng đầu tiên là xem thời tiết tại địa điểm hiện tại, theo địa chỉ bất kỳ, hay xem trên Google Map):http:api.openweathermap.orgdata2.5weather?lat=10.778182lon=106.665504appid=be8d3e323de722ff78208a7dbb2dcd6fTa được kết quả tương tự như sau: Các source code bạn tự nối đuôi appid mà Tui đã chỉ ở trên là có thể chạy tốt.End update 13122015—————————————–Việc phân tích cấu trúc JSON để viết Java class các bạn đã được học kỹ ở các bài trước rồi, nên bài này Tui không nói nữa mà Tui chỉ show Mô hình Java class đã viết ra như sau (Bạn tự viết): – Ta sẽ dùng GSon để chuyển JSON qua Java class, từ đó dễ dàng cho việc sử dụng lấy thông tin dự báo thời tiết.– Còn dưới đây là cấu trúc JSON cho trường hợp dự báo các ngày khác (Daily):Ví dụ:http:api.openweathermap.orgdata2.5forecastdaily?lat=10.778182lon=106.665504cnt=10Hay:http:api.openweathermap.orgdata2.5forecastdaily?q=hồ chí minhcnt=10Thì ta có kết quả với cấu trúc JSON khá khác cho với trường hợp trên như sau: –> Bạn tự phân tích cấu trúc ở trên để viết Java Class cho trường hợp Daily (chức năng số 3).Trong Project này Tui sẽ thực hiện 3 chức năng (thời tiết địa điểm hiện tại của thiết bị, xem thời tiết theo địa điểm nhập bất kỳ và xem thời tiết trên Google Map), còn chức năng dự báo ngày kế tiếp các bạn tiếp tục thực hiện.
Trang 1Xây dựng phần mềm dự báo thời tiết
Tui muốn tổng hợp các bài tập về Google Map, về Đa tiến trình, về JSon,
Webservice… để xây dựng phần mềm dự báo thời tiết đơn giản như hình dưới đây:
– Phần mềm sẽ có 4 chức năng như mô tả ở trên, để làm được bài này thì các bạn cần phải có các kiến thức sau:
Đồng thời nghiên cứu thêm API Open Weather Map (Hỗ trợ xem thời tiết hầu hết mọi nơi trên thế giới, được đánh giá là một trong những API cũng cấp webservice về
dự báo thời tiết tốt nhất hiện nay)
Cập nhật ngày 13/12/2015
1
Trang 2Để sử dụng được API này bạn cần đăng nhập để lấy appid, chi tiết đọc
Trang 3Chi tiết hướng dẫn sử dụng: http://openweathermap.org/api
Các bạn tranh thủ ôn lại các bài trên sau đó Tui sẽ trình bày chi tiết từng bước cách thực hiện dự án này.
Trước khi bắt tay vào lập trình bài này thì ta xem sơ qua cấu trúc JSON khi kiểm tra thời tiết của một địa điểm nào đó, ví dụ ở Thành Phố Hồ Chí Minh:
Ta được kết quả tương tự như sau:
Trang 4Các source code bạn tự nối đuôi appid mà Tui đã chỉ ở trên là có thể chạy tốt.
Trang 5– Ta sẽ dùng GSon để chuyển JSON qua Java class, từ đó dễ dàng cho việc sử dụng lấy thông tin dự báo thời tiết.
– Còn dưới đây là cấu trúc JSON cho trường hợp dự báo các ngày khác (Daily):
Trang 6–> Bạn tự phân tích cấu trúc ở trên để viết Java Class cho trường hợp Daily (chức năng số 3).
Trong Project này Tui sẽ thực hiện 3 chức năng (thời tiết địa điểm hiện tại của thiết
bị, xem thời tiết theo địa điểm nhập bất kỳ và xem thời tiết trên Google Map), còn chức năng dự báo ngày kế tiếp các bạn tiếp tục thực hiện.
Tui có cấu trúc tập tin, class của dự án như sau:
Trang 7– Tui chụp màn hình sử dụng phần mềm dự báo thời tiết như sau:
1) Từ màn hình chính, nếu bấm vào “Thời tiết địa điểm hiện tại của thiết bị”:
Chương trình sẽ hiển thị thông báo chi tiết dự báo thời tiết như sau:
Trang 8Ta thấy chi tiết của địa điểm hiện tại của thiết bị (vị trị hiện tại tương đối trong phạm vi thiết bị), ở trên ta thấy nhiệt
độ, bầu trời bằng hình có nắng, có mây, có mưa…, tốc độ gió, áp suất…
2) Từ màn hình chính, nếu bấm vào “Xem thời tiết theo địa điểm nhập bất kỳ”:
Chương trình sẽ hiển thị màn hình cho phép nhập địa chỉ bất kỳ, hoặc chọn các tỉnh thành có sẵn của Việt Nam (muốn bất kỳ địa điểm nào khác ở Việt Nam hay trên thế giới thì tự gõ địa chỉ vào), màn hình chọn địa điểm:
Trang 9Nếu ta chọn hoặc nhập địa điểm
bất kỳ, ví dụ như Hồ Chí Minh, ta có kết quả sau:
Trang 10Ở hình trên ta thấy đấy, Hồ Chí Minh tuy có mưa nhưng nhiệt độ vẫn nóng là 34.2 độ C Đúng là tại thời điểm Tui post hình này lên là Sài gòn đang mưa và vẫn nóng le lưỡi.
3) Tại màn hình chính, chọn “Xem thời tiết trên Google Map”, chương trình sẽ tự động hiển thị thời tiết tại vị trí hiện tại trên bản đồ, và cho phép bạn nhấn chọn bất
kỳ địa điểm nào đó trên bản đồ để xem thời tiết Đây là chức năng rất thú vị và coding hơi phức tạp.
Ta có kết quả:
Trang 11Nhớ là bạn có thể nhấn chọn vị trí khác để xem thời tiết, ví dụ Tui chọn Nguyễn văn Trỗi:
Trang 12Nếu làm tốt bài này bạn có thể áp dụng một cách uyển chuyển vào các dự án liên quan tới Du lịch, xem thời tiết….
Sau đây là Coding chi tiết cho từng phần, tui sẽ giải thích những đặc tính mới trong Android Studio, còn những cái này tương tự như Eclipse thì thôi (Tui chỉ trỏ link tới rồi các bạn đọc lại).
Ta cần xây dựng mô hình class cho Weather theo tọa độ và địa chỉ của kết quả Json
2 loại dưới đây:
http://api.openweathermap.org/data/2.5/weather?lat=10.778182&lon=106.665504
Như sau:
Trang 13Tui sẽ không phân tích hay giải thích tại sao phải viết các lớp như trên nữa, vì Tui đã hướng dẫn chi tiết ở các bài 61 , bài 62 , bài 63 các bạn bắt buộc phải đọc lại.
Soure code từng lớp như sau:
publicclassClouds {
privateintall;
publicintgetAll() {
publicclassCoord {
private doublelon;
privatedoublelat;
publicdoublegetLon() {
returnlon;
}
publicvoidsetLon(doublelon) {
Trang 14publicclassMain {
privatedoubletemp;
privatedoubletemp_min;
privatedoubletemp_max;
privatedoublepressure;
privatedoublesea_level;
privatedoublegrnd_level;
privatedoublehumidity;
publicdoublegetTemp() {
Trang 15publicclassSys {
privatedoublemessage;
privateString country;
privatelongsunrise;
privatelongsunset;
publicString getCountry() {
Trang 16publicclassWeatherItem {
privatelongid;
privateString main;
privateString description;
privateString icon;
publiclonggetId() {
Trang 17publicclassWind {
privatedoublespeed;
privatedoubledeg;
publicdoublegetSpeed() {
publicclassOpenWeatherJSon {
privateCoord coord;
privateSys sys;
privateList<WeatherItem> weather;privateString base;
privateMain main;
privateWind wind;
privateClouds clouds;
privatelongdt;
privatelongid;
privateString name;
privateintcod;
publicCoord getCoord() {
Trang 19– Như vậy ta đã có đủ mô hình lớp về kết quả dự báo thời tiết theo định dạng JSON.
– Bạn cần chú ý phải thêm thư viện cho dự án để đưa về Json thông qua GSon (Bạn xem lại thư viện ở các bài trước, ở bài này Tui không hướng dẫn nữa).
– Tiến hành viết thư viện đọc thời tiết bằng đa tiến trình, thư viên này được sử dụng
và tái sử dụng cho các chức năng kiểm tra thời tiết theo tọa độ hay địa chỉ.
Chi tiết từng lớp như sau:
Enum TypePrediction:
Trang 20publicenumTypePrediction {
ADDRESS_NAME,//nhập theo địa chỉ cụ thể
LATITUDE_LONGITUDE//nhập theo vĩ độ kinh độ
}
enum này để chia ra 2 loại là xem thời tiết theo địa chỉ và theo tọa độ.
Lớp OpenWeatherMapAPI, lớp này dùng để đọc thông tin thời tiết (đưa Json về model java class thông qua GSon):
publicclassOpenWeatherMapAPI {
publicstaticOpenWeatherJSon prediction(String q)
{
try{
String location= URLEncoder.encode(q, "UTF-8");
URL url = newURL("http://api.openweathermap.org/data/2.5/weather?
String idIcon = results.getWeather().get(0).getIcon().toString();
String urlIcon = "http://openweathermap.org/img/w/"+idIcon+".png";
URL urlImage = newURL(urlIcon);
Trang 21String idIcon = results.getWeather().get(0).getIcon().toString();
String urlIcon = "http://openweathermap.org/img/w/"+idIcon+".png";
URL urlImage = newURL(urlIcon);
String idIcon = results.getWeather().get(0).getIcon().toString();
String urlIcon = "http://openweathermap.org/img/w/"+idIcon+".png";
URL urlImage = newURL(urlIcon);
Trang 22String location= URLEncoder.encode(q, "UTF-8");
URL url = newURL("http://api.openweathermap.org/data/2.5/forecast/daily?q="+location+"&cnt="+cnt);
InputStreamReader reader = new8");
InputStreamReader(url.openStream(),"UTF-OpenWeatherJSon results = newGson().fromJson(reader,
OpenWeatherJSon.class);
String idIcon = results.getWeather().get(0).getIcon().toString();
String urlIcon = "http://openweathermap.org/img/w/"+idIcon+".png";
URL urlImage = newURL(urlIcon);
Trang 23– Lớp WeatherAsyncTask, để thực hiện đa tiến trình truy vấn thời tiết, hiển thị lên
giao diện Lớp này được sử dụng chung cho cả theo Địa chỉ hay theo tọa độ.
Trang 25publicWeatherAsyncTask(Marker marker,GoogleMap map,Activity
activity,doublelatitude,doublelongitude)
//Tiến hành tạo đối tượng URL
URL urlConnection = newURL(urlIcon);
InputStream input = connection.getInputStream();
//Tiến hành convert qua hình ảnh
Trang 26TextView txtCloudliness= (TextView)
activity.findViewById(R.id.txtCloudliness);
TextView txtPressure= (TextView) activity.findViewById(R.id.txtPressure);TextView txtHumidty= (TextView) activity.findViewById(R.id.txtHumidty);TextView txtSunrise= (TextView) activity.findViewById(R.id.txtSunrise);TextView txtSunset= (TextView) activity.findViewById(R.id.txtSunset);doubletemperature=openWeatherJSon.getMain().getTemp()-273.15;
String maxtemp= 273.15)+"°C";
format.format(openWeatherJSon.getMain().getTemp_max()-String mintemp= 273.15)+"°C";
format.format(openWeatherJSon.getMain().getTemp_min()-String wind= openWeatherJSon.getWind().getSpeed()+" m/s";
String mesg = openWeatherJSon.getWeather().get(0).getMain();
// Translator translate = Translator.getInstance();
// String cloudiness=mesg+" ("+translate.translate(mesg,
Date timeSunSet = newDate(openWeatherJSon.getSys().getSunset()*1000);String sunset= timeSunSet.getHours()+":"+timeSunSet.getMinutes();
Trang 27/*String city = address.getLocality();
String state = address.getAdminArea();
String country = address.getCountryName();
String postalCode = address.getPostalCode();
String knownName = address.getFeatureName();*/
Trang 2815 9 16 0 16 1 16 2 16 3 16 4 16 5 16 6 16 7 16 8 16 9 17 0 17 1 17 2 17 3 17 4 17 5 17 6 17 7 17 8 17 9 18 0 18 1 18 2 18 3 18
Trang 294 18 5 18 6 18 7 18 8 18 9 19 0 19 1 19 2 19 3 19 4 19 5 19 6 19 7 19 8 19 9 20 0 20 1 20 2 20 3 20 4 20 5 20 6 20 7 20 8 20 9
Trang 300
21
1
– Sau đó ta tiến hành thiết kế các màn hình về viết code cho từng màn hình.
-Ở trên 3 Activity đều sử dụng
1 màn hình (vì cho dù tìm theo kiểu nào đi nữa thì thông tin thời tiết cũng đầy đủ thông số giống nhau).
– Ta đi vào từng màn hình, trước tiên là màn hình MainActivity:
Activity_main.xml:
Trang 35publicbooleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_main, menu);
returntrue;
}
@Override
Trang 36publicbooleanonOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml
– Tiếp tục xử lý cho màn hình xem thời tiết tại địa điểm hiện tại của thiết bị, đó là
WeatherCurrentLocationActivity , chú ý là cả 3 trường hợp hiển thị chi tiết thời tiết đều sử dụng chung layout “ activity_weather_current_location.xml “:
Trang 37nội dung XML của màn hình hiển thị chi tiết :
Trang 39android:hint="Nhiệt độ lớn nhất ở đây" />
android:hint="Nhiệt độ nhỏ nhất ở đây" />
android:hint="Tố độ gió ở đây" />
Trang 40android:hint="Hướng mây" />
android:hint="Áp suất ở đây" />
android:hint="độ ẩm ở đây" />
android:id="@+id/textView25" />
Trang 41android:hint="Mặt trời mọc" />
android:hint="Mặt trời mọc" />
</TableRow>
</TableLayout>
</ScrollView>
</LinearLayout>
Trang 426 16 7 16 8 16 9 17 0 17 1 17 2 17 3 17 4 17 5 17 6 17 7 17 8 17 9 18 0 18 1 18 2 18 3 18 4 18 5 18 6 18 7 18 8 18 9 19 0 19 1
Trang 4319 2 19 3 19 4 19 5 19 6 19 7 19 8 19 9 20 0 20 1 20 2 20 3 20 4 20 5 20 6 20 7 20 8 20 9 21 0 21 1 21 2 21 3 21 4 21 5 21 6 21
Trang 45* source code lấy địa điểm hiện tại của thiết bị
* chú ý nhớ cấp quyền trong Manifest để cho phép truy suất
*/
privatevoidgetCurrentLocation() {
LocationManager locationManager = (LocationManager)
getSystemService(LOCATION_SERVICE);
Criteria criteria = newCriteria();
Location lastLocation =
locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
Trang 46@Override
publicbooleanonOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml
Trang 48Như vậy chức năng này cũng sử dụng chung màn hình hiển thị chi tiết thời tiết, và ta cần cung cấp màn hình chọn tỉnh thành Việt Nam có sẵn hoặc trong ô nhập địa chỉ
cho phép người sử dụng nhập bất kỳ địa điểm nào đó trên thế giới Bấm nút Xem thời tiết hệ thống sẽ xuất hiện kết quả như hình số 3 ở trên (bạn thấy đó ở sài gòn
bây giờ là 27.9 độ C quá là mát mẻ… vì Tui chụp hình này lúc 10h đêm, chứng tỏ phần mềm này nó thông minh, nó biết ban đêm thường là mát hơn ban ngày ).
– Ta xem layout của màn hình chọn địa chỉ (activity_choose_address.xml):
Trang 51publicvoidonClick(View v) {
//mở màn hình xem thời tiết theo địa chỉ nhập bất kỳ
publicvoidonItemClick(AdapterView<?> parent, View view, int
position, longid) {
publicbooleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_weather_by_address, menu);
returntrue;
}
@Override
publicbooleanonOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml
Trang 525 4 5 5 5 6 5 7 5 8 5 9 6 0 6 1 6 2 6 3 6 4 6 5 6 6 6 7 6 8 6 9 7 0 7 1 7 2 7 3 7 4 7 5 7 6 7 7 7 8 7
Trang 53– sau khi bấm vào nút xem thời tiết, hệ thống sẽ mở màn hình
( WeatherByAddressActivity ), chú ý màn hình này như đã nói ở trên là sử dụng chung layout với chức năng xem thời tiết tại vị trí hiện tại của máy.
source code của lớp WeatherByAddressActivity như sau:
1 packagecom.tranduythanh.weatherprediction;
Trang 54publicbooleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present
getMenuInflater().inflate(R.menu.menu_weather_by_address, menu);returntrue;
}
@Override
publicbooleanonOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here The action bar will
// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.intid = item.getItemId();
Trang 55-Chức năng cuối cùng Tui muốn hướng dẫn là xem thời tiết tại vị trí bất kỳ trên bản
đồ (lần đầu tiên mở lên thì hệ thống sẽ hiển thị thời tiết tại vị trí hiện tại của thiết bị lên bản đồ, sau đó người sử dụng muốn xem nơi khác thì chỉ cần nhấn vào vị trí trên bản đồ, chức năng này rất tiện lợi):
– Chức năng này ta cần xử lý coding hơi phức tạp chút xíu, cần phải xử lý custom InfoWindowAdapter cho việc hiển thị giao diện khác nên bản đồ cũng như xác định
vị trí mà người sử dụng chọn bất kỳ trên bản đồ rồi di chuyển và hiển thị chi tiết thời tiết tại địa chỉ mới này.
– Bạn chú ý để hiển thị Map trong Android Studio thì nó đơn giản hơn rất nhiều so với Eclipse vì Android Studio đã hỗ trợ rất tốt chức năng này.
Trang 56– Ta cần tạo Google Map Activity tên là WeatherMapsActivity như sau:
– Bấm chuột phải vào Package/ chọn New/ chọn Google/ chọn Google Maps Activity:
– Sau
đó màn hình tạo activity hiển thị lên, bạn đặt tên là WeatherMapsActivity hệ thống
sẽ tạo ra layout tương thích để hiển thị Map (activity_weather_maps.xml):
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="@+id/map"
tools:context="com.tranduythanh.weatherprediction.WeatherMapsActivity"android:name="com.google.android.gms.maps.SupportMapFragment" />
Và lớp WeatherMapsActivity kế thừa từ FragmentActivity.
Đồng thời nó sẽ phát sinh ra thêm 1 file google_maps_api.xml để lưu trữ KEY sử dụng Map như đã hướng dẫn ở các bài trước (bạn cần tự tạo để lấy KEY dán vào đây):
Trang 57Ở trên bạn cần làm theo bước: Copy toàn bộ dữ liệu trong dòng mà tui đánh dấu là
số 1, đưa nó vào link trong vùng Tui đánh dấu là số 2 (cách tạo key trong này đã hướng dẫn từ các bài trước về Map, bạn tự coi lại), sau khi nó tạo ra Key truy suất MAP, bạn dán Key đó vào vùng số 3 Ở vùng Số hệ thông có tự đặt tên
là google_maps_key
– Sau đó bạn mở AndroidManifest lên để quát sát nó có cái gì ở đây:
Bạn thấy đấy, nó đơn giản hơn rất là nhiều, nó tự làm giùm cho chúng ta.
– Tiếp theo ta tiến hành coding để xử lý cho cho thời tiết trên map:
– Tạo lớp MyInfoWindowAdapter (sử dụng chung Layout xem thời tiết như đã đề
cập ở trên) để hiển thị lên Map: